From bea82b6ecbba4e4682b7c6aa10dbc35992368b02 Mon Sep 17 00:00:00 2001 From: Vithor Jaeger Date: Wed, 4 Sep 2024 09:54:42 -0400 Subject: [PATCH 1/3] fix some typing issues, format and dependencies versions --- pocketbase/client.py | 13 ++-- pocketbase/models/__init__.py | 12 +++- pocketbase/models/file_upload.py | 7 ++- pocketbase/models/utils/base_model.py | 2 +- pocketbase/services/__init__.py | 4 +- pocketbase/services/admin_service.py | 18 ++++-- pocketbase/services/backups_service.py | 25 +++++--- pocketbase/services/collection_service.py | 9 ++- pocketbase/services/log_service.py | 6 +- pocketbase/services/realtime_service.py | 12 ++-- pocketbase/services/record_service.py | 57 +++++++++++------ .../services/utils/base_crud_service.py | 37 ++++++++--- pocketbase/services/utils/crud_service.py | 19 ++++-- pocketbase/services/utils/sse.py | 6 +- pocketbase/stores/base_auth_store.py | 6 +- pocketbase/stores/local_auth_store.py | 18 +++--- pocketbase/utils.py | 4 +- poetry.lock | 61 ++++++++++--------- pyproject.toml | 17 +++--- tests/integration/conftest.py | 3 +- tests/integration/test_admin.py | 22 ++++--- tests/integration/test_backups.py | 33 +++++++--- tests/integration/test_collection.py | 11 ++-- tests/integration/test_files.py | 8 ++- tests/integration/test_local_auth_store.py | 10 +-- tests/integration/test_record.py | 10 ++- tests/integration/test_record_auth.py | 29 ++++++--- tests/integration/test_record_event.py | 8 +-- tests/integration/test_settings.py | 16 +++-- tests/test_client.py | 3 +- 30 files changed, 314 insertions(+), 172 deletions(-) diff --git a/pocketbase/client.py b/pocketbase/client.py index 3f3dd32..1803ee6 100644 --- a/pocketbase/client.py +++ b/pocketbase/client.py @@ -24,7 +24,6 @@ class Client: auth_store: BaseAuthStore settings: SettingsService admins: AdminService - records: Record collections: CollectionService records: RecordService logs: LogService @@ -59,13 +58,13 @@ def collection(self, id_or_name: str) -> RecordService: self.record_service[id_or_name] = RecordService(self, id_or_name) return self.record_service[id_or_name] - def _send(self, path: str, req_config: dict[str:Any]) -> httpx.Response: + def _send(self, path: str, req_config: dict[str, Any]) -> httpx.Response: """Sends an api http request returning response object.""" - config = {"method": "GET"} + config: dict[str, Any] = {"method": "GET"} config.update(req_config) # check if Authorization header can be added if self.auth_store.token and ( - "headers" not in config or "Authorization" not in config["headers"] + "headers" not in config or "Authorization" not in config["headers"] ): config["headers"] = config.get("headers", {}) config["headers"].update({"Authorization": self.auth_store.token}) @@ -99,7 +98,7 @@ def _send(self, path: str, req_config: dict[str:Any]) -> httpx.Response: headers=headers, json=body, data=data, - files=files, + files=files, # type: ignore timeout=self.timeout, ) except Exception as e: @@ -109,12 +108,12 @@ def _send(self, path: str, req_config: dict[str:Any]) -> httpx.Response: ) return response - def send_raw(self, path: str, req_config: dict[str:Any]) -> bytes: + def send_raw(self, path: str, req_config: dict[str, Any]) -> bytes: """Sends an api http request returning raw bytes response.""" response = self._send(path, req_config) return response.content - def send(self, path: str, req_config: dict[str:Any]) -> Any: + def send(self, path: str, req_config: dict[str, Any]) -> Any: """Sends an api http request.""" response = self._send(path, req_config) try: diff --git a/pocketbase/models/__init__.py b/pocketbase/models/__init__.py index 45be273..4563c9b 100644 --- a/pocketbase/models/__init__.py +++ b/pocketbase/models/__init__.py @@ -2,8 +2,16 @@ from .backups import Backup from .collection import Collection from .external_auth import ExternalAuth +from .file_upload import FileUpload from .log_request import LogRequest from .record import Record -from .file_upload import FileUpload -__all__ = ["Admin", "Backup", "Collection", "ExternalAuth", "LogRequest", "Record", "FileUpload"] +__all__ = [ + "Admin", + "Backup", + "Collection", + "ExternalAuth", + "LogRequest", + "Record", + "FileUpload", +] diff --git a/pocketbase/models/file_upload.py b/pocketbase/models/file_upload.py index 60ab29e..7c94013 100644 --- a/pocketbase/models/file_upload.py +++ b/pocketbase/models/file_upload.py @@ -1,6 +1,7 @@ -from httpx._types import FileTypes from typing import Sequence, Union +from httpx._types import FileTypes + FileUploadTypes = Union[FileTypes, Sequence[FileTypes]] @@ -9,6 +10,8 @@ def __init__(self, *args): self.files: FileUploadTypes = args def get(self, key: str): - if isinstance(self.files[0], Sequence) and not isinstance(self.files[0], str): + if isinstance(self.files[0], Sequence) and not isinstance( + self.files[0], str + ): return tuple((key, i) for i in self.files) return ((key, self.files),) diff --git a/pocketbase/models/utils/base_model.py b/pocketbase/models/utils/base_model.py index ba8505e..cc5c0e4 100644 --- a/pocketbase/models/utils/base_model.py +++ b/pocketbase/models/utils/base_model.py @@ -1,7 +1,7 @@ from __future__ import annotations -from abc import ABC import datetime +from abc import ABC from pocketbase.utils import to_datetime diff --git a/pocketbase/services/__init__.py b/pocketbase/services/__init__.py index ac9f852..55cda1e 100644 --- a/pocketbase/services/__init__.py +++ b/pocketbase/services/__init__.py @@ -1,6 +1,6 @@ -from .admin_service import AdminService, AdminAuthResponse +from .admin_service import AdminAuthResponse, AdminService from .collection_service import CollectionService -from .log_service import LogService, HourlyStats +from .log_service import HourlyStats, LogService from .realtime_service import RealtimeService from .record_service import RecordService from .settings_service import SettingsService diff --git a/pocketbase/services/admin_service.py b/pocketbase/services/admin_service.py index 0ad6fe7..d9ea884 100644 --- a/pocketbase/services/admin_service.py +++ b/pocketbase/services/admin_service.py @@ -1,8 +1,8 @@ from __future__ import annotations +from pocketbase.models.admin import Admin from pocketbase.models.utils.base_model import BaseModel from pocketbase.services.utils.crud_service import CrudService -from pocketbase.models.admin import Admin from pocketbase.utils import validate_token @@ -17,7 +17,7 @@ def __init__(self, token: str, admin: Admin, **kwargs) -> None: setattr(self, key, value) @property - def is_valid(self)->bool: + def is_valid(self) -> bool: return validate_token(self.token) @@ -33,14 +33,16 @@ def update(self, id: str, body_params: dict, query_params={}) -> BaseModel: If the current `client.auth_store.model` matches with the updated id, then on success the `client.auth_store.model` will be updated with the result. """ - item = super().update(id, body_params=body_params, query_params=query_params) + item = super().update( + id, body_params=body_params, query_params=query_params + ) try: if ( self.client.auth_store.model.collection_id is not None and item.id == self.client.auth_store.model.id ): self.client.auth_store.save(self.client.auth_store.token, item) - except: + except Exception: pass return item @@ -56,7 +58,7 @@ def delete(self, id: str, query_params={}) -> BaseModel: and item.id == self.client.auth_store.model.id ): self.client.auth_store.save(self.client.auth_store.token, item) - except: + except Exception: pass return item @@ -69,7 +71,11 @@ def auth_response(self, response_data: dict) -> AdminAuthResponse: return AdminAuthResponse(token=token, admin=admin, **response_data) def auth_with_password( - self, email: str, password: str, body_params: dict = {}, query_params: dict = {} + self, + email: str, + password: str, + body_params: dict = {}, + query_params: dict = {}, ) -> AdminAuthResponse: """ Authenticate an admin account with its email and password diff --git a/pocketbase/services/backups_service.py b/pocketbase/services/backups_service.py index 1633d29..444b9b6 100644 --- a/pocketbase/services/backups_service.py +++ b/pocketbase/services/backups_service.py @@ -19,20 +19,31 @@ def create(self, name: str): ) def get_full_list(self, query_params: dict = {}) -> list[Backup]: - response_data = self.client.send(self.base_path(), {"method": "GET", "params": query_params}) + response_data = self.client.send( + self.base_path(), {"method": "GET", "params": query_params} + ) return [self.decode(item) for item in response_data] def download(self, key: str, file_token: str = None) -> bytes: if file_token is None: file_token = self.client.get_file_token() - return self.client.send_raw("%s/%s" % (self.base_path(), key), - {"method": "GET", "params": {"token": file_token}}) + return self.client.send_raw( + "%s/%s" % (self.base_path(), key), + {"method": "GET", "params": {"token": file_token}}, + ) def delete(self, key: str): - self.client.send("%s/%s" % (self.base_path(), key), {"method": "DELETE"}) + self.client.send( + "%s/%s" % (self.base_path(), key), {"method": "DELETE"} + ) - def restore(self, key: str): - self.client.send("%s/%s/restore" % (self.base_path(), key), {"method": "POST"}) + def restore(self, key: str): + self.client.send( + "%s/%s/restore" % (self.base_path(), key), {"method": "POST"} + ) def upload(self, file_upload: FileUpload): - self.client.send(self.base_path() + "/upload", {"method": "POST", "body": {"file": file_upload}}) \ No newline at end of file + self.client.send( + self.base_path() + "/upload", + {"method": "POST", "body": {"file": file_upload}}, + ) diff --git a/pocketbase/services/collection_service.py b/pocketbase/services/collection_service.py index 9188a4e..7a7e074 100644 --- a/pocketbase/services/collection_service.py +++ b/pocketbase/services/collection_service.py @@ -1,8 +1,8 @@ from __future__ import annotations -from pocketbase.services.utils.crud_service import CrudService -from pocketbase.models.utils.base_model import BaseModel from pocketbase.models.collection import Collection +from pocketbase.models.utils.base_model import BaseModel +from pocketbase.services.utils.crud_service import CrudService class CollectionService(CrudService): @@ -30,7 +30,10 @@ def import_collections( { "method": "PUT", "params": query_params, - "body": {"collections": collections, "deleteMissing": delete_missing}, + "body": { + "collections": collections, + "deleteMissing": delete_missing, + }, }, ) return True diff --git a/pocketbase/services/log_service.py b/pocketbase/services/log_service.py index 27746ad..02eeacc 100644 --- a/pocketbase/services/log_service.py +++ b/pocketbase/services/log_service.py @@ -1,13 +1,13 @@ from __future__ import annotations +import datetime from dataclasses import dataclass from typing import Union from urllib.parse import quote -import datetime -from pocketbase.services.utils.base_service import BaseService -from pocketbase.models.utils.list_result import ListResult from pocketbase.models.log_request import LogRequest +from pocketbase.models.utils.list_result import ListResult +from pocketbase.services.utils.base_service import BaseService from pocketbase.utils import to_datetime diff --git a/pocketbase/services/realtime_service.py b/pocketbase/services/realtime_service.py index f67295b..ab4bc4f 100644 --- a/pocketbase/services/realtime_service.py +++ b/pocketbase/services/realtime_service.py @@ -1,12 +1,12 @@ from __future__ import annotations -from typing import Callable, List import dataclasses import json +from typing import Callable, List +from pocketbase.models.record import Record from pocketbase.services.utils.base_service import BaseService from pocketbase.services.utils.sse import Event, SSEClient -from pocketbase.models.record import Record @dataclasses.dataclass @@ -142,13 +142,17 @@ def _connect_handler(self, event: Event) -> None: def _connect(self) -> None: self._disconnect() self.event_source = SSEClient(self.client.build_url("/api/realtime")) - self.event_source.add_event_listener("PB_CONNECT", self._connect_handler) + self.event_source.add_event_listener( + "PB_CONNECT", self._connect_handler + ) def _disconnect(self) -> None: self._remove_subscription_listeners() self.client_id = "" if not self.event_source: return - self.event_source.remove_event_listener("PB_CONNECT", self._connect_handler) + self.event_source.remove_event_listener( + "PB_CONNECT", self._connect_handler + ) self.event_source.close() self.event_source = None diff --git a/pocketbase/services/record_service.py b/pocketbase/services/record_service.py index c2a92b1..353951e 100644 --- a/pocketbase/services/record_service.py +++ b/pocketbase/services/record_service.py @@ -1,12 +1,11 @@ from __future__ import annotations -from dataclasses import dataclass -from typing import List +from dataclasses import dataclass from urllib.parse import quote, urlencode -from pocketbase.services.realtime_service import Callable, MessageData -from pocketbase.models.utils.base_model import BaseModel from pocketbase.models.record import Record +from pocketbase.models.utils.base_model import BaseModel +from pocketbase.services.realtime_service import Callable, MessageData from pocketbase.services.utils.crud_service import CrudService from pocketbase.utils import camel_to_snake, validate_token @@ -20,8 +19,9 @@ def __init__(self, token: str, record: Record, **kwargs) -> None: self.record = record for key, value in kwargs.items(): setattr(self, key, value) + @property - def is_valid(self)->bool: + def is_valid(self) -> bool: return validate_token(self.token) @@ -73,40 +73,48 @@ def get_file_url( def subscribe(self, callback: Callable[[MessageData], None]): """Subscribe to realtime changes of any record from the collection.""" - return self.client.realtime.subscribe(self.collection_id_or_name, callback) + return self.client.realtime.subscribe( + self.collection_id_or_name, callback + ) - def subscribeOne(self, record_id: str, callback: Callable[[MessageData], None]): + def subscribeOne( + self, record_id: str, callback: Callable[[MessageData], None] + ): """Subscribe to the realtime changes of a single record in the collection.""" return self.client.realtime.subscribe( self.collection_id_or_name + "/" + record_id, callback ) - def unsubscribe(self, *record_ids: List[str]): + def unsubscribe(self, *record_ids: str): """Unsubscribe to the realtime changes of a single record in the collection.""" if record_ids and len(record_ids) > 0: subs = [] for id in record_ids: subs.append(self.collection_id_or_name + "/" + id) return self.client.realtime.unsubscribe(subs) - return self.client.realtime.unsubscribe_by_prefix(self.collection_id_or_name) + return self.client.realtime.unsubscribe_by_prefix( + self.collection_id_or_name + ) def update(self, id: str, body_params: dict = {}, query_params: dict = {}): """ If the current `client.auth_store.model` matches with the updated id, then on success the `client.auth_store.model` will be updated with the result. """ - item = super().update(id, body_params=body_params, query_params=query_params) + item = super().update( + id, body_params=body_params, query_params=query_params + ) try: if ( self.client.auth_store.model.collection_id is not None and item.id == self.client.auth_store.model.id ): self.client.auth_store.save(self.client.auth_store.token, item) - except: + except Exception: pass return item - def delete(self, id: str, query_params: dict = {}): + def delete(self, id: str, query_params: dict = {}) -> bool: """ If the current `client.auth_store.model` matches with the deleted id, then on success the `client.auth_store` will be cleared. @@ -119,7 +127,7 @@ def delete(self, id: str, query_params: dict = {}): and id == self.client.auth_store.model.id ): self.client.auth_store.clear() - except: + except Exception: pass return success @@ -129,9 +137,11 @@ def auth_response(self, response_data: dict) -> RecordAuthResponse: token = response_data.pop("token", "") if token and record: self.client.auth_store.save(token, record) - return RecordAuthResponse(token=token, record=record, **response_data) + return RecordAuthResponse(token=token, record=record, **response_data) # type: ignore - def list_auth_methods(self, query_params: str = {}): + def list_auth_methods(self, query_params: dict | None) -> AuthMethodsList: + if query_params is None: + query_params = {} """Returns all available collection auth methods.""" response_data = self.client.send( self.base_collection_path() + "/auth-methods", @@ -142,7 +152,8 @@ def list_auth_methods(self, query_params: str = {}): def apply_pythonic_keys(ap): pythonic_keys_ap = { - camel_to_snake(key).replace("@", ""): value for key, value in ap.items() + camel_to_snake(key).replace("@", ""): value + for key, value in ap.items() } return pythonic_keys_ap @@ -152,7 +163,9 @@ def apply_pythonic_keys(ap): apply_pythonic_keys, response_data.get("authProviders", []) ) ] - return AuthMethodsList(username_password, email_password, auth_providers) + return AuthMethodsList( + username_password, email_password, auth_providers + ) def auth_with_password( self, @@ -169,7 +182,9 @@ def auth_with_password( - the authentication token - the authenticated record model """ - body_params.update({"identity": username_or_email, "password": password}) + body_params.update( + {"identity": username_or_email, "password": password} + ) response_data = self.client.send( self.base_collection_path() + "/auth-with-password", { @@ -250,7 +265,11 @@ def requestEmailChange( return True def confirmEmailChange( - self, token: str, password: str, body_params: dict = {}, query_params: dict = {} + self, + token: str, + password: str, + body_params: dict = {}, + query_params: dict = {}, ) -> bool: """ Confirms Email Change by with the confirmation token and confirm with users password diff --git a/pocketbase/services/utils/base_crud_service.py b/pocketbase/services/utils/base_crud_service.py index a04e7e5..31509c0 100644 --- a/pocketbase/services/utils/base_crud_service.py +++ b/pocketbase/services/utils/base_crud_service.py @@ -1,15 +1,16 @@ from __future__ import annotations -from abc import ABC +from abc import ABC, abstractmethod from urllib.parse import quote -from pocketbase.utils import ClientResponseError from pocketbase.models.utils.base_model import BaseModel from pocketbase.models.utils.list_result import ListResult from pocketbase.services.utils.base_service import BaseService +from pocketbase.utils import ClientResponseError class BaseCrudService(BaseService, ABC): + @abstractmethod def decode(self, data: dict) -> BaseModel: """Response data decoder""" @@ -30,7 +31,11 @@ def request(result: list[BaseModel], page: int) -> list: return request(result, 1) def _get_list( - self, base_path: str, page: int = 1, per_page: int = 30, query_params: dict = {} + self, + base_path: str, + page: int = 1, + per_page: int = 30, + query_params: dict = {}, ) -> ListResult: query_params.update({"page": page, "perPage": per_page}) response_data = self.client.send( @@ -49,14 +54,19 @@ def _get_list( items, ) - def _get_one(self, base_path: str, id: str, query_params: dict = {}) -> BaseModel: + def _get_one( + self, base_path: str, id: str, query_params: dict = {} + ) -> BaseModel: return self.decode( self.client.send( - f"{base_path}/{quote(id)}", {"method": "GET", "params": query_params} + f"{base_path}/{quote(id)}", + {"method": "GET", "params": query_params}, ) ) - def _get_first_list_item(self, base_path: str, filter: str, query_params={}): + def _get_first_list_item( + self, base_path: str, filter: str, query_params={} + ): query_params.update( { "filter": filter, @@ -81,17 +91,26 @@ def _create( ) def _update( - self, base_path: str, id: str, body_params: dict = {}, query_params: dict = {} + self, + base_path: str, + id: str, + body_params: dict = {}, + query_params: dict = {}, ) -> BaseModel: return self.decode( self.client.send( f"{base_path}/{quote(id)}", - {"method": "PATCH", "params": query_params, "body": body_params}, + { + "method": "PATCH", + "params": query_params, + "body": body_params, + }, ) ) def _delete(self, base_path: str, id: str, query_params: dict = {}) -> bool: self.client.send( - f"{base_path}/{quote(id)}", {"method": "DELETE", "params": query_params} + f"{base_path}/{quote(id)}", + {"method": "DELETE", "params": query_params}, ) return True diff --git a/pocketbase/services/utils/crud_service.py b/pocketbase/services/utils/crud_service.py index 3236084..3738483 100644 --- a/pocketbase/services/utils/crud_service.py +++ b/pocketbase/services/utils/crud_service.py @@ -1,6 +1,6 @@ from __future__ import annotations -from abc import ABC +from abc import ABC, abstractmethod from pocketbase.models.utils.base_model import BaseModel from pocketbase.models.utils.list_result import ListResult @@ -8,6 +8,7 @@ class CrudService(BaseCrudService, ABC): + @abstractmethod def base_crud_path(self) -> str: """Base path for the crud actions (without trailing slash, eg. '/admins').""" @@ -19,7 +20,9 @@ def get_full_list( def get_list( self, page: int = 1, per_page: int = 30, query_params: dict = {} ) -> ListResult: - return self._get_list(self.base_crud_path(), page, per_page, query_params) + return self._get_list( + self.base_crud_path(), page, per_page, query_params + ) def get_first_list_item(self, filter: str, query_params={}): """ @@ -31,7 +34,9 @@ def get_first_list_item(self, filter: str, query_params={}): For consistency with `getOne`, this method will throw a 404 ClientResponseError if no item was found. """ - return self._get_first_list_item(self.base_crud_path(), filter, query_params) + return self._get_first_list_item( + self.base_crud_path(), filter, query_params + ) def get_one(self, id: str, query_params: dict = {}) -> BaseModel: """ @@ -39,13 +44,17 @@ def get_one(self, id: str, query_params: dict = {}) -> BaseModel: """ return self._get_one(self.base_crud_path(), id, query_params) - def create(self, body_params: dict = {}, query_params: dict = {}) -> BaseModel: + def create( + self, body_params: dict = {}, query_params: dict = {} + ) -> BaseModel: return self._create(self.base_crud_path(), body_params, query_params) def update( self, id: str, body_params: dict = {}, query_params: dict = {} ) -> BaseModel: - return self._update(self.base_crud_path(), id, body_params, query_params) + return self._update( + self.base_crud_path(), id, body_params, query_params + ) def delete(self, id: str, query_params: dict = {}) -> bool: return self._delete(self.base_crud_path(), id, query_params) diff --git a/pocketbase/services/utils/sse.py b/pocketbase/services/utils/sse.py index 50fb8e8..8d57af7 100644 --- a/pocketbase/services/utils/sse.py +++ b/pocketbase/services/utils/sse.py @@ -1,8 +1,8 @@ from __future__ import annotations -from typing import Callable import dataclasses import threading +from typing import Callable import httpx @@ -125,7 +125,9 @@ def __init__( self._loop_thread.daemon = True self._loop_thread.start() - def add_event_listener(self, event: str, callback: Callable[[Event], None]) -> None: + def add_event_listener( + self, event: str, callback: Callable[[Event], None] + ) -> None: self._listeners[event] = callback self._loop_thread.listeners = self._listeners diff --git a/pocketbase/stores/base_auth_store.py b/pocketbase/stores/base_auth_store.py index 920e5c2..93cfc22 100644 --- a/pocketbase/stores/base_auth_store.py +++ b/pocketbase/stores/base_auth_store.py @@ -12,7 +12,7 @@ class BaseAuthStore(ABC): PocketBase AuthStore implementations. """ - base_token: str + base_token: str | None base_model: Record | Admin | None def __init__( @@ -32,7 +32,9 @@ def model(self) -> Record | Admin | None: """Retrieves the stored model data (if any).""" return self.base_model - def save(self, token: str = "", model: Record | Admin | None = None) -> None: + def save( + self, token: str = "", model: Record | Admin | None = None + ) -> None: """Saves the provided new token and model data in the auth store.""" self.base_token = token if token else "" diff --git a/pocketbase/stores/local_auth_store.py b/pocketbase/stores/local_auth_store.py index 0e68ef1..c834c67 100644 --- a/pocketbase/stores/local_auth_store.py +++ b/pocketbase/stores/local_auth_store.py @@ -1,12 +1,12 @@ from __future__ import annotations -from typing import Any -import pickle import os +import pickle +from typing import Any -from pocketbase.stores.base_auth_store import BaseAuthStore -from pocketbase.models.record import Record from pocketbase.models.admin import Admin +from pocketbase.models.record import Record +from pocketbase.stores.base_auth_store import BaseAuthStore class LocalAuthStore(BaseAuthStore): @@ -26,7 +26,7 @@ def __init__( self.complete_filepath = os.path.join(filepath, filename) @property - def token(self) -> str: + def token(self) -> str | None: data = self._storage_get(self.complete_filepath) if not data or "token" not in data: return None @@ -39,8 +39,12 @@ def model(self) -> Record | Admin | None: return None return data["model"] - def save(self, token: str = "", model: Record | Admin | None = None) -> None: - self._storage_set(self.complete_filepath, {"token": token, "model": model}) + def save( + self, token: str = "", model: Record | Admin | None = None + ) -> None: + self._storage_set( + self.complete_filepath, {"token": token, "model": model} + ) super().save(token, model) def clear(self) -> None: diff --git a/pocketbase/utils.py b/pocketbase/utils.py index 5e8e427..28c2ea9 100644 --- a/pocketbase/utils.py +++ b/pocketbase/utils.py @@ -33,7 +33,9 @@ def normalize_base64(encoded_str): def validate_token(token: str) -> bool: if len(token.split(".")) != 3: return False - decoded_bytes = base64.urlsafe_b64decode(normalize_base64(token.split(".")[1])) + decoded_bytes = base64.urlsafe_b64decode( + normalize_base64(token.split(".")[1]) + ) decoded_str = decoded_bytes.decode("utf-8") data = json.loads(decoded_str) exp = data["exp"] diff --git a/poetry.lock b/poetry.lock index a5e09ff..0023bb4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "anyio" @@ -24,13 +24,13 @@ trio = ["trio (<0.22)"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] @@ -46,13 +46,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.2.0" +version = "1.2.2" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] [package.extras] @@ -135,13 +135,13 @@ socks = ["socksio (==1.*)"] [[package]] name = "idna" -version = "3.7" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] @@ -279,28 +279,29 @@ testing = ["pytest-asyncio (==0.20.*)", "pytest-cov (==4.*)"] [[package]] name = "ruff" -version = "0.3.5" +version = "0.6.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.3.5-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:aef5bd3b89e657007e1be6b16553c8813b221ff6d92c7526b7e0227450981eac"}, - {file = "ruff-0.3.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:89b1e92b3bd9fca249153a97d23f29bed3992cff414b222fcd361d763fc53f12"}, - {file = "ruff-0.3.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e55771559c89272c3ebab23326dc23e7f813e492052391fe7950c1a5a139d89"}, - {file = "ruff-0.3.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dabc62195bf54b8a7876add6e789caae0268f34582333cda340497c886111c39"}, - {file = "ruff-0.3.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a05f3793ba25f194f395578579c546ca5d83e0195f992edc32e5907d142bfa3"}, - {file = "ruff-0.3.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:dfd3504e881082959b4160ab02f7a205f0fadc0a9619cc481982b6837b2fd4c0"}, - {file = "ruff-0.3.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87258e0d4b04046cf1d6cc1c56fadbf7a880cc3de1f7294938e923234cf9e498"}, - {file = "ruff-0.3.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:712e71283fc7d9f95047ed5f793bc019b0b0a29849b14664a60fd66c23b96da1"}, - {file = "ruff-0.3.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a532a90b4a18d3f722c124c513ffb5e5eaff0cc4f6d3aa4bda38e691b8600c9f"}, - {file = "ruff-0.3.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:122de171a147c76ada00f76df533b54676f6e321e61bd8656ae54be326c10296"}, - {file = "ruff-0.3.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d80a6b18a6c3b6ed25b71b05eba183f37d9bc8b16ace9e3d700997f00b74660b"}, - {file = "ruff-0.3.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a7b6e63194c68bca8e71f81de30cfa6f58ff70393cf45aab4c20f158227d5936"}, - {file = "ruff-0.3.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a759d33a20c72f2dfa54dae6e85e1225b8e302e8ac655773aff22e542a300985"}, - {file = "ruff-0.3.5-py3-none-win32.whl", hash = "sha256:9d8605aa990045517c911726d21293ef4baa64f87265896e491a05461cae078d"}, - {file = "ruff-0.3.5-py3-none-win_amd64.whl", hash = "sha256:dc56bb16a63c1303bd47563c60482a1512721053d93231cf7e9e1c6954395a0e"}, - {file = "ruff-0.3.5-py3-none-win_arm64.whl", hash = "sha256:faeeae9905446b975dcf6d4499dc93439b131f1443ee264055c5716dd947af55"}, - {file = "ruff-0.3.5.tar.gz", hash = "sha256:a067daaeb1dc2baf9b82a32dae67d154d95212080c80435eb052d95da647763d"}, + {file = "ruff-0.6.3-py3-none-linux_armv6l.whl", hash = "sha256:97f58fda4e309382ad30ede7f30e2791d70dd29ea17f41970119f55bdb7a45c3"}, + {file = "ruff-0.6.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b061e49b5cf3a297b4d1c27ac5587954ccb4ff601160d3d6b2f70b1622194dc"}, + {file = "ruff-0.6.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:34e2824a13bb8c668c71c1760a6ac7d795ccbd8d38ff4a0d8471fdb15de910b1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bddfbb8d63c460f4b4128b6a506e7052bad4d6f3ff607ebbb41b0aa19c2770d1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ced3eeb44df75353e08ab3b6a9e113b5f3f996bea48d4f7c027bc528ba87b672"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47021dff5445d549be954eb275156dfd7c37222acc1e8014311badcb9b4ec8c1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d7bd20dc07cebd68cc8bc7b3f5ada6d637f42d947c85264f94b0d1cd9d87384"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:500f166d03fc6d0e61c8e40a3ff853fa8a43d938f5d14c183c612df1b0d6c58a"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42844ff678f9b976366b262fa2d1d1a3fe76f6e145bd92c84e27d172e3c34500"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70452a10eb2d66549de8e75f89ae82462159855e983ddff91bc0bce6511d0470"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65a533235ed55f767d1fc62193a21cbf9e3329cf26d427b800fdeacfb77d296f"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2e2c23cef30dc3cbe9cc5d04f2899e7f5e478c40d2e0a633513ad081f7361b5"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8a136aa7d228975a6aee3dd8bea9b28e2b43e9444aa678fb62aeb1956ff2351"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f92fe93bc72e262b7b3f2bba9879897e2d58a989b4714ba6a5a7273e842ad2f8"}, + {file = "ruff-0.6.3-py3-none-win32.whl", hash = "sha256:7a62d3b5b0d7f9143d94893f8ba43aa5a5c51a0ffc4a401aa97a81ed76930521"}, + {file = "ruff-0.6.3-py3-none-win_amd64.whl", hash = "sha256:746af39356fee2b89aada06c7376e1aa274a23493d7016059c3a72e3b296befb"}, + {file = "ruff-0.6.3-py3-none-win_arm64.whl", hash = "sha256:14a9528a8b70ccc7a847637c29e56fd1f9183a9db743bbc5b8e0c4ad60592a82"}, + {file = "ruff-0.6.3.tar.gz", hash = "sha256:183b99e9edd1ef63be34a3b51fee0a9f4ab95add123dbf89a71f7b1f0c991983"}, ] [[package]] @@ -354,4 +355,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "1bde87bf555716b2d9f84c683885812caf4c2151ea4459fc87a7217445424202" +content-hash = "4779b76e64c6b8a7a25bf25e719243c8bf887af6208e11f41f85c9a66e21f3bd" diff --git a/pyproject.toml b/pyproject.toml index 7ec032f..22eb421 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,10 @@ name = "pocketbase" description = "PocketBase SDK for python." requires-python = ">=3.7" license = "MIT" -authors = [{ name = "Vithor Jaeger", email = "vaphes@gmail.com" }, { name = "Max Amling", email = "max-amling@web.de" }] +authors = [ + { name = "Vithor Jaeger", email = "vaphes@gmail.com" }, + { name = "Max Amling", email = "max-amling@web.de" }, +] classifiers = [ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", @@ -26,7 +29,7 @@ dynamic = ["readme", "version"] [tool.poetry] name = "pocketbase" -version = "0.12.1" +version = "0.13.0" description = "PocketBase SDK for python." authors = ["Vithor Jaeger "] readme = "README.md" @@ -39,13 +42,13 @@ keywords = ["pocketbase", "sdk"] [tool.poetry.dependencies] python = "^3.7" -httpx = "^0.24.1" +httpx = "^0" [tool.poetry.group.dev.dependencies] -flake8 = "^5.0.4" -pytest = "^7.1.3" -pytest-httpx = "^0.22.0" -ruff = "^0.3.5" +flake8 = "^5.0" +pytest = "^7.1" +pytest-httpx = "^0" +ruff = "^0" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 8f1d484..1a5c228 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -1,8 +1,7 @@ -import logging +import pytest from pocketbase import PocketBase from pocketbase.utils import ClientResponseError -import pytest class State: diff --git a/tests/integration/test_admin.py b/tests/integration/test_admin.py index a9d34c9..ce02ee5 100644 --- a/tests/integration/test_admin.py +++ b/tests/integration/test_admin.py @@ -1,10 +1,12 @@ +from os import environ, path +from time import sleep +from uuid import uuid4 + +import pytest + from pocketbase import PocketBase from pocketbase.models.admin import Admin from pocketbase.utils import ClientResponseError -from uuid import uuid4 -import pytest -from os import environ, path -from time import sleep class TestAdminService: @@ -23,10 +25,12 @@ def test_create_admin(self, client: PocketBase, state): } ) # should stay logged in as previous admin + assert client.auth_store.model is not None assert client.auth_store.model.id != state.admin.id def test_login_as_created_admin(self, client: PocketBase, state): client.admins.auth_with_password(state.email, state.password) + assert client.auth_store.model is not None assert client.auth_store.model.id == state.admin.id def test_update_admin(self, client: PocketBase, state): @@ -48,14 +52,18 @@ def test_update_admin(self, client: PocketBase, state): def test_admin_password_reset(self, client: PocketBase, state): assert client.admins.requestPasswordReset(state.new_email) sleep(0.1) - mail = environ.get("TMP_EMAIL_DIR") + f"/{state.new_email}" + mail = environ.get("TMP_EMAIL_DIR", "") + f"/{state.new_email}" assert path.exists(mail) for line in open(mail).readlines(): if "/confirm-password-reset/" in line: - token = line.split("/confirm-password-reset/", 1)[1].split('"')[0] + token = line.split("/confirm-password-reset/", 1)[1].split('"')[ + 0 + ] assert len(token) > 10 new_password = uuid4().hex - assert client.admins.confirmPasswordReset(token, new_password, new_password) + assert client.admins.confirmPasswordReset( + token, new_password, new_password + ) client.admins.auth_with_password(state.new_email, new_password) def test_delete_admin(self, client: PocketBase, state): diff --git a/tests/integration/test_backups.py b/tests/integration/test_backups.py index 55c7430..a36cfc0 100644 --- a/tests/integration/test_backups.py +++ b/tests/integration/test_backups.py @@ -2,16 +2,17 @@ import errno import http import time -from typing import Iterator +from typing import Any, Generator, Iterator from uuid import uuid4 import pytest from pocketbase import PocketBase from pocketbase.models import FileUpload -from pocketbase.models.collection import Collection +from pocketbase.models.utils.base_model import BaseModel from pocketbase.utils import ClientResponseError + def cleanup_backup(client: PocketBase, backup_name: str): # Cleanup print("Cleaning up uploaded backup %s" % (backup_name,)) @@ -20,7 +21,10 @@ def cleanup_backup(client: PocketBase, backup_name: str): # Check that it was deleted for backup in client.backups.get_full_list(): if backup.key == backup_name: - pytest.fail("Backup %s still found in list of all backups" % (backup_name,)) + pytest.fail( + "Backup %s still found in list of all backups" % (backup_name,) + ) + @pytest.fixture def backup_name(client: PocketBase) -> Iterator[str]: @@ -33,7 +37,7 @@ def backup_name(client: PocketBase) -> Iterator[str]: @pytest.fixture -def target_collection(client: PocketBase) -> Collection: +def target_collection(client: PocketBase) -> Generator[BaseModel, Any, None]: collection = client.collections.create( { "name": uuid4().hex, @@ -57,7 +61,9 @@ def target_collection(client: PocketBase) -> Collection: class TestBackupsService: - def test_create_list_download_and_delete(self, client: PocketBase, state, backup_name): + def test_create_list_download_and_delete( + self, client: PocketBase, state, backup_name + ): # Find new backup in list of all backups for backup in client.backups.get_full_list(): if backup.key == backup_name: @@ -66,14 +72,19 @@ def test_create_list_download_and_delete(self, client: PocketBase, state, backup assert backup.size > 0 break else: - pytest.fail("Backup %s not found in list of all backups" % (state.backup_name,)) + pytest.fail( + "Backup %s not found in list of all backups" + % (state.backup_name,) + ) # Download the backup data = client.backups.download(backup_name) assert isinstance(data, bytes) assert len(data) == state.backup.size - def test_restore(self, client: PocketBase, state, backup_name, target_collection): + def test_restore( + self, client: PocketBase, state, backup_name, target_collection + ): # Create a record that will be deleted with backup is restored. collection = client.collection(target_collection.id) state.record = collection.create({"title": "Test record"}) @@ -98,10 +109,14 @@ def test_upload(self, client: PocketBase, state, backup_name): state.downloaded_backup = client.backups.download(backup_name) state.new_backup_name = "%s.zip" % (uuid4().hex[:16],) - upload = FileUpload(state.new_backup_name, state.downloaded_backup, "application/zip") + upload = FileUpload( + state.new_backup_name, state.downloaded_backup, "application/zip" + ) client.backups.upload(upload) try: - state.downloaded_new_backup = client.backups.download(state.new_backup_name) + state.downloaded_new_backup = client.backups.download( + state.new_backup_name + ) assert state.downloaded_new_backup == state.downloaded_backup finally: cleanup_backup(client, state.new_backup_name) diff --git a/tests/integration/test_collection.py b/tests/integration/test_collection.py index 2dd3048..b6320f9 100644 --- a/tests/integration/test_collection.py +++ b/tests/integration/test_collection.py @@ -1,10 +1,11 @@ -from pocketbase import PocketBase -from pocketbase.utils import ClientResponseError -from pocketbase.models.collection import Collection - from uuid import uuid4 + import pytest +from pocketbase import PocketBase +from pocketbase.models.collection import Collection +from pocketbase.utils import ClientResponseError + class TestCollectionService: def test_create(self, client: PocketBase, state): @@ -54,7 +55,7 @@ def test_update(self, client: PocketBase, state): def test_delete(self, client: PocketBase, state): client.collections.delete(state.collection.id) with pytest.raises(ClientResponseError) as exc: - client.collections.delete(state.collection.id, uuid4().hex) + client.collections.delete(state.collection.id, uuid4().hex) # type: ignore assert exc.value.status == 404 # double already deleted diff --git a/tests/integration/test_files.py b/tests/integration/test_files.py index c8d100e..10e947a 100644 --- a/tests/integration/test_files.py +++ b/tests/integration/test_files.py @@ -1,9 +1,11 @@ -from pocketbase import PocketBase -from pocketbase.client import FileUpload -import httpx from random import getrandbits from uuid import uuid4 +import httpx + +from pocketbase import PocketBase +from pocketbase.client import FileUpload + class TestFileService: def test_init_collection(self, client: PocketBase, state): diff --git a/tests/integration/test_local_auth_store.py b/tests/integration/test_local_auth_store.py index 7281a12..2754a88 100644 --- a/tests/integration/test_local_auth_store.py +++ b/tests/integration/test_local_auth_store.py @@ -1,10 +1,12 @@ +import tempfile +from uuid import uuid4 + +import pytest + from pocketbase import PocketBase from pocketbase.models.admin import Admin -from pocketbase.utils import ClientResponseError from pocketbase.stores.local_auth_store import LocalAuthStore -from uuid import uuid4 -import pytest -import tempfile +from pocketbase.utils import ClientResponseError class TestLocalAuthStore: diff --git a/tests/integration/test_record.py b/tests/integration/test_record.py index 85db3e0..e30f7c6 100644 --- a/tests/integration/test_record.py +++ b/tests/integration/test_record.py @@ -1,8 +1,10 @@ -from pocketbase import PocketBase -from pocketbase.utils import ClientResponseError from uuid import uuid4 + import pytest +from pocketbase import PocketBase +from pocketbase.utils import ClientResponseError + class TestRecordService: def test_init_collection(self, client: PocketBase, state): @@ -90,7 +92,9 @@ def test_create_multi_relation_record(self, client: PocketBase, state): ) def test_get_record(self, client: PocketBase, state): - state.get_record = client.collection(state.coll.id).get_one(state.record.id) + state.get_record = client.collection(state.coll.id).get_one( + state.record.id + ) assert state.get_record.title is not None assert state.record.title == state.get_record.title assert not state.get_record.is_new diff --git a/tests/integration/test_record_auth.py b/tests/integration/test_record_auth.py index 033739b..28add2b 100644 --- a/tests/integration/test_record_auth.py +++ b/tests/integration/test_record_auth.py @@ -1,13 +1,14 @@ +from os import environ, path +from time import sleep +from uuid import uuid4 + +import pytest + from pocketbase import PocketBase -from pocketbase.models.record import Record from pocketbase.models.admin import Admin +from pocketbase.models.record import Record from pocketbase.utils import ClientResponseError -from uuid import uuid4 -import pytest -from time import sleep -from os import environ, path - class TestRecordAuthService: def test_create_user(self, client: PocketBase, state): @@ -27,7 +28,9 @@ def test_create_user(self, client: PocketBase, state): def test_login_user(self, client: PocketBase, state): oldtoken = client.auth_store.token client.auth_store.clear() - client.collection("users").auth_with_password(state.email, state.password) + client.collection("users").auth_with_password( + state.email, state.password + ) # should now be logged in as new user assert isinstance(client.auth_store.model, Record) assert client.auth_store.model.id == state.user.id @@ -77,7 +80,9 @@ def test_change_email(self, client: PocketBase, state): if "/confirm-email-change/" in line: token = line.split("/confirm-email-change/", 1)[1].split('"')[0] assert len(token) > 10 - assert client.collection("users").confirmEmailChange(token, state.password) + assert client.collection("users").confirmEmailChange( + token, state.password + ) client.collection("users").auth_with_password(new_email, state.password) state.email = new_email @@ -90,12 +95,16 @@ def test_request_password_reset(self, client: PocketBase, state): assert path.exists(mail) for line in open(mail).readlines(): if "/confirm-password-reset/" in line: - token = line.split("/confirm-password-reset/", 1)[1].split('"')[0] + token = line.split("/confirm-password-reset/", 1)[1].split('"')[ + 0 + ] assert len(token) > 10 assert client.collection("users").confirmPasswordReset( token, state.password, state.password ) - client.collection("users").auth_with_password(state.email, state.password) + client.collection("users").auth_with_password( + state.email, state.password + ) def test_delete_user(self, client: PocketBase, state): client.collection("users").delete(state.user.id) diff --git a/tests/integration/test_record_event.py b/tests/integration/test_record_event.py index 572641d..31fb6b8 100644 --- a/tests/integration/test_record_event.py +++ b/tests/integration/test_record_event.py @@ -1,10 +1,10 @@ -from pocketbase import PocketBase +from time import sleep from uuid import uuid4 + +from pocketbase import PocketBase +from pocketbase.models import Record from pocketbase.services import RecordService from pocketbase.services.realtime_service import MessageData -from pocketbase.models import Record - -from time import sleep class TestRecordEventService: diff --git a/tests/integration/test_settings.py b/tests/integration/test_settings.py index 3d16f62..661b518 100644 --- a/tests/integration/test_settings.py +++ b/tests/integration/test_settings.py @@ -1,8 +1,10 @@ -from pocketbase import PocketBase +from os import environ, path +from uuid import uuid4 + import pytest + +from pocketbase import PocketBase from pocketbase.utils import ClientResponseError -from uuid import uuid4 -from os import environ, path class TestSettingsService: @@ -22,8 +24,12 @@ def test_read_all(self, client: PocketBase, state): def test_email(self, client: PocketBase, state): addr = uuid4().hex - assert client.settings.test_email(f"settings@{addr}.com", "verification") - assert path.exists(environ.get("TMP_EMAIL_DIR") + f"/settings@{addr}.com") + assert client.settings.test_email( + f"settings@{addr}.com", "verification" + ) + assert path.exists( + environ.get("TMP_EMAIL_DIR") + f"/settings@{addr}.com" + ) def test_s3(self, client: PocketBase, state): with pytest.raises(ClientResponseError) as exc: diff --git a/tests/test_client.py b/tests/test_client.py index f0bafd4..c7d95c6 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1,5 +1,6 @@ -from pytest_httpx import HTTPXMock import httpx +from pytest_httpx import HTTPXMock + from pocketbase import PocketBase From 8d881bae6874f0896dafa60e0a93ed133ce8fab0 Mon Sep 17 00:00:00 2001 From: Vithor Jaeger Date: Wed, 4 Sep 2024 09:57:06 -0400 Subject: [PATCH 2/3] fix lock --- poetry.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 0023bb4..ee6c9b8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -355,4 +355,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "4779b76e64c6b8a7a25bf25e719243c8bf887af6208e11f41f85c9a66e21f3bd" +content-hash = "5f129504a646ebce1eabdc6f5f5e19b633ba214f072f79fd1c1f14ba19b7746d" From 535c14c4c2fa86048a6345bcdd1d0551fddd5033 Mon Sep 17 00:00:00 2001 From: Vithor Jaeger Date: Wed, 4 Sep 2024 09:59:41 -0400 Subject: [PATCH 3/3] fix query_params mistake --- pocketbase/services/record_service.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pocketbase/services/record_service.py b/pocketbase/services/record_service.py index 353951e..267659b 100644 --- a/pocketbase/services/record_service.py +++ b/pocketbase/services/record_service.py @@ -139,7 +139,9 @@ def auth_response(self, response_data: dict) -> RecordAuthResponse: self.client.auth_store.save(token, record) return RecordAuthResponse(token=token, record=record, **response_data) # type: ignore - def list_auth_methods(self, query_params: dict | None) -> AuthMethodsList: + def list_auth_methods( + self, query_params: dict | None = None + ) -> AuthMethodsList: if query_params is None: query_params = {} """Returns all available collection auth methods."""