Skip to content

Commit ec637a9

Browse files
Add @validate decorator to input validation functions
- Import `validate` from `_internal.decorators`. - Apply `@validate` decorator to methods in `Application` and `Client` to enforce input validation. - Replace `find_spec('pydantic')` with `USING_PYDANTIC` in conditional Pydantic imports. - Add logic to log additional errors in `HTTPClient`.
1 parent e2d5891 commit ec637a9

File tree

8 files changed

+48
-10
lines changed

8 files changed

+48
-10
lines changed

squarecloud/app.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from squarecloud import errors
88

9+
from ._internal.decorators import validate
910
from .data import (
1011
AppData,
1112
Backup,
@@ -526,6 +527,7 @@ async def delete(self) -> Response:
526527
)
527528
return response
528529

530+
@validate
529531
async def commit(self, file: File) -> Response:
530532
"""
531533
The commit function is used to commit the application.
@@ -541,6 +543,7 @@ async def commit(self, file: File) -> Response:
541543
)
542544
return response
543545

546+
@validate
544547
async def files_list(self, path: str) -> list[FileInfo]:
545548
"""
546549
The files_list function returns a list of files and folders in the
@@ -558,6 +561,7 @@ async def files_list(self, path: str) -> list[FileInfo]:
558561
)
559562
return response
560563

564+
@validate
561565
async def read_file(self, path: str) -> BytesIO:
562566
"""
563567
The read_file function reads the contents of a file from an app.
@@ -572,6 +576,7 @@ async def read_file(self, path: str) -> BytesIO:
572576
)
573577
return response
574578

579+
@validate
575580
async def create_file(self, file: File, path: str) -> Response:
576581

577582
"""
@@ -591,6 +596,7 @@ async def create_file(self, file: File, path: str) -> Response:
591596
)
592597
return response
593598

599+
@validate
594600
async def delete_file(self, path: str) -> Response:
595601
"""
596602
The delete_file function deletes a file from the app.
@@ -620,6 +626,7 @@ async def last_deploys(self) -> list[list[DeployData]]:
620626
)
621627
return response
622628

629+
@validate
623630
async def github_integration(self, access_token: str) -> str:
624631
"""
625632
The create_github_integration function returns a webhook to integrate
@@ -642,6 +649,7 @@ async def domain_analytics(self) -> DomainAnalytics:
642649
)
643650
return analytics
644651

652+
@validate
645653
async def set_custom_domain(self, custom_domain: str):
646654
response: Response = await self.client.set_custom_domain(
647655
self.id, custom_domain, avoid_listener=True
@@ -652,6 +660,7 @@ async def all_backups(self):
652660
backups: list[BackupInfo] = await self.client.all_app_backups(self.id)
653661
return backups
654662

663+
@validate
655664
async def move_file(self, origin: str, dest: str):
656665
return await self.client.move_app_file(self.id, origin, dest)
657666

squarecloud/client.py

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

88
from typing_extensions import deprecated
99

10+
from ._internal.decorators import validate
1011
from .app import Application
1112
from .data import (
1213
AppData,
@@ -253,6 +254,7 @@ async def get_logs(self, app_id: str, **_kwargs) -> LogsData:
253254

254255
return logs_data
255256

257+
@validate
256258
@_notify_listener(Endpoint.app_status())
257259
async def app_status(self, app_id: str, **_kwargs) -> StatusData:
258260
"""
@@ -274,6 +276,7 @@ async def app_status(self, app_id: str, **_kwargs) -> StatusData:
274276
payload: dict[str, Any] = response.response
275277
return StatusData(**payload)
276278

279+
@validate
277280
@_notify_listener(Endpoint.start())
278281
async def start_app(self, app_id: str, **_kwargs) -> Response:
279282
"""
@@ -293,6 +296,7 @@ async def start_app(self, app_id: str, **_kwargs) -> Response:
293296
"""
294297
return await self._http.start_application(app_id)
295298

299+
@validate
296300
@_notify_listener(Endpoint.stop())
297301
async def stop_app(self, app_id: str, **_kwargs) -> Response:
298302
"""
@@ -312,6 +316,7 @@ async def stop_app(self, app_id: str, **_kwargs) -> Response:
312316
"""
313317
return await self._http.stop_application(app_id)
314318

319+
@validate
315320
@_notify_listener(Endpoint.restart())
316321
async def restart_app(self, app_id: str, **_kwargs) -> Response:
317322
"""
@@ -331,6 +336,7 @@ async def restart_app(self, app_id: str, **_kwargs) -> Response:
331336
"""
332337
return await self._http.restart_application(app_id)
333338

339+
@validate
334340
@_notify_listener(Endpoint.backup())
335341
async def backup(self, app_id: str, **_kwargs) -> Backup:
336342
"""
@@ -354,6 +360,7 @@ async def backup(self, app_id: str, **_kwargs) -> Backup:
354360

355361
# async def app_backups(self) -> list[BackupInfo]:
356362

363+
@validate
357364
@_notify_listener(Endpoint.delete_app())
358365
async def delete_app(self, app_id: str, **_kwargs) -> Response:
359366
"""
@@ -373,6 +380,7 @@ async def delete_app(self, app_id: str, **_kwargs) -> Response:
373380
"""
374381
return await self._http.delete_application(app_id)
375382

383+
@validate
376384
@_notify_listener(Endpoint.commit())
377385
async def commit(self, app_id: str, file: File, **_kwargs) -> Response:
378386
"""
@@ -393,6 +401,7 @@ async def commit(self, app_id: str, file: File, **_kwargs) -> Response:
393401
"""
394402
return await self._http.commit(app_id, file)
395403

404+
@validate
396405
@_notify_listener(Endpoint.user())
397406
async def app(self, app_id: str, **_kwargs) -> Application:
398407
"""
@@ -454,6 +463,7 @@ async def all_apps(self, **_kwargs) -> list[Application]:
454463
apps.append(Application(client=self, http=self._http, **data))
455464
return apps
456465

466+
@validate
457467
@_notify_listener(Endpoint.upload())
458468
async def upload_app(self, file: File, **_kwargs) -> UploadData:
459469
"""
@@ -508,6 +518,7 @@ async def upload_app(self, file: File, **_kwargs) -> UploadData:
508518
payload: dict[str, Any] = response.response
509519
return UploadData(**payload)
510520

521+
@validate
511522
@_notify_listener(Endpoint.files_list())
512523
async def app_files_list(
513524
self, app_id: str, path: str, **_kwargs
@@ -538,6 +549,7 @@ async def app_files_list(
538549
for data in response.response
539550
]
540551

552+
@validate
541553
@_notify_listener(Endpoint.files_read())
542554
async def read_app_file(
543555
self, app_id: str, path: str, **_kwargs
@@ -563,6 +575,7 @@ async def read_app_file(
563575
if response.response:
564576
return BytesIO(bytes(response.response.get('data')))
565577

578+
@validate
566579
@_notify_listener(Endpoint.files_create())
567580
async def create_app_file(
568581
self, app_id: str, file: File, path: str, **_kwargs
@@ -597,6 +610,7 @@ async def create_app_file(
597610

598611
return response
599612

613+
@validate
600614
@_notify_listener(Endpoint.files_delete())
601615
async def delete_app_file(
602616
self, app_id: str, path: str, **_kwargs
@@ -620,6 +634,7 @@ async def delete_app_file(
620634
"""
621635
return await self._http.file_delete(app_id, path)
622636

637+
@validate
623638
@_notify_listener(Endpoint.app_data())
624639
async def app_data(self, app_id: str, **_kwargs) -> AppData:
625640
"""
@@ -640,6 +655,7 @@ async def app_data(self, app_id: str, **_kwargs) -> AppData:
640655
response: Response = await self._http.get_app_data(app_id)
641656
return AppData(**response.response)
642657

658+
@validate
643659
@_notify_listener(Endpoint.last_deploys())
644660
async def last_deploys(
645661
self, app_id: str, **_kwargs
@@ -664,6 +680,7 @@ async def last_deploys(
664680
data = response.response
665681
return [[DeployData(**deploy) for deploy in _] for _ in data]
666682

683+
@validate
667684
@_notify_listener(Endpoint.github_integration())
668685
async def github_integration(
669686
self, app_id: str, access_token: str, **_kwargs
@@ -692,6 +709,7 @@ async def github_integration(
692709
data = response.response
693710
return data.get('webhook')
694711

712+
@validate
695713
@_notify_listener(Endpoint.custom_domain())
696714
async def set_custom_domain(
697715
self, app_id: str, custom_domain: str, **_kwargs
@@ -717,6 +735,7 @@ async def set_custom_domain(
717735
app_id=app_id, custom_domain=custom_domain
718736
)
719737

738+
@validate
720739
@_notify_listener(Endpoint.domain_analytics())
721740
async def domain_analytics(
722741
self, app_id: str, **_kwargs
@@ -742,6 +761,7 @@ async def domain_analytics(
742761

743762
return DomainAnalytics(**response.response)
744763

764+
@validate
745765
@_notify_listener(Endpoint.all_backups())
746766
async def all_app_backups(
747767
self, app_id: str, **_kwargs
@@ -760,6 +780,7 @@ async def all_apps_status(self, **_kwargs) -> list[ResumedStatus]:
760780
all_status.append(ResumedStatus(**status))
761781
return all_status
762782

783+
@validate
763784
@_notify_listener(Endpoint.move_file())
764785
async def move_app_file(
765786
self, app_id: str, origin: str, dest: str, **_kwargs
@@ -769,11 +790,13 @@ async def move_app_file(
769790
)
770791
return response
771792

793+
@validate
772794
@_notify_listener(Endpoint.dns_records())
773795
async def dns_records(self, app_id: str) -> list[DNSRecord]:
774796
response: Response = await self._http.dns_records(app_id)
775797
return [DNSRecord(**data) for data in response.response]
776798

799+
@validate
777800
@_notify_listener(Endpoint.current_integration())
778801
async def current_app_integration(self, app_id: str) -> str | None:
779802
response: Response = await self._http.get_app_current_integration(

squarecloud/data.py

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

33
from datetime import datetime
4-
from importlib.util import find_spec
54
from typing import Any, Dict, Literal, Optional
65

7-
if find_spec('pydantic'):
6+
from ._internal.constants import USING_PYDANTIC
7+
8+
if USING_PYDANTIC:
89
from pydantic.dataclasses import dataclass
910
else:
1011
from dataclasses import dataclass

squarecloud/http/http_client.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ async def request(self, route: Router, **kwargs) -> Response | bytes:
216216
log_level = logging.ERROR
217217
error = TooManyRequests
218218
case _:
219+
log_level = logging.ERROR
219220
error = RequestError
220221

221222
if _ := _get_error(code):

squarecloud/listeners/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import inspect
22
import types
33
from dataclasses import dataclass
4-
from importlib.util import find_spec
54
from types import MappingProxyType
65
from typing import TYPE_CHECKING, Any, Callable, Optional, Type, Union
76

8-
if find_spec('pydantic'):
7+
from .._internal.constants import USING_PYDANTIC
8+
9+
if USING_PYDANTIC:
910
import pydantic
1011
from pydantic import BaseModel
1112

squarecloud/listeners/capture_listener.py

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

76
from .. import data, errors
7+
from .._internal.constants import USING_PYDANTIC
88
from ..http import Endpoint
99
from . import Listener, ListenerManager
1010

11-
if find_spec('pydantic'):
11+
if USING_PYDANTIC:
1212
import pydantic
1313

1414
ListenerDataTypes = Union[

squarecloud/listeners/request_listener.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import inspect
22
import logging
33
import types
4-
from importlib.util import find_spec
54
from typing import Any
65

7-
if using_pydantic := find_spec('pydantic'):
6+
from .._internal.constants import USING_PYDANTIC
7+
8+
if USING_PYDANTIC:
89
import pydantic
910

1011
from ..http import Endpoint, Response
@@ -39,7 +40,6 @@ async def notify(
3940
:param response: Response: Get the response from the endpoint
4041
:return: The result of the call function
4142
"""
42-
global using_pydantic
4343

4444
def filter_annotations(annotations: list[Any]) -> Any:
4545
for item in annotations:
@@ -65,7 +65,7 @@ def filter_annotations(annotations: list[Any]) -> Any:
6565
call_extra_param is not None
6666
and annotation is not None
6767
and annotation != call_extra_param.empty
68-
and using_pydantic
68+
and USING_PYDANTIC
6969
):
7070
annotation: Any = call_extra_param.annotation
7171
cast_result = self.cast_to_pydantic_model(annotation, extra)

squarecloud/utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from typing import Any, Literal
22

3+
from squarecloud._internal.decorators import validate
4+
35

46
class ConfigFile:
57
"""
@@ -8,6 +10,7 @@ class ConfigFile:
810
https://docs.squarecloud.app/articles/how-to-create-your-squarecloud-configuration-file
911
"""
1012

13+
@validate
1114
def __init__(
1215
self,
1316
display_name: str,

0 commit comments

Comments
 (0)