mirror of
https://github.com/fastapi/full-stack-fastapi-template.git
synced 2026-11-03 20:36:27 +00:00
Compare commits
23 Commits
2d45624282
...
7d1fbef97c
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d1fbef97c | |||
| 3685fb6625 | |||
| 119e31fba2 | |||
| 6bc7fa47e3 | |||
| 33c75e4cab | |||
| 6d63f81979 | |||
| 77be72439c | |||
| a586c1c05c | |||
| 8c6e31a8f7 | |||
| 8e4fd7c722 | |||
| 54de75638b | |||
| 49a94eaab4 | |||
| 14728b636c | |||
| a727535488 | |||
| 95a7a61c8b | |||
| 70461bb937 | |||
| 4179f15185 | |||
| 787e79a463 | |||
| 67250999a5 | |||
| 2a6eeda629 | |||
| 6bb47f9c9c | |||
| 248d7d11e7 | |||
| 98d93cfee8 |
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../.venv/lib/python3.14/site-packages/fastapi/.agents/skills/fastapi
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"kind": "tool-skill",
|
||||||
|
"version": "0.0.19"
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
name: library-skills
|
||||||
|
description: Use Library Skills to discover, install, refresh, repair, check, and manage agent skills from installed packages.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Library Skills
|
||||||
|
|
||||||
|
Use this skill when a project might benefit from agent skills bundled by its installed packages, or when existing Library Skills-managed symlinks are stale, broken, orphaned, or need to be checked.
|
||||||
|
|
||||||
|
Run commands from the project root.
|
||||||
|
|
||||||
|
Agents bundle their own skills by including an `.agents/skills` directory. More details in [Library Skills](https://library-skills.io).
|
||||||
|
|
||||||
|
## First-Time Setup
|
||||||
|
|
||||||
|
- Make sure project dependencies are installed first, for example with `uv sync` for Python projects or `npm install` / `bun install` for Node.js projects.
|
||||||
|
- Run `uvx library-skills` or `npx library-skills` to discover skills bundled by the installed packages and install selected skills interactively.
|
||||||
|
- Use `uvx library-skills --all` or `npx library-skills --all` only when all newly discovered skills should be installed without selecting individual skills.
|
||||||
|
- Use `uvx library-skills --tool-skill` or `npx library-skills --tool-skill` to copy this Library Skills tool skill into the project so future agents know how to discover, install, update, repair, and check skills.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
- Run `uvx library-skills` or `npx library-skills` to discover package-provided skills, install selected new skills, and reconcile existing managed symlinks.
|
||||||
|
- Run `uvx library-skills list` or `npx library-skills list` to inspect discovered and installed skills.
|
||||||
|
- Run `uvx library-skills list --json` or `npx library-skills list --json` for machine-readable installed status.
|
||||||
|
- Run `uvx library-skills scan --json` or `npx library-skills scan --json` for discovery-only automation.
|
||||||
|
- Run `uvx library-skills --check` or `npx library-skills --check` to validate managed skill symlink state without changing files.
|
||||||
|
- Run `uvx library-skills --yes` or `npx library-skills --yes` to repair stale managed symlinks and remove orphaned managed symlinks non-interactively.
|
||||||
|
- Add `--claude` when `.claude/skills` should also be managed.
|
||||||
|
- Add `--skill NAME` to install a specific discovered skill by name.
|
||||||
|
|
||||||
|
## Safety
|
||||||
|
|
||||||
|
- Prefer rerunning `library-skills` over editing managed symlinks manually.
|
||||||
|
- If installed skill symlinks are broken, dependencies may not be installed yet. Try the project's normal install command first, such as `uv sync`, `npm install`, or `bun install`, then rerun `library-skills`.
|
||||||
|
- Do not delete or overwrite hand-authored skill directories.
|
||||||
|
- Library Skills only removes managed symlinks. It should not remove copied or hand-authored skill directories.
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../.venv/lib/python3.14/site-packages/sqlmodel/.agents/skills/sqlmodel
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../.venv/lib/python3.14/site-packages/fastapi/.agents/skills/fastapi
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"kind": "tool-skill",
|
||||||
|
"version": "0.0.19"
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
name: library-skills
|
||||||
|
description: Use Library Skills to discover, install, refresh, repair, check, and manage agent skills from installed packages.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Library Skills
|
||||||
|
|
||||||
|
Use this skill when a project might benefit from agent skills bundled by its installed packages, or when existing Library Skills-managed symlinks are stale, broken, orphaned, or need to be checked.
|
||||||
|
|
||||||
|
Run commands from the project root.
|
||||||
|
|
||||||
|
Agents bundle their own skills by including an `.agents/skills` directory. More details in [Library Skills](https://library-skills.io).
|
||||||
|
|
||||||
|
## First-Time Setup
|
||||||
|
|
||||||
|
- Make sure project dependencies are installed first, for example with `uv sync` for Python projects or `npm install` / `bun install` for Node.js projects.
|
||||||
|
- Run `uvx library-skills` or `npx library-skills` to discover skills bundled by the installed packages and install selected skills interactively.
|
||||||
|
- Use `uvx library-skills --all` or `npx library-skills --all` only when all newly discovered skills should be installed without selecting individual skills.
|
||||||
|
- Use `uvx library-skills --tool-skill` or `npx library-skills --tool-skill` to copy this Library Skills tool skill into the project so future agents know how to discover, install, update, repair, and check skills.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
- Run `uvx library-skills` or `npx library-skills` to discover package-provided skills, install selected new skills, and reconcile existing managed symlinks.
|
||||||
|
- Run `uvx library-skills list` or `npx library-skills list` to inspect discovered and installed skills.
|
||||||
|
- Run `uvx library-skills list --json` or `npx library-skills list --json` for machine-readable installed status.
|
||||||
|
- Run `uvx library-skills scan --json` or `npx library-skills scan --json` for discovery-only automation.
|
||||||
|
- Run `uvx library-skills --check` or `npx library-skills --check` to validate managed skill symlink state without changing files.
|
||||||
|
- Run `uvx library-skills --yes` or `npx library-skills --yes` to repair stale managed symlinks and remove orphaned managed symlinks non-interactively.
|
||||||
|
- Add `--claude` when `.claude/skills` should also be managed.
|
||||||
|
- Add `--skill NAME` to install a specific discovered skill by name.
|
||||||
|
|
||||||
|
## Safety
|
||||||
|
|
||||||
|
- Prefer rerunning `library-skills` over editing managed symlinks manually.
|
||||||
|
- If installed skill symlinks are broken, dependencies may not be installed yet. Try the project's normal install command first, such as `uv sync`, `npm install`, or `bun install`, then rerun `library-skills`.
|
||||||
|
- Do not delete or overwrite hand-authored skill directories.
|
||||||
|
- Library Skills only removes managed symlinks. It should not remove copied or hand-authored skill directories.
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../.venv/lib/python3.14/site-packages/sqlmodel/.agents/skills/sqlmodel
|
||||||
@@ -29,29 +29,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||||
run: echo "$GITHUB_CONTEXT"
|
run: echo "$GITHUB_CONTEXT"
|
||||||
- uses: tiangolo/issue-manager@2fb3484ec9279485df8659e8ec73de262431737d # 0.6.0
|
- uses: tiangolo/issue-manager@75d60679db1ea348f6f6ea1d0e20de80a7c04645 # 0.7.1
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
config: >
|
|
||||||
{
|
|
||||||
"answered": {
|
|
||||||
"delay": 864000,
|
|
||||||
"message": "Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs."
|
|
||||||
},
|
|
||||||
"waiting": {
|
|
||||||
"delay": 2628000,
|
|
||||||
"message": "As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.",
|
|
||||||
"reminder": {
|
|
||||||
"before": "P3D",
|
|
||||||
"message": "Heads-up: this will be closed in 3 days unless there's new activity."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"invalid": {
|
|
||||||
"delay": 0,
|
|
||||||
"message": "This was marked as invalid and will be closed now. If this is an error, please provide additional details."
|
|
||||||
},
|
|
||||||
"maybe-ai": {
|
|
||||||
"delay": 0,
|
|
||||||
"message": "This was marked as potentially AI generated and will be closed now. If this is an error, please provide additional details, make sure to read the docs about contributing and AI."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- synchronize
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
debug_enabled:
|
debug_enabled:
|
||||||
@@ -60,7 +57,7 @@ jobs:
|
|||||||
bun-version: 1.3.12
|
bun-version: 1.3.12
|
||||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||||
with:
|
with:
|
||||||
python-version: '3.10'
|
python-version-file: .python-version
|
||||||
- name: Setup tmate session
|
- name: Setup tmate session
|
||||||
uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113 # v3.24
|
uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113 # v3.24
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ name: pre-commit
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- synchronize
|
|
||||||
|
|
||||||
permissions: {}
|
permissions: {}
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@@ -48,7 +44,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.11"
|
python-version-file: .python-version
|
||||||
- name: Setup uv
|
- name: Setup uv
|
||||||
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.13"
|
python-version-file: .python-version
|
||||||
- name: Setup uv
|
- name: Setup uv
|
||||||
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -5,10 +5,6 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- synchronize
|
|
||||||
|
|
||||||
permissions: {}
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -23,7 +19,7 @@ jobs:
|
|||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version-file: .python-version
|
||||||
- name: Install uv
|
- name: Install uv
|
||||||
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -5,10 +5,6 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- synchronize
|
|
||||||
|
|
||||||
permissions: {}
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
pull_request:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions: {}
|
permissions: {}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
3.14
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
FROM python:3.10
|
FROM python:3.14
|
||||||
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
@@ -42,4 +42,4 @@ RUN --mount=type=cache,target=/root/.cache/uv \
|
|||||||
|
|
||||||
WORKDIR /app/backend/
|
WORKDIR /app/backend/
|
||||||
|
|
||||||
CMD ["fastapi", "run", "--workers", "4", "app/main.py"]
|
CMD ["fastapi", "run", "--workers", "4"]
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ reusable_oauth2 = OAuth2PasswordBearer(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_db() -> Generator[Session, None, None]:
|
def get_db() -> Generator[Session]:
|
||||||
with Session(engine) as session:
|
with Session(engine) as session:
|
||||||
yield session
|
yield session
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ def get_current_user(session: SessionDep, token: TokenDep) -> User:
|
|||||||
token, settings.SECRET_KEY, algorithms=[security.ALGORITHM]
|
token, settings.SECRET_KEY, algorithms=[security.ALGORITHM]
|
||||||
)
|
)
|
||||||
token_data = TokenPayload(**payload)
|
token_data = TokenPayload(**payload)
|
||||||
except (InvalidTokenError, ValidationError):
|
except InvalidTokenError, ValidationError:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_403_FORBIDDEN,
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
detail="Could not validate credentials",
|
detail="Could not validate credentials",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import secrets
|
import secrets
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Annotated, Any, Literal
|
from typing import Annotated, Any, Literal, Self
|
||||||
|
|
||||||
from pydantic import (
|
from pydantic import (
|
||||||
AnyUrl,
|
AnyUrl,
|
||||||
@@ -12,7 +12,6 @@ from pydantic import (
|
|||||||
model_validator,
|
model_validator,
|
||||||
)
|
)
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
from typing_extensions import Self
|
|
||||||
|
|
||||||
|
|
||||||
def parse_cors(v: Any) -> list[str] | str:
|
def parse_cors(v: Any) -> list[str] | str:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from datetime import datetime, timedelta, timezone
|
from datetime import UTC, datetime, timedelta
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import jwt
|
import jwt
|
||||||
@@ -20,7 +20,7 @@ ALGORITHM = "HS256"
|
|||||||
|
|
||||||
|
|
||||||
def create_access_token(subject: str | Any, expires_delta: timedelta) -> str:
|
def create_access_token(subject: str | Any, expires_delta: timedelta) -> str:
|
||||||
expire = datetime.now(timezone.utc) + expires_delta
|
expire = datetime.now(UTC) + expires_delta
|
||||||
to_encode = {"exp": expire, "sub": str(subject)}
|
to_encode = {"exp": expire, "sub": str(subject)}
|
||||||
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=ALGORITHM)
|
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=ALGORITHM)
|
||||||
return encoded_jwt
|
return encoded_jwt
|
||||||
|
|||||||
+11
-7
@@ -1,5 +1,5 @@
|
|||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime, timezone
|
from datetime import UTC, datetime
|
||||||
|
|
||||||
from pydantic import EmailStr
|
from pydantic import EmailStr
|
||||||
from sqlalchemy import DateTime
|
from sqlalchemy import DateTime
|
||||||
@@ -7,7 +7,7 @@ from sqlmodel import Field, Relationship, SQLModel
|
|||||||
|
|
||||||
|
|
||||||
def get_datetime_utc() -> datetime:
|
def get_datetime_utc() -> datetime:
|
||||||
return datetime.now(timezone.utc)
|
return datetime.now(UTC)
|
||||||
|
|
||||||
|
|
||||||
# Shared properties
|
# Shared properties
|
||||||
@@ -30,8 +30,11 @@ class UserRegister(SQLModel):
|
|||||||
|
|
||||||
|
|
||||||
# Properties to receive via API on update, all are optional
|
# Properties to receive via API on update, all are optional
|
||||||
class UserUpdate(UserBase):
|
class UserUpdate(SQLModel):
|
||||||
email: EmailStr | None = Field(default=None, max_length=255) # type: ignore[assignment]
|
email: EmailStr | None = Field(default=None, max_length=255)
|
||||||
|
is_active: bool | None = None
|
||||||
|
is_superuser: bool | None = None
|
||||||
|
full_name: str | None = Field(default=None, max_length=255)
|
||||||
password: str | None = Field(default=None, min_length=8, max_length=128)
|
password: str | None = Field(default=None, min_length=8, max_length=128)
|
||||||
|
|
||||||
|
|
||||||
@@ -53,7 +56,7 @@ class User(UserBase, table=True):
|
|||||||
default_factory=get_datetime_utc,
|
default_factory=get_datetime_utc,
|
||||||
sa_type=DateTime(timezone=True), # type: ignore
|
sa_type=DateTime(timezone=True), # type: ignore
|
||||||
)
|
)
|
||||||
items: list["Item"] = Relationship(back_populates="owner", cascade_delete=True)
|
items: list[Item] = Relationship(back_populates="owner", cascade_delete=True)
|
||||||
|
|
||||||
|
|
||||||
# Properties to return via API, id is always required
|
# Properties to return via API, id is always required
|
||||||
@@ -79,8 +82,9 @@ class ItemCreate(ItemBase):
|
|||||||
|
|
||||||
|
|
||||||
# Properties to receive on item update
|
# Properties to receive on item update
|
||||||
class ItemUpdate(ItemBase):
|
class ItemUpdate(SQLModel):
|
||||||
title: str | None = Field(default=None, min_length=1, max_length=255) # type: ignore[assignment]
|
title: str | None = Field(default=None, min_length=1, max_length=255)
|
||||||
|
description: str | None = Field(default=None, max_length=255)
|
||||||
|
|
||||||
|
|
||||||
# Database model, database table inferred from class name
|
# Database model, database table inferred from class name
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import UTC, datetime, timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ def generate_new_account_email(
|
|||||||
|
|
||||||
def generate_password_reset_token(email: str) -> str:
|
def generate_password_reset_token(email: str) -> str:
|
||||||
delta = timedelta(hours=settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS)
|
delta = timedelta(hours=settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS)
|
||||||
now = datetime.now(timezone.utc)
|
now = datetime.now(UTC)
|
||||||
expires = now + delta
|
expires = now + delta
|
||||||
exp = expires.timestamp()
|
exp = expires.timestamp()
|
||||||
encoded_jwt = jwt.encode(
|
encoded_jwt = jwt.encode(
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
name = "app"
|
name = "app"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = ""
|
description = ""
|
||||||
requires-python = ">=3.10,<4.0"
|
requires-python = ">=3.14,<4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastapi[standard]<1.0.0,>=0.114.2",
|
"fastapi[standard]>=0.138.1,<1.0.0",
|
||||||
"python-multipart<1.0.0,>=0.0.27",
|
"python-multipart<1.0.0,>=0.0.27",
|
||||||
"email-validator<3.0.0.0,>=2.1.0.post1",
|
"email-validator<3.0.0.0,>=2.1.0.post1",
|
||||||
"tenacity<10.0.0,>=8.2.3",
|
"tenacity<10.0.0,>=8.2.3",
|
||||||
@@ -14,7 +14,7 @@ dependencies = [
|
|||||||
"alembic<2.0.0,>=1.12.1",
|
"alembic<2.0.0,>=1.12.1",
|
||||||
"httpx<1.0.0,>=0.25.1",
|
"httpx<1.0.0,>=0.25.1",
|
||||||
"psycopg[binary]<4.0.0,>=3.1.13",
|
"psycopg[binary]<4.0.0,>=3.1.13",
|
||||||
"sqlmodel<1.0.0,>=0.0.21",
|
"sqlmodel>=0.0.39,<1.0.0",
|
||||||
"pydantic-settings<3.0.0,>=2.2.1",
|
"pydantic-settings<3.0.0,>=2.2.1",
|
||||||
"sentry-sdk[fastapi]>=2.0.0,<3.0.0",
|
"sentry-sdk[fastapi]>=2.0.0,<3.0.0",
|
||||||
"pyjwt<3.0.0,>=2.13.0",
|
"pyjwt<3.0.0,>=2.13.0",
|
||||||
@@ -27,7 +27,6 @@ dev = [
|
|||||||
"mypy<3.0.0,>=1.8.0",
|
"mypy<3.0.0,>=1.8.0",
|
||||||
"ty>=0.0.25",
|
"ty>=0.0.25",
|
||||||
"ruff<1.0.0,>=0.2.2",
|
"ruff<1.0.0,>=0.2.2",
|
||||||
"prek>=0.2.24,<1.0.0",
|
|
||||||
"coverage<8.0.0,>=7.4.3",
|
"coverage<8.0.0,>=7.4.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -40,7 +39,7 @@ strict = true
|
|||||||
exclude = ["venv", ".venv", "alembic"]
|
exclude = ["venv", ".venv", "alembic"]
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
target-version = "py310"
|
target-version = "py314"
|
||||||
exclude = ["alembic"]
|
exclude = ["alembic"]
|
||||||
|
|
||||||
[tool.ruff.lint]
|
[tool.ruff.lint]
|
||||||
@@ -79,3 +78,6 @@ show_contexts = true
|
|||||||
|
|
||||||
[tool.ty.terminal]
|
[tool.ty.terminal]
|
||||||
error-on-warning = true
|
error-on-warning = true
|
||||||
|
|
||||||
|
[tool.fastapi]
|
||||||
|
entrypoint = "app.main:app"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from tests.utils.utils import get_superuser_token_headers
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session", autouse=True)
|
@pytest.fixture(scope="session", autouse=True)
|
||||||
def db() -> Generator[Session, None, None]:
|
def db() -> Generator[Session]:
|
||||||
with Session(engine) as session:
|
with Session(engine) as session:
|
||||||
init_db(session)
|
init_db(session)
|
||||||
yield session
|
yield session
|
||||||
@@ -25,7 +25,7 @@ def db() -> Generator[Session, None, None]:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def client() -> Generator[TestClient, None, None]:
|
def client() -> Generator[TestClient]:
|
||||||
with TestClient(app) as c:
|
with TestClient(app) as c:
|
||||||
yield c
|
yield c
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ services:
|
|||||||
# etc. To enable it, update .env, set:
|
# etc. To enable it, update .env, set:
|
||||||
# DOMAIN=localhost.tiangolo.com
|
# DOMAIN=localhost.tiangolo.com
|
||||||
proxy:
|
proxy:
|
||||||
image: traefik:3.6
|
image: traefik:v3.7
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
traefik:
|
traefik:
|
||||||
image: traefik:3.6
|
image: traefik:v3.7
|
||||||
ports:
|
ports:
|
||||||
# Listen on port 80, default for HTTP, necessary to redirect to HTTPS
|
# Listen on port 80, default for HTTP, necessary to redirect to HTTPS
|
||||||
- 80:80
|
- 80:80
|
||||||
|
|||||||
@@ -431,14 +431,26 @@ export const UserUpdateSchema = {
|
|||||||
title: 'Email'
|
title: 'Email'
|
||||||
},
|
},
|
||||||
is_active: {
|
is_active: {
|
||||||
type: 'boolean',
|
anyOf: [
|
||||||
title: 'Is Active',
|
{
|
||||||
default: true
|
type: 'boolean'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Is Active'
|
||||||
},
|
},
|
||||||
is_superuser: {
|
is_superuser: {
|
||||||
type: 'boolean',
|
anyOf: [
|
||||||
title: 'Is Superuser',
|
{
|
||||||
default: false
|
type: 'boolean'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'null'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
title: 'Is Superuser'
|
||||||
},
|
},
|
||||||
full_name: {
|
full_name: {
|
||||||
anyOf: [
|
anyOf: [
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ export type UsersPublic = {
|
|||||||
|
|
||||||
export type UserUpdate = {
|
export type UserUpdate = {
|
||||||
email?: (string | null);
|
email?: (string | null);
|
||||||
is_active?: boolean;
|
is_active?: (boolean | null);
|
||||||
is_superuser?: boolean;
|
is_superuser?: (boolean | null);
|
||||||
full_name?: (string | null);
|
full_name?: (string | null);
|
||||||
password?: (string | null);
|
password?: (string | null);
|
||||||
};
|
};
|
||||||
|
|||||||
+4
-3
@@ -1,8 +1,6 @@
|
|||||||
[tool.uv.workspace]
|
|
||||||
members = ["backend"]
|
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = [
|
dev = [
|
||||||
|
"prek>=0.2.24,<1.0.0",
|
||||||
"zizmor>=1.25.2",
|
"zizmor>=1.25.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -10,6 +8,9 @@ github-actions = [
|
|||||||
"smokeshow >=0.5.0",
|
"smokeshow >=0.5.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[tool.uv.workspace]
|
||||||
|
members = ["backend"]
|
||||||
|
|
||||||
[tool.typos.files]
|
[tool.typos.files]
|
||||||
extend-exclude = [
|
extend-exclude = [
|
||||||
"img/",
|
"img/",
|
||||||
|
|||||||
@@ -2,13 +2,21 @@
|
|||||||
|
|
||||||
## Latest Changes
|
## Latest Changes
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* 🔧 Use FastAPI entrypoint. PR [#2360](https://github.com/fastapi/full-stack-fastapi-template/pull/2360) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
* ♻️ Add library-skills for FastAPI and SQLModel. PR [#2354](https://github.com/fastapi/full-stack-fastapi-template/pull/2354) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
|
||||||
### Refactors
|
### Refactors
|
||||||
|
|
||||||
|
* ♻️ Refactor models to improve types. PR [#2356](https://github.com/fastapi/full-stack-fastapi-template/pull/2356) by [@tiangolo](https://github.com/tiangolo).
|
||||||
* 🔧 Add FastAPI VS Code extension to recommended extensions. PR [#2206](https://github.com/fastapi/full-stack-fastapi-template/pull/2206) by [@tiangolo](https://github.com/tiangolo).
|
* 🔧 Add FastAPI VS Code extension to recommended extensions. PR [#2206](https://github.com/fastapi/full-stack-fastapi-template/pull/2206) by [@tiangolo](https://github.com/tiangolo).
|
||||||
* ♻️ Update meta titles. PR [#2179](https://github.com/fastapi/full-stack-fastapi-template/pull/2179) by [@alejsdev](https://github.com/alejsdev).
|
* ♻️ Update meta titles. PR [#2179](https://github.com/fastapi/full-stack-fastapi-template/pull/2179) by [@alejsdev](https://github.com/alejsdev).
|
||||||
|
|
||||||
### Upgrades
|
### Upgrades
|
||||||
|
|
||||||
|
* ⬆️ Upgrade FastAPI version. PR [#2357](https://github.com/fastapi/full-stack-fastapi-template/pull/2357) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
* ⬆️ Upgrade Python to 3.14. PR [#2352](https://github.com/fastapi/full-stack-fastapi-template/pull/2352) by [@tiangolo](https://github.com/tiangolo).
|
||||||
* ⬆️ Upgrade Sentry and FastAPI. PR [#2181](https://github.com/fastapi/full-stack-fastapi-template/pull/2181) by [@patrick91](https://github.com/patrick91).
|
* ⬆️ Upgrade Sentry and FastAPI. PR [#2181](https://github.com/fastapi/full-stack-fastapi-template/pull/2181) by [@patrick91](https://github.com/patrick91).
|
||||||
|
|
||||||
### Docs
|
### Docs
|
||||||
@@ -19,6 +27,12 @@
|
|||||||
|
|
||||||
### Internal
|
### Internal
|
||||||
|
|
||||||
|
* ➕ Move prek to top level dependencies. PR [#2353](https://github.com/fastapi/full-stack-fastapi-template/pull/2353) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
* 🔧 Sort keys in pyproject.toml. PR [#2350](https://github.com/fastapi/full-stack-fastapi-template/pull/2350) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
* 👷 Simplify pull request workflow triggers. PR [#2349](https://github.com/fastapi/full-stack-fastapi-template/pull/2349) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
* 👷 Update issue-manager to 0.7.1. PR [#2348](https://github.com/fastapi/full-stack-fastapi-template/pull/2348) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
* ⬆️ Update issue-manager to 0.7.0. PR [#2347](https://github.com/fastapi/full-stack-fastapi-template/pull/2347) by [@tiangolo](https://github.com/tiangolo).
|
||||||
|
* 🔒️ Update zizmor workflow security checks. PR [#2345](https://github.com/fastapi/full-stack-fastapi-template/pull/2345) by [@tiangolo](https://github.com/tiangolo).
|
||||||
* 👷 Add pre-commit hook to catch typos. PR [#2317](https://github.com/fastapi/full-stack-fastapi-template/pull/2317) by [@YuriiMotov](https://github.com/YuriiMotov).
|
* 👷 Add pre-commit hook to catch typos. PR [#2317](https://github.com/fastapi/full-stack-fastapi-template/pull/2317) by [@YuriiMotov](https://github.com/YuriiMotov).
|
||||||
* Bump form-data from 4.0.5 to 4.0.6 in /frontend. PR [#2337](https://github.com/fastapi/full-stack-fastapi-template/pull/2337) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
* Bump form-data from 4.0.5 to 4.0.6 in /frontend. PR [#2337](https://github.com/fastapi/full-stack-fastapi-template/pull/2337) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||||
* ⬆ Bump starlette from 1.0.1 to 1.3.1. PR [#2338](https://github.com/fastapi/full-stack-fastapi-template/pull/2338) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
* ⬆ Bump starlette from 1.0.1 to 1.3.1. PR [#2338](https://github.com/fastapi/full-stack-fastapi-template/pull/2338) by [@dependabot[bot]](https://github.com/apps/dependabot).
|
||||||
|
|||||||
Reference in New Issue
Block a user