Skip to content

Commit 6deb2ec

Browse files
committed
Better typing annotations and some updates to match TS lib
1 parent 2e26131 commit 6deb2ec

39 files changed

+968
-636
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44

55
.vscode/
6+
.ruff_cache/
67

78
### Python ###
89
# Byte-compiled / optimized / DLL files

pocketbase/client.py

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,30 @@
11
from __future__ import annotations
22

33
from typing import Any, Dict
4-
from urllib.parse import quote, urlencode
54

65
import httpx
76

7+
from pocketbase.errors import ClientResponseError
88
from pocketbase.models import FileUpload
99
from pocketbase.models.record import Record
1010
from pocketbase.services.admin_service import AdminService
1111
from pocketbase.services.backups_service import BackupsService
1212
from pocketbase.services.collection_service import CollectionService
13+
from pocketbase.services.files_service import FileService
14+
from pocketbase.services.health_service import HealthService
1315
from pocketbase.services.log_service import LogService
1416
from pocketbase.services.realtime_service import RealtimeService
1517
from pocketbase.services.record_service import RecordService
1618
from pocketbase.services.settings_service import SettingsService
17-
from pocketbase.stores.base_auth_store import BaseAuthStore
18-
from pocketbase.utils import ClientResponseError
19+
from pocketbase.stores.base_auth_store import AuthStore, BaseAuthStore
1920

2021

2122
class Client:
22-
base_url: str
23-
lang: str
24-
auth_store: BaseAuthStore
25-
settings: SettingsService
26-
admins: AdminService
27-
collections: CollectionService
28-
records: RecordService
29-
logs: LogService
30-
realtime: RealtimeService
31-
record_service: Dict[str, RecordService]
32-
3323
def __init__(
3424
self,
3525
base_url: str = "/",
3626
lang: str = "en-US",
37-
auth_store: BaseAuthStore | None = None,
27+
auth_store: AuthStore | None = None,
3828
timeout: float = 120,
3929
http_client: httpx.Client | None = None,
4030
) -> None:
@@ -47,16 +37,12 @@ def __init__(
4737
self.admins = AdminService(self)
4838
self.backups = BackupsService(self)
4939
self.collections = CollectionService(self)
40+
self.files = FileService(self)
41+
self.health = HealthService(self)
5042
self.logs = LogService(self)
5143
self.settings = SettingsService(self)
5244
self.realtime = RealtimeService(self)
53-
self.record_service = {}
54-
55-
def collection(self, id_or_name: str) -> RecordService:
56-
"""Returns the RecordService associated to the specified collection."""
57-
if id_or_name not in self.record_service:
58-
self.record_service[id_or_name] = RecordService(self, id_or_name)
59-
return self.record_service[id_or_name]
45+
self.record_service: Dict[str, RecordService] = {}
6046

6147
def _send(self, path: str, req_config: dict[str, Any]) -> httpx.Response:
6248
"""Sends an api http request returning response object."""
@@ -74,9 +60,9 @@ def _send(self, path: str, req_config: dict[str, Any]) -> httpx.Response:
7460
method = config.get("method", "GET")
7561
params = config.get("params", None)
7662
headers = config.get("headers", None)
77-
body = config.get("body", None)
63+
body: dict[str, Any] | None = config.get("body", None)
7864
# handle requests including files as multipart:
79-
data = {}
65+
data: dict[str, Any] | None = {}
8066
files = ()
8167
for k, v in (body if isinstance(body, dict) else {}).items():
8268
if isinstance(v, FileUpload):
@@ -108,6 +94,12 @@ def _send(self, path: str, req_config: dict[str, Any]) -> httpx.Response:
10894
)
10995
return response
11096

97+
def collection(self, id_or_name: str) -> RecordService:
98+
"""Returns the RecordService associated to the specified collection."""
99+
if id_or_name not in self.record_service:
100+
self.record_service[id_or_name] = RecordService(self, id_or_name)
101+
return self.record_service[id_or_name]
102+
111103
def send_raw(self, path: str, req_config: dict[str, Any]) -> bytes:
112104
"""Sends an api http request returning raw bytes response."""
113105
response = self._send(path, req_config)
@@ -123,35 +115,29 @@ def send(self, path: str, req_config: dict[str, Any]) -> Any:
123115
if response.status_code >= 400:
124116
raise ClientResponseError(
125117
f"Response error. Status code:{response.status_code}",
126-
url=response.url,
118+
url=str(response.url),
127119
status=response.status_code,
128120
data=data,
129121
)
130122
return data
131123

132-
def get_file_url(self, record: Record, filename: str, query_params: dict):
133-
parts = [
134-
"api",
135-
"files",
136-
quote(record.collection_id or record.collection_name),
137-
quote(record.id),
138-
quote(filename),
139-
]
140-
result = self.build_url("/".join(parts))
141-
if len(query_params) != 0:
142-
params: str = urlencode(query_params)
143-
result += "&" if "?" in result else "?"
144-
result += params
145-
return result
146-
147-
def get_file_token(self):
148-
res = self.send("/api/files/token", req_config={"method": "POST"})
149-
return res["token"]
150-
151124
def build_url(self, path: str) -> str:
152125
url = self.base_url
153126
if not self.base_url.endswith("/"):
154127
url += "/"
155128
if path.startswith("/"):
156129
path = path[1:]
157130
return url + path
131+
132+
# TODO: add deprecated decorator
133+
def get_file_url(
134+
self,
135+
record: Record,
136+
filename: str,
137+
query_params: dict[str, Any] | None = None,
138+
):
139+
return self.files.get_url(record, filename, query_params)
140+
141+
# TODO: add deprecated decorator
142+
def get_file_token(self) -> str:
143+
return self.files.get_token()

pocketbase/errors.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from __future__ import annotations
2+
3+
from typing import Any
4+
5+
6+
class ClientResponseError(Exception):
7+
def __init__(
8+
self,
9+
*args: Any,
10+
url: str = "",
11+
status: int = 0,
12+
data: dict[str, Any] | None = None,
13+
is_abort: bool = False,
14+
original_error: Any = None,
15+
**kwargs: Any,
16+
) -> None:
17+
super().__init__(*args)
18+
self.url = url
19+
self.status = status
20+
self.data = data or {}
21+
self.is_abort = is_abort
22+
self.original_error = original_error

pocketbase/models/admin.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
from __future__ import annotations
22

3+
from typing import Any
4+
35
from pocketbase.models.utils.base_model import BaseModel
46

57

68
class Admin(BaseModel):
79
avatar: int
810
email: str
911

10-
def load(self, data: dict) -> None:
12+
def load(self, data: dict[str, Any]) -> None:
1113
super().load(data)
1214
self.avatar = data.get("avatar", 0)
1315
self.email = data.get("email", "")

pocketbase/models/backups.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import datetime
4+
from typing import Any
45

56
from pocketbase.models.utils import BaseModel
67
from pocketbase.utils import to_datetime
@@ -11,7 +12,7 @@ class Backup(BaseModel):
1112
modified: str | datetime.datetime
1213
size: int
1314

14-
def load(self, data: dict) -> None:
15+
def load(self, data: dict[str, Any]) -> None:
1516
super().load(data)
1617
self.key = data.get("key", "")
1718
self.modified = to_datetime(data.pop("modified", ""))

pocketbase/models/collection.py

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

3+
from typing import Any
4+
35
from pocketbase.models.utils.base_model import BaseModel
46
from pocketbase.models.utils.schema_field import SchemaField
57

@@ -14,9 +16,9 @@ class Collection(BaseModel):
1416
create_rule: str | None
1517
update_rule: str | None
1618
delete_rule: str | None
17-
options: dict
19+
options: dict[str, Any]
1820

19-
def load(self, data: dict) -> None:
21+
def load(self, data: dict[str, Any]) -> None:
2022
super().load(data)
2123
self.name = data.get("name", "")
2224
self.system = data.get("system", False)

pocketbase/models/external_auth.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
from typing import Any
4+
35
from pocketbase.models.utils.base_model import BaseModel
46

57

@@ -9,7 +11,7 @@ class ExternalAuth(BaseModel):
911
provider: str
1012
provider_id: str
1113

12-
def load(self, data: dict) -> None:
14+
def load(self, data: dict[str, Any]) -> None:
1315
super().load(data)
1416
self.record_id = data.get("recordId", "")
1517
self.collection_id = data.get("collectionId", "")

pocketbase/models/file_upload.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77

88
class FileUpload:
9-
def __init__(self, *args):
10-
self.files: FileUploadTypes = args
9+
def __init__(self, *args: FileUploadTypes):
10+
self.files = args
1111

1212
def get(self, key: str):
1313
if isinstance(self.files[0], Sequence) and not isinstance(

pocketbase/models/log_request.py

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

3+
from typing import Any
4+
35
from pocketbase.models.utils.base_model import BaseModel
46

57

@@ -12,9 +14,9 @@ class LogRequest(BaseModel):
1214
user_ip: str
1315
referer: str
1416
user_agent: str
15-
meta: dict
17+
meta: dict[str, Any]
1618

17-
def load(self, data: dict) -> None:
19+
def load(self, data: dict[str, Any]) -> None:
1820
super().load(data)
1921
self.url = data.get("url", "")
2022
self.method = data.get("method", "")

pocketbase/models/record.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
from __future__ import annotations
22

3+
from typing import Any
4+
35
from pocketbase.models.utils.base_model import BaseModel
46
from pocketbase.utils import camel_to_snake
57

68

79
class Record(BaseModel):
810
collection_id: str
911
collection_name: str
10-
expand: dict
12+
expand: dict[str, Any]
1113

12-
def load(self, data: dict) -> None:
14+
def load(self, data: dict[str, Any]) -> None:
1315
super().load(data)
1416
self.expand = {}
1517
for key, value in data.items():
@@ -18,9 +20,9 @@ def load(self, data: dict) -> None:
1820
self.load_expanded()
1921

2022
@classmethod
21-
def parse_expanded(cls, data: dict):
23+
def parse_expanded(cls, data: Any):
2224
if isinstance(data, list):
23-
return [cls(a) for a in data]
25+
return [cls(a) for a in data] # type: ignore
2426
return cls(data)
2527

2628
def load_expanded(self) -> None:

0 commit comments

Comments
 (0)