Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,6 @@ jobs:
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
pydantic-version: ["v2"]
include:
- python-version: "3.9"
pydantic-version: "v1"
- python-version: "3.10"
pydantic-version: "v1"
- python-version: "3.11"
pydantic-version: "v1"
- python-version: "3.12"
pydantic-version: "v1"
fail-fast: false
runs-on: ubuntu-latest
env:
Expand Down Expand Up @@ -63,9 +53,6 @@ jobs:
limit-access-to-actor: true
- name: Install Dependencies
run: uv sync --locked --all-extras --dev
- name: Install Pydantic v1
if: matrix.pydantic-version == 'v1'
run: uv pip install "pydantic<2.0.0"
- name: Lint
run: uv run --no-sync scripts/lint.sh
- run: mkdir coverage
Expand All @@ -77,7 +64,7 @@ jobs:
- name: Store coverage files
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.python-version }}-${{ matrix.pydantic-version }}
name: coverage-${{ matrix.python-version }}
path: coverage
include-hidden-files: true

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ dependencies = [
"rignore >= 0.5.1",
"httpx >= 0.27.0",
"rich-toolkit >= 0.14.5",
"pydantic[email] >= 1.6.1",
"pydantic[email] >= 2.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FastAPI requires >= 2.7, but it's fine by me either way.

"sentry-sdk >= 2.20.0",
"fastar >= 0.8.0",
]
Expand Down
26 changes: 10 additions & 16 deletions src/fastapi_cloud_cli/commands/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import rignore
import typer
from httpx import Client
from pydantic import BaseModel, EmailStr, ValidationError
from pydantic import BaseModel, EmailStr, TypeAdapter, ValidationError
from rich.text import Text
from rich_toolkit import RichToolkit
from rich_toolkit.menu import Option
Expand All @@ -23,11 +23,6 @@
from fastapi_cloud_cli.utils.apps import AppConfig, get_app_config, write_app_config
from fastapi_cloud_cli.utils.auth import is_logged_in
from fastapi_cloud_cli.utils.cli import get_rich_toolkit, handle_http_errors
from fastapi_cloud_cli.utils.pydantic_compat import (
TypeAdapter,
model_dump,
model_validate,
)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -108,7 +103,7 @@ def _get_teams() -> list[Team]:

data = response.json()["data"]

return [model_validate(Team, team) for team in data]
return [Team.model_validate(team) for team in data]


class AppResponse(BaseModel):
Expand All @@ -125,7 +120,7 @@ def _create_app(team_id: str, app_name: str) -> AppResponse:

response.raise_for_status()

return model_validate(AppResponse, response.json())
return AppResponse.model_validate(response.json())


class DeploymentStatus(str, Enum):
Expand Down Expand Up @@ -178,7 +173,7 @@ def _create_deployment(app_id: str) -> CreateDeploymentResponse:
response = client.post(f"/apps/{app_id}/deployments/")
response.raise_for_status()

return model_validate(CreateDeploymentResponse, response.json())
return CreateDeploymentResponse.model_validate(response.json())


class RequestUploadResponse(BaseModel):
Expand All @@ -203,7 +198,7 @@ def _upload_deployment(deployment_id: str, archive_path: Path) -> None:
response = fastapi_client.post(f"/deployments/{deployment_id}/upload")
response.raise_for_status()

upload_data = model_validate(RequestUploadResponse, response.json())
upload_data = RequestUploadResponse.model_validate(response.json())
logger.debug("Received upload URL: %s", upload_data.url)

logger.debug("Starting file upload to S3")
Expand Down Expand Up @@ -238,7 +233,7 @@ def _get_app(app_slug: str) -> Optional[AppResponse]:

data = response.json()

return model_validate(AppResponse, data)
return AppResponse.model_validate(data)


def _get_apps(team_id: str) -> list[AppResponse]:
Expand All @@ -248,7 +243,7 @@ def _get_apps(team_id: str) -> list[AppResponse]:

data = response.json()["data"]

return [model_validate(AppResponse, app) for app in data]
return [AppResponse.model_validate(app) for app in data]


WAITING_MESSAGES = [
Expand Down Expand Up @@ -434,7 +429,7 @@ def _send_waitlist_form(
with toolkit.progress("Sending your request...") as progress:
with APIClient() as client:
with handle_http_errors(progress):
response = client.post("/users/waiting-list", json=model_dump(result))
response = client.post("/users/waiting-list", json=result.model_dump())

response.raise_for_status()

Expand All @@ -459,7 +454,7 @@ def _waitlist_form(toolkit: RichToolkit) -> None:

toolkit.print_line()

result = model_validate(SignupToWaitingList, {"email": email})
result = SignupToWaitingList.model_validate({"email": email})

if toolkit.confirm(
"Do you want to get access faster by giving us more information?",
Expand All @@ -483,8 +478,7 @@ def _waitlist_form(toolkit: RichToolkit) -> None:
result = form.run() # type: ignore

try:
result = model_validate(
SignupToWaitingList,
result = SignupToWaitingList.model_validate(
{
"email": email,
**result, # type: ignore
Expand Down
3 changes: 1 addition & 2 deletions src/fastapi_cloud_cli/commands/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from fastapi_cloud_cli.utils.auth import is_logged_in
from fastapi_cloud_cli.utils.cli import get_rich_toolkit, handle_http_errors
from fastapi_cloud_cli.utils.env import validate_environment_variable_name
from fastapi_cloud_cli.utils.pydantic_compat import model_validate

logger = logging.getLogger(__name__)

Expand All @@ -29,7 +28,7 @@ def _get_environment_variables(app_id: str) -> EnvironmentVariableResponse:
response = client.get(f"/apps/{app_id}/environment-variables/")
response.raise_for_status()

return model_validate(EnvironmentVariableResponse, response.json())
return EnvironmentVariableResponse.model_validate(response.json())


def _delete_environment_variable(app_id: str, name: str) -> bool:
Expand Down
5 changes: 2 additions & 3 deletions src/fastapi_cloud_cli/commands/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
write_auth_config,
)
from fastapi_cloud_cli.utils.cli import get_rich_toolkit, handle_http_errors
from fastapi_cloud_cli.utils.pydantic_compat import model_validate_json

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -44,7 +43,7 @@ def _start_device_authorization(

response.raise_for_status()

return model_validate_json(AuthorizationData, response.text)
return AuthorizationData.model_validate_json(response.text)


def _fetch_access_token(client: httpx.Client, device_code: str, interval: int) -> str:
Expand Down Expand Up @@ -74,7 +73,7 @@ def _fetch_access_token(client: httpx.Client, device_code: str, interval: int) -

time.sleep(interval)

response_data = model_validate_json(TokenResponse, response.text)
response_data = TokenResponse.model_validate_json(response.text)

return response_data.access_token

Expand Down
7 changes: 3 additions & 4 deletions src/fastapi_cloud_cli/utils/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@
)

import httpx
from pydantic import BaseModel, Field, ValidationError
from pydantic import BaseModel, Field, TypeAdapter, ValidationError
from typing_extensions import ParamSpec

from fastapi_cloud_cli import __version__
from fastapi_cloud_cli.config import Settings
from fastapi_cloud_cli.utils.auth import get_auth_token
from fastapi_cloud_cli.utils.pydantic_compat import TypeAdapter

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -49,8 +48,8 @@ class BuildLogLineMessage(BaseModel):


BuildLogLine = Union[BuildLogLineMessage, BuildLogLineGeneric]
BuildLogAdapter = TypeAdapter[BuildLogLine](
Annotated[BuildLogLine, Field(discriminator="type")] # type: ignore
BuildLogAdapter: TypeAdapter[BuildLogLine] = TypeAdapter(
Annotated[BuildLogLine, Field(discriminator="type")]
)


Expand Down
6 changes: 2 additions & 4 deletions src/fastapi_cloud_cli/utils/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

from pydantic import BaseModel

from fastapi_cloud_cli.utils.pydantic_compat import model_dump_json, model_validate_json

logger = logging.getLogger("fastapi_cli")


Expand All @@ -23,7 +21,7 @@ def get_app_config(path_to_deploy: Path) -> Optional[AppConfig]:
return None

logger.debug("App config loaded successfully")
return model_validate_json(AppConfig, config_path.read_text(encoding="utf-8"))
return AppConfig.model_validate_json(config_path.read_text(encoding="utf-8"))


README = """
Expand Down Expand Up @@ -52,7 +50,7 @@ def write_app_config(path_to_deploy: Path, app_config: AppConfig) -> None:
config_path.parent.mkdir(parents=True, exist_ok=True)

config_path.write_text(
model_dump_json(app_config),
app_config.model_dump_json(),
encoding="utf-8",
)
readme_path.write_text(README, encoding="utf-8")
Expand Down
6 changes: 2 additions & 4 deletions src/fastapi_cloud_cli/utils/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

from pydantic import BaseModel

from fastapi_cloud_cli.utils.pydantic_compat import model_dump_json, model_validate_json

from .config import get_auth_path

logger = logging.getLogger("fastapi_cli")
Expand All @@ -22,7 +20,7 @@ def write_auth_config(auth_data: AuthConfig) -> None:
auth_path = get_auth_path()
logger.debug("Writing auth config to: %s", auth_path)

auth_path.write_text(model_dump_json(auth_data), encoding="utf-8")
auth_path.write_text(auth_data.model_dump_json(), encoding="utf-8")
logger.debug("Auth config written successfully")


Expand All @@ -46,7 +44,7 @@ def read_auth_config() -> Optional[AuthConfig]:
return None

logger.debug("Auth config loaded successfully")
return model_validate_json(AuthConfig, auth_path.read_text(encoding="utf-8"))
return AuthConfig.model_validate_json(auth_path.read_text(encoding="utf-8"))


def get_auth_token() -> Optional[str]:
Expand Down
72 changes: 0 additions & 72 deletions src/fastapi_cloud_cli/utils/pydantic_compat.py

This file was deleted.

2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.