Skip to content

Commit ae58e8e

Browse files
♻️ Adaptations to make the installation of Pydantic optional
1 parent b7ae71d commit ae58e8e

File tree

10 files changed

+86
-42
lines changed

10 files changed

+86
-42
lines changed

pyproject.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = 'squarecloud-api'
3-
version = '3.5.1'
3+
version = '3.6.2'
44
description = 'SquareCloud API wrapper'
55
authors = ['Robert Nogueira <robertlucasnogueira@gmail.com>']
66
repository = 'https://github.com/squarecloudofc/wrapper-api-py'
@@ -12,8 +12,11 @@ packages = [{ include = 'squarecloud' }]
1212
[tool.poetry.dependencies]
1313
python = '^3.9'
1414
aiohttp = "3.9.5"
15-
pydantic = '^2.5.2'
1615
taskipy = "^1.13.0"
16+
pydantic = {version = "^2.8.2", optional = true}
17+
18+
[tool.poetry.extras]
19+
pydantic = ["pydantic"]
1720

1821
[tool.poetry.group.dev.dependencies]
1922
pytest = '^7.4.3'
@@ -26,6 +29,8 @@ ruff = '^0.0.289'
2629
memory-profiler = '^0.61.0'
2730
requests = '^2.31.0'
2831
pytest-rerunfailures = "^13.0"
32+
python-dotenv = "^1.0.1"
33+
rich = "^13.7.1"
2934

3035
[build-system]
3136
requires = ['poetry-core']

squarecloud/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
from .file import File
2222
from .http.endpoints import Endpoint
2323

24-
__version__ = '3.5.1'
24+
__version__ = '3.6.2'

squarecloud/app.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
from io import BytesIO
55
from typing import TYPE_CHECKING, Any, Callable
66

7-
from pydantic import PositiveInt
8-
97
from squarecloud import errors
108

119
from .data import (
@@ -170,7 +168,7 @@ def __init__(
170168
http: HTTPClient,
171169
id: str,
172170
name: str,
173-
ram: PositiveInt,
171+
ram: int,
174172
lang: str,
175173
cluster: str,
176174
domain: str | None,
@@ -203,7 +201,7 @@ def __init__(
203201
self._domain: str | None = domain
204202
self._custom: str | None = custom
205203
self._desc: str | None = desc
206-
self._ram: PositiveInt = ram
204+
self._ram: int = ram
207205
self._lang: str = lang
208206
self._cluster: str = cluster
209207
self._client: 'Client' = client

squarecloud/data.py

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
from __future__ import annotations
22

33
from datetime import datetime
4+
from importlib.util import find_spec
45
from typing import Any, Dict, Literal, Optional
56

6-
from pydantic import confloat, conint
7-
from pydantic.dataclasses import dataclass
7+
if find_spec('pydantic'):
8+
from pydantic.dataclasses import dataclass
9+
else:
10+
from dataclasses import dataclass
811

912

1013
@dataclass(frozen=True)
@@ -67,9 +70,9 @@ class StatusData:
6770
running: bool
6871
storage: str
6972
network: Dict[str, Any]
70-
requests: conint(ge=0)
71-
uptime: conint(ge=0) | None = None
72-
time: conint(ge=0) | None = None
73+
requests: int
74+
uptime: int | None = None
75+
time: int | None = None
7376

7477
def to_dict(self):
7578
return self.__dict__.copy()
@@ -107,7 +110,7 @@ class AppData:
107110
id: str
108111
name: str
109112
cluster: str
110-
ram: confloat(ge=0)
113+
ram: float
111114
language: Optional[str]
112115
cluster: str
113116
domain: str | None = None
@@ -128,13 +131,13 @@ class UserData:
128131
:ivar plan: User plan
129132
:ivar email: User email
130133
131-
:type id: conint(ge=0)
134+
:type id: int
132135
:type name: str
133136
:type plan: PlanData
134137
:type email: str | None = None
135138
"""
136139

137-
id: conint(ge=0)
140+
id: int
138141
name: str
139142
plan: PlanData
140143
email: str | None = None
@@ -253,9 +256,9 @@ class UploadData:
253256
id: str
254257
name: str
255258
language: Language
256-
ram: confloat(ge=0)
257-
cpu: confloat(ge=0)
258-
subdomain: str | None = None
259+
ram: float
260+
cpu: float
261+
domain: str | None = None
259262
description: str | None = None
260263

261264
def to_dict(self):
@@ -283,9 +286,9 @@ class FileInfo:
283286
app_id: str
284287
type: Literal['file', 'directory']
285288
name: str
286-
lastModified: conint(ge=0) | float
289+
lastModified: int | float
287290
path: str
288-
size: confloat(ge=0.0) = 0.0
291+
size: int = 0
289292

290293
def to_dict(self):
291294
return self.__dict__.copy()
@@ -310,17 +313,33 @@ class AnalyticsTotal:
310313

311314
@dataclass(frozen=True)
312315
class DomainAnalytics:
313-
hostname: str
314-
total: list[AnalyticsTotal]
315-
countries: list[Any]
316-
methods: list[Any]
317-
referers: list[Any]
318-
browsers: list[Any]
319-
deviceTypes: list[Any]
320-
operatingSystems: list[Any]
321-
agents: list[Any]
322-
hosts: list[Any]
323-
paths: list[Any]
316+
@dataclass(frozen=True)
317+
class Analytics:
318+
total: list[AnalyticsTotal]
319+
countries: list[Any]
320+
methods: list[Any]
321+
referers: list[Any]
322+
browsers: list[Any]
323+
deviceTypes: list[Any]
324+
operatingSystems: list[Any]
325+
agents: list[Any]
326+
hosts: list[Any]
327+
paths: list[Any]
328+
329+
def to_dict(self):
330+
return self.__dict__.copy()
331+
332+
@dataclass(frozen=True)
333+
class Domain:
334+
hostname: str
335+
analytics: DomainAnalytics.Analytics | None
336+
337+
@dataclass(frozen=True)
338+
class Custom:
339+
analytics: DomainAnalytics.Analytics | None
340+
341+
domain: Domain
342+
custom: Custom
324343

325344
def to_dict(self):
326345
return self.__dict__.copy()

squarecloud/listeners/__init__.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import inspect
22
import types
33
from dataclasses import dataclass
4+
from importlib.util import find_spec
45
from types import MappingProxyType
56
from typing import TYPE_CHECKING, Any, Callable, Optional, Type, Union
67

7-
import pydantic
8-
from pydantic import BaseModel
8+
if find_spec('pydantic'):
9+
import pydantic
10+
from pydantic import BaseModel
911

1012
from .. import data, errors
1113
from ..http.endpoints import Endpoint
@@ -137,9 +139,9 @@ def clear_listeners(self) -> None:
137139

138140
@classmethod
139141
def cast_to_pydantic_model(
140-
cls, model: Type[BaseModel], values: dict[Any, Any]
142+
cls, model: Type['BaseModel'], values: dict[Any, Any]
141143
):
142-
result: BaseModel | None | dict = values
144+
result: 'BaseModel' | None | dict = values
143145
if isinstance(model, types.UnionType):
144146
for ty in model.__args__:
145147
if ty is None:

squarecloud/listeners/capture_listener.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import inspect
22
import logging
33
import types
4+
from importlib.util import find_spec
45
from typing import Any, Union
56

6-
import pydantic
7-
87
from .. import data, errors
98
from ..http import Endpoint
109
from . import Listener, ListenerManager
1110

11+
if find_spec('pydantic'):
12+
import pydantic
13+
1214
ListenerDataTypes = Union[
1315
data.AppData,
1416
data.StatusData,

squarecloud/listeners/request_listener.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import inspect
22
import logging
33
import types
4+
from importlib.util import find_spec
45
from typing import Any
56

6-
import pydantic
7+
if using_pydantic := find_spec('pydantic'):
8+
import pydantic
79

810
from ..http import Endpoint, Response
911
from . import ListenerManager
@@ -37,6 +39,7 @@ async def notify(
3739
:param response: Response: Get the response from the endpoint
3840
:return: The result of the call function
3941
"""
42+
global using_pydantic
4043

4144
def filter_annotations(annotations: list[Any]) -> Any:
4245
for item in annotations:
@@ -62,6 +65,7 @@ def filter_annotations(annotations: list[Any]) -> Any:
6265
call_extra_param is not None
6366
and annotation is not None
6467
and annotation != call_extra_param.empty
68+
and using_pydantic
6569
):
6670
annotation: Any = call_extra_param.annotation
6771
cast_result = self.cast_to_pydantic_model(annotation, extra)

tests/test_capture_listeners.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
from importlib.util import find_spec
2+
13
import pytest
2-
from pydantic import BaseModel
4+
5+
if using_pydantic := find_spec('pydantic'):
6+
from pydantic import BaseModel
37

48
from squarecloud import Endpoint, errors
59
from squarecloud.app import Application
@@ -127,6 +131,9 @@ def callback_two():
127131
assert listener.callback is callback_two
128132
assert listener.endpoint == Endpoint.app_status()
129133

134+
@pytest.mark.skipif(
135+
'not using_pydantic', reason='pydantic not installed'
136+
)
130137
@_clear_listener_on_rerun(endpoint=Endpoint.app_status())
131138
async def test_pydantic_cast(self, app: Application):
132139
class Person(BaseModel):

tests/test_files.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ async def test_files_type(self, app_files: list[FileInfo]):
1818
assert isinstance(file, FileInfo)
1919

2020
assert isinstance(file.name, str)
21-
assert isinstance(file.size, float)
21+
assert isinstance(file.size, int)
2222
assert isinstance(file.lastModified, int | float)
2323

2424
assert file.type in ('file', 'directory')
@@ -52,7 +52,7 @@ async def test_files_list(
5252
assert isinstance(file, FileInfo)
5353

5454
assert isinstance(file.name, str)
55-
assert isinstance(file.size, float)
55+
assert isinstance(file.size, int)
5656
assert isinstance(file.lastModified, int | float)
5757

5858
assert file.type in ('file', 'directory')

tests/test_request_listeners.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import sys
2+
from importlib.util import find_spec
13
from io import BytesIO
24

35
import pytest
4-
from pydantic import BaseModel
6+
7+
if using_pydantic := bool(find_spec('pydantic')):
8+
from pydantic import BaseModel
59

610
from squarecloud import Client, Endpoint, File
711
from squarecloud.app import Application
@@ -395,6 +399,9 @@ async def test_listener(response: Response):
395399
assert isinstance(expected_result, str)
396400
assert isinstance(expected_response, Response)
397401

402+
@pytest.mark.skipif(
403+
'not using_pydantic', reason='pydantic not installed'
404+
)
398405
@_clear_listener_on_rerun(endpoint=Endpoint.app_status())
399406
async def test_pydantic_cast(self, client: Client, app: Application):
400407
class Person(BaseModel):

0 commit comments

Comments
 (0)