Skip to content

Commit 8ef0554

Browse files
committed
More compat
1 parent 9e8fa41 commit 8ef0554

File tree

5 files changed

+54
-14
lines changed

5 files changed

+54
-14
lines changed

src/fastapi_cloud_cli/commands/deploy.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import rignore
1414
import typer
1515
from httpx import Client
16-
from pydantic import BaseModel, EmailStr, TypeAdapter, ValidationError
16+
from pydantic import BaseModel, EmailStr, ValidationError
1717
from rich.text import Text
1818
from rich_toolkit import RichToolkit
1919
from rich_toolkit.menu import Option
@@ -24,7 +24,11 @@
2424
from fastapi_cloud_cli.utils.apps import AppConfig, get_app_config, write_app_config
2525
from fastapi_cloud_cli.utils.auth import is_logged_in
2626
from fastapi_cloud_cli.utils.cli import get_rich_toolkit, handle_http_errors
27-
from fastapi_cloud_cli.utils.pydantic_compat import model_validate
27+
from fastapi_cloud_cli.utils.pydantic_compat import (
28+
TypeAdapter,
29+
model_dump,
30+
model_validate,
31+
)
2832

2933
logger = logging.getLogger(__name__)
3034

@@ -417,9 +421,7 @@ def _send_waitlist_form(
417421
with toolkit.progress("Sending your request...") as progress:
418422
with APIClient() as client:
419423
with handle_http_errors(progress):
420-
response = client.post(
421-
"/users/waiting-list", json=result.model_dump(mode="json")
422-
)
424+
response = client.post("/users/waiting-list", json=model_dump(result))
423425

424426
response.raise_for_status()
425427

@@ -444,7 +446,7 @@ def _waitlist_form(toolkit: RichToolkit) -> None:
444446

445447
toolkit.print_line()
446448

447-
result = SignupToWaitingList(email=email)
449+
result = model_validate(SignupToWaitingList, {"email": email})
448450

449451
if toolkit.confirm(
450452
"Do you want to get access faster by giving us more information?",

src/fastapi_cloud_cli/commands/login.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
write_auth_config,
1717
)
1818
from fastapi_cloud_cli.utils.cli import get_rich_toolkit, handle_http_errors
19-
from fastapi_cloud_cli.utils.pydantic_compat import model_validate
19+
from fastapi_cloud_cli.utils.pydantic_compat import model_validate_json
2020

2121
logger = logging.getLogger(__name__)
2222

@@ -44,7 +44,7 @@ def _start_device_authorization(
4444

4545
response.raise_for_status()
4646

47-
return model_validate(AuthorizationData, response.json())
47+
return model_validate_json(AuthorizationData, response.text)
4848

4949

5050
def _fetch_access_token(client: httpx.Client, device_code: str, interval: int) -> str:
@@ -74,7 +74,7 @@ def _fetch_access_token(client: httpx.Client, device_code: str, interval: int) -
7474

7575
time.sleep(interval)
7676

77-
response_data = model_validate(TokenResponse, response.json())
77+
response_data = model_validate_json(TokenResponse, response.text)
7878

7979
return response_data.access_token
8080

src/fastapi_cloud_cli/utils/apps.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from pydantic import BaseModel
66

7-
from fastapi_cloud_cli.utils.pydantic_compat import model_validate_json
7+
from fastapi_cloud_cli.utils.pydantic_compat import model_dump_json, model_validate_json
88

99
logger = logging.getLogger("fastapi_cli")
1010

@@ -52,7 +52,7 @@ def write_app_config(path_to_deploy: Path, app_config: AppConfig) -> None:
5252
config_path.parent.mkdir(parents=True, exist_ok=True)
5353

5454
config_path.write_text(
55-
app_config.model_dump_json(),
55+
model_dump_json(app_config),
5656
encoding="utf-8",
5757
)
5858
readme_path.write_text(README, encoding="utf-8")

src/fastapi_cloud_cli/utils/auth.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from pydantic import BaseModel
99

10-
from fastapi_cloud_cli.utils.pydantic_compat import model_validate_json
10+
from fastapi_cloud_cli.utils.pydantic_compat import model_dump_json, model_validate_json
1111

1212
from .config import get_auth_path
1313

@@ -22,7 +22,7 @@ def write_auth_config(auth_data: AuthConfig) -> None:
2222
auth_path = get_auth_path()
2323
logger.debug("Writing auth config to: %s", auth_path)
2424

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

2828

src/fastapi_cloud_cli/utils/pydantic_compat.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict, Type, TypeVar
1+
from typing import Any, Dict, Generic, Type, TypeVar
22

33
from pydantic import BaseModel
44
from pydantic.version import VERSION as PYDANTIC_VERSION
@@ -7,6 +7,7 @@
77
PYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2
88

99

10+
T = TypeVar("T")
1011
Model = TypeVar("Model", bound=BaseModel)
1112

1213

@@ -22,3 +23,40 @@ def model_validate_json(model_class: Type[Model], data: str) -> Model:
2223
return model_class.model_validate_json(data) # type: ignore[no-any-return, unused-ignore, attr-defined]
2324
else:
2425
return model_class.parse_raw(data) # type: ignore[no-any-return, unused-ignore, attr-defined]
26+
27+
28+
def model_dump(obj: BaseModel, **kwargs: Any) -> Dict[Any, Any]:
29+
if PYDANTIC_V2:
30+
return obj.model_dump(**kwargs) # type: ignore[no-any-return, unused-ignore, attr-defined]
31+
else:
32+
return obj.dict(**kwargs) # type: ignore[no-any-return, unused-ignore, attr-defined]
33+
34+
35+
def model_dump_json(obj: BaseModel) -> str:
36+
if PYDANTIC_V2:
37+
return obj.model_dump_json() # type: ignore[no-any-return, unused-ignore, attr-defined]
38+
else:
39+
return obj.json() # type: ignore[no-any-return, unused-ignore, attr-defined]
40+
41+
42+
class TypeAdapter(Generic[T]):
43+
def __init__(self, type_: Type[T]) -> None:
44+
self.type_ = type_
45+
46+
if PYDANTIC_V2:
47+
from pydantic import ( # type: ignore[attr-defined, unused-ignore]
48+
TypeAdapter as PydanticTypeAdapter,
49+
)
50+
51+
self._adapter = PydanticTypeAdapter(type_)
52+
else:
53+
self._adapter = None # type: ignore[assignment, unused-ignore]
54+
55+
def validate_python(self, value: Any) -> T:
56+
"""Validate a Python object against the type."""
57+
if PYDANTIC_V2:
58+
return self._adapter.validate_python(value) # type: ignore[no-any-return, union-attr, unused-ignore]
59+
else:
60+
from pydantic import parse_obj_as
61+
62+
return parse_obj_as(self.type_, value) # type: ignore[no-any-return, unused-ignore]

0 commit comments

Comments
 (0)