Skip to content

Commit 1049655

Browse files
authored
update to pocketbase version 0.8.0-rc2 (#4)
update to pocketbase version 0.8.0-rc1 fixed flake8 errors, but there are still remaining errors: F401 ... imported but unused E501 line too long (... > 79 characters) E722 do not use bare 'except'
1 parent 9ae4712 commit 1049655

25 files changed

+541
-614
lines changed

pocketbase/client.py

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,33 @@
11
from __future__ import annotations
22

3-
from typing import Any
3+
from typing import Any, Dict
4+
from urllib.parse import quote, urlencode
45

56
import httpx
67

7-
from pocketbase.services.admins import Admins
8-
from pocketbase.services.collections import Collections
9-
from pocketbase.services.logs import Logs
10-
from pocketbase.services.realtime import Realtime
11-
from pocketbase.services.records import Records
12-
from pocketbase.services.users import Users
13-
from pocketbase.services.settings import Settings
8+
from pocketbase.utils import ClientResponseError
9+
from pocketbase.models.record import Record
10+
from pocketbase.services.admin_service import AdminService
11+
from pocketbase.services.collection_service import CollectionService
12+
from pocketbase.services.log_service import LogService
13+
from pocketbase.services.realtime_service import RealtimeService
14+
from pocketbase.services.record_service import RecordService
15+
from pocketbase.services.settings_service import SettingsService
1416
from pocketbase.stores.base_auth_store import BaseAuthStore
1517

1618

17-
class ClientResponseError(Exception):
18-
url: str = ""
19-
status: int = 0
20-
data: dict = {}
21-
is_abort: bool = False
22-
original_error: Any | None = None
23-
24-
def __init__(self, *args, **kwargs) -> None:
25-
super().__init__(*args)
26-
self.url = kwargs.get("url", "")
27-
self.status = kwargs.get("status", 0)
28-
self.data = kwargs.get("data", {})
29-
self.is_abort = kwargs.get("is_abort", False)
30-
self.original_error = kwargs.get("original_error", None)
31-
32-
3319
class Client:
3420
base_url: str
3521
lang: str
3622
auth_store: BaseAuthStore
37-
settings: Settings
38-
admins: Admins
39-
users: Users
40-
collections: Collections
41-
records: Records
42-
logs: Logs
43-
realtime: Realtime
23+
settings: SettingsService
24+
admins: AdminService
25+
records: Record
26+
collections: CollectionService
27+
records: RecordService
28+
logs: LogService
29+
realtime: RealtimeService
30+
record_service: Dict[str, RecordService]
4431

4532
def __init__(
4633
self,
@@ -52,13 +39,18 @@ def __init__(
5239
self.lang = lang
5340
self.auth_store = auth_store or BaseAuthStore() # LocalAuthStore()
5441
# services
55-
self.admins = Admins(self)
56-
self.users = Users(self)
57-
self.records = Records(self)
58-
self.collections = Collections(self)
59-
self.logs = Logs(self)
60-
self.settings = Settings(self)
61-
self.realtime = Realtime(self)
42+
self.admins = AdminService(self)
43+
self.collections = CollectionService(self)
44+
self.logs = LogService(self)
45+
self.settings = SettingsService(self)
46+
self.realtime = RealtimeService(self)
47+
self.record_service = {}
48+
49+
def collection(self, id_or_name: str) -> RecordService:
50+
"""Returns the RecordService associated to the specified collection."""
51+
if id_or_name not in self.record_service:
52+
self.record_service[id_or_name] = RecordService(self, id_or_name)
53+
return self.record_service[id_or_name]
6254

6355
def send(self, path: str, req_config: dict[str:Any]) -> Any:
6456
"""Sends an api http request."""
@@ -68,12 +60,9 @@ def send(self, path: str, req_config: dict[str:Any]) -> Any:
6860
if self.auth_store.token and (
6961
"headers" not in config or "Authorization" not in config["headers"]
7062
):
71-
auth_type = "Admin"
72-
if hasattr(self.auth_store.model, "verified"):
73-
auth_type = "User"
7463
config["headers"] = config.get("headers", {})
7564
config["headers"].update(
76-
{"Authorization": f"{auth_type} {self.auth_store.token}"}
65+
{"Authorization": self.auth_store.token}
7766
)
7867
# build url + path
7968
url = self.build_url(path)
@@ -109,6 +98,21 @@ def send(self, path: str, req_config: dict[str:Any]) -> Any:
10998
)
11099
return data
111100

101+
def get_file_url(self, record: Record, filename: str, query_params: dict):
102+
parts = [
103+
'api',
104+
'files',
105+
quote(record.collection_id or record.collection_name),
106+
quote(record.id),
107+
quote(filename),
108+
]
109+
result = self.build_url('/'.join(parts))
110+
if len(query_params) != 0:
111+
params: str = urlencode(query_params)
112+
result += '&' if '?' in result else '?'
113+
result += params
114+
return result
115+
112116
def build_url(self, path: str) -> str:
113117
url = self.base_url
114118
if not self.base_url.endswith("/"):

pocketbase/models/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@
33
from .external_auth import ExternalAuth
44
from .log_request import LogRequest
55
from .record import Record
6-
from .user import User

pocketbase/models/admin.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,8 @@
99
class Admin(BaseModel):
1010
avatar: int
1111
email: str
12-
last_reset_sent_at: str | datetime.datetime
1312

1413
def load(self, data: dict) -> None:
1514
super().load(data)
1615
self.avatar = data.get("avatar", 0)
1716
self.email = data.get("email", "")
18-
self.last_reset_sent_at = to_datetime(data.get("lastResetSentAt", ""))

pocketbase/models/collection.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,41 @@
66

77
class Collection(BaseModel):
88
name: str
9+
type: str
910
schema: list[SchemaField]
1011
system: bool
1112
list_rule: str | None
1213
view_rule: str | None
1314
create_rule: str | None
1415
update_rule: str | None
1516
delete_rule: str | None
17+
options: dict
1618

1719
def load(self, data: dict) -> None:
1820
super().load(data)
1921
self.name = data.get("name", "")
2022
self.system = data.get("system", False)
23+
self.type = data.get("type", "base")
24+
self.options = data.get("options", {})
25+
26+
# rules
2127
self.list_rule = data.get("listRule", None)
2228
self.view_rule = data.get("viewRule", None)
2329
self.create_rule = data.get("createRule", None)
2430
self.update_rule = data.get("updateRule", None)
2531
self.delete_rule = data.get("deleteRule", "")
32+
33+
# schema
2634
schema = data.get("schema", [])
2735
self.schema = []
2836
for field in schema:
2937
self.schema.append(SchemaField(**field))
38+
39+
def is_base(self):
40+
return self.type == 'base'
41+
42+
def is_auth(self):
43+
return self.type == 'auth'
44+
45+
def is_single(self):
46+
return self.type == 'single'

pocketbase/models/external_auth.py

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

55

66
class ExternalAuth(BaseModel):
7-
user_id: str
7+
record_id: str
8+
collection_id: str
89
provider: str
910
provider_id: str
1011

1112
def load(self, data: dict) -> None:
1213
super().load(data)
13-
self.user_id = data.get("userId", "")
14+
self.record_id = data.get("recordId", "")
15+
self.collection_id = data.get("collectionId", "")
1416
self.provider = data.get("provider", "")
1517
self.provider_id = data.get("providerId", "")

pocketbase/models/user.py

Lines changed: 0 additions & 29 deletions
This file was deleted.

pocketbase/models/utils/base_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ def load(self, data: dict) -> None:
3030
@property
3131
def is_new(self) -> bool:
3232
"""Returns whether the current loaded data represent a stored db record."""
33-
return not self.id or self.id == "00000000-0000-0000-0000-000000000000"
33+
return not self.id

pocketbase/services/__init__.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
from .admins import Admins, AdminAuthResponse
2-
from .collections import Collections
3-
from .logs import Logs, HourlyStats
4-
from .realtime import Realtime
5-
from .records import Records
6-
from .settings import Settings
7-
from .users import Users, UserAuthResponse, AuthMethodsList, AuthProviderInfo
1+
from .admin_service import AdminService, AdminAuthResponse
2+
from .collection_service import CollectionService
3+
from .log_service import LogService, HourlyStats
4+
from .realtime_service import RealtimeService
5+
from .record_service import RecordService
6+
from .settings_service import SettingsService
Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,39 @@ def __init__(self, token: str, admin: Admin, **kwargs) -> None:
1616
setattr(self, key, value)
1717

1818

19-
class Admins(CrudService):
19+
class AdminService(CrudService):
2020
def decode(self, data: dict) -> BaseModel:
2121
return Admin(data)
2222

2323
def base_crud_path(self) -> str:
2424
return "/api/admins"
2525

26+
def update(self, id: str, body_params: dict, query_params: dict) -> BaseModel:
27+
"""
28+
If the current `client.auth_store.model` matches with the updated id,
29+
then on success the `client.auth_store.model` will be updated with the result.
30+
"""
31+
item = super(AdminService).update(id, body_params)
32+
try:
33+
if self.client.auth_store.model.collection_id is not None and item.id == self.client.auth_store.model.id:
34+
self.client.auth_store.save(self.client.auth_store.token, item)
35+
except:
36+
pass
37+
return item
38+
39+
def delete(self, id: str, body_params: dict, query_params: dict) -> BaseModel:
40+
"""
41+
If the current `client.auth_store.model` matches with the deleted id,
42+
then on success the `client.auth_store` will be cleared.
43+
"""
44+
item = super(AdminService).delete(id, body_params)
45+
try:
46+
if self.client.auth_store.model.collection_id is not None and item.id == self.client.auth_store.model.id:
47+
self.client.auth_store.save(self.client.auth_store.token, item)
48+
except:
49+
pass
50+
return item
51+
2652
def auth_response(self, response_data: dict) -> AdminAuthResponse:
2753
"""Prepare successful authorize response."""
2854
admin = self.decode(response_data.pop("admin", {}))
@@ -31,18 +57,18 @@ def auth_response(self, response_data: dict) -> AdminAuthResponse:
3157
self.client.auth_store.save(token, admin)
3258
return AdminAuthResponse(token=token, admin=admin, **response_data)
3359

34-
def auth_via_email(
60+
def auth_with_password(
3561
self, email: str, password: str, body_params: dict = {}, query_params: dict = {}
3662
) -> AdminAuthResponse:
3763
"""
38-
Authenticate an admin account by its email and password
64+
Authenticate an admin account with its email and password
3965
and returns a new admin token and data.
4066
4167
On success this method automatically updates the client's AuthStore data.
4268
"""
43-
body_params.update({"email": email, "password": password})
69+
body_params.update({"identity": email, "password": password})
4470
response_data = self.client.send(
45-
self.base_crud_path() + "/auth-via-email",
71+
self.base_crud_path() + "/auth-with-password",
4672
{
4773
"method": "POST",
4874
"params": query_params,
@@ -52,7 +78,7 @@ def auth_via_email(
5278
)
5379
return self.auth_response(response_data)
5480

55-
def refresh(
81+
def authRefresh(
5682
self, body_params: dict = {}, query_params: dict = {}
5783
) -> AdminAuthResponse:
5884
"""
@@ -63,7 +89,7 @@ def refresh(
6389
"""
6490
return self.auth_response(
6591
self.client.send(
66-
self.base_crud_path() + "/refresh",
92+
self.base_crud_path() + "/auth-refresh",
6793
{"method": "POST", "params": query_params, "body": body_params},
6894
)
6995
)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pocketbase.models.collection import Collection
66

77

8-
class Collections(CrudService):
8+
class CollectionService(CrudService):
99
def decode(self, data: dict) -> BaseModel:
1010
return Collection(data)
1111

0 commit comments

Comments
 (0)