about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/postgrest/_sync
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/postgrest/_sync')
-rw-r--r--.venv/lib/python3.12/site-packages/postgrest/_sync/__init__.py1
-rw-r--r--.venv/lib/python3.12/site-packages/postgrest/_sync/client.py128
-rw-r--r--.venv/lib/python3.12/site-packages/postgrest/_sync/request_builder.py415
3 files changed, 544 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/postgrest/_sync/__init__.py b/.venv/lib/python3.12/site-packages/postgrest/_sync/__init__.py
new file mode 100644
index 00000000..9d48db4f
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/postgrest/_sync/__init__.py
@@ -0,0 +1 @@
+from __future__ import annotations
diff --git a/.venv/lib/python3.12/site-packages/postgrest/_sync/client.py b/.venv/lib/python3.12/site-packages/postgrest/_sync/client.py
new file mode 100644
index 00000000..29b9aab4
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/postgrest/_sync/client.py
@@ -0,0 +1,128 @@
+from __future__ import annotations
+
+from typing import Any, Dict, Optional, Union, cast
+
+from deprecation import deprecated
+from httpx import Headers, QueryParams, Timeout
+
+from ..base_client import BasePostgrestClient
+from ..constants import (
+    DEFAULT_POSTGREST_CLIENT_HEADERS,
+    DEFAULT_POSTGREST_CLIENT_TIMEOUT,
+)
+from ..types import CountMethod
+from ..utils import SyncClient
+from ..version import __version__
+from .request_builder import SyncRequestBuilder, SyncRPCFilterRequestBuilder
+
+_TableT = Dict[str, Any]
+
+
+class SyncPostgrestClient(BasePostgrestClient):
+    """PostgREST client."""
+
+    def __init__(
+        self,
+        base_url: str,
+        *,
+        schema: str = "public",
+        headers: Dict[str, str] = DEFAULT_POSTGREST_CLIENT_HEADERS,
+        timeout: Union[int, float, Timeout] = DEFAULT_POSTGREST_CLIENT_TIMEOUT,
+        verify: bool = True,
+        proxy: Optional[str] = None,
+    ) -> None:
+        BasePostgrestClient.__init__(
+            self,
+            base_url,
+            schema=schema,
+            headers=headers,
+            timeout=timeout,
+            verify=verify,
+            proxy=proxy,
+        )
+        self.session = cast(SyncClient, self.session)
+
+    def create_session(
+        self,
+        base_url: str,
+        headers: Dict[str, str],
+        timeout: Union[int, float, Timeout],
+        verify: bool = True,
+        proxy: Optional[str] = None,
+    ) -> SyncClient:
+        return SyncClient(
+            base_url=base_url,
+            headers=headers,
+            timeout=timeout,
+            verify=verify,
+            proxy=proxy,
+            follow_redirects=True,
+            http2=True,
+        )
+
+    def __enter__(self) -> SyncPostgrestClient:
+        return self
+
+    def __exit__(self, exc_type, exc, tb) -> None:
+        self.aclose()
+
+    def aclose(self) -> None:
+        """Close the underlying HTTP connections."""
+        self.session.aclose()
+
+    def from_(self, table: str) -> SyncRequestBuilder[_TableT]:
+        """Perform a table operation.
+
+        Args:
+            table: The name of the table
+        Returns:
+            :class:`AsyncRequestBuilder`
+        """
+        return SyncRequestBuilder[_TableT](self.session, f"/{table}")
+
+    def table(self, table: str) -> SyncRequestBuilder[_TableT]:
+        """Alias to :meth:`from_`."""
+        return self.from_(table)
+
+    @deprecated("0.2.0", "1.0.0", __version__, "Use self.from_() instead")
+    def from_table(self, table: str) -> SyncRequestBuilder:
+        """Alias to :meth:`from_`."""
+        return self.from_(table)
+
+    def rpc(
+        self,
+        func: str,
+        params: dict,
+        count: Optional[CountMethod] = None,
+        head: bool = False,
+        get: bool = False,
+    ) -> SyncRPCFilterRequestBuilder[Any]:
+        """Perform a stored procedure call.
+
+        Args:
+            func: The name of the remote procedure to run.
+            params: The parameters to be passed to the remote procedure.
+            count: The method to use to get the count of rows returned.
+            head: When set to `true`, `data` will not be returned. Useful if you only need the count.
+            get: When set to `true`, the function will be called with read-only access mode.
+        Returns:
+            :class:`AsyncRPCFilterRequestBuilder`
+        Example:
+            .. code-block:: python
+
+                await client.rpc("foobar", {"arg": "value"}).execute()
+
+        .. versionchanged:: 0.10.9
+            This method now returns a :class:`AsyncRPCFilterRequestBuilder`.
+        .. versionchanged:: 0.10.2
+            This method now returns a :class:`AsyncFilterRequestBuilder` which allows you to
+            filter on the RPC's resultset.
+        """
+        method = "HEAD" if head else "GET" if get else "POST"
+
+        headers = Headers({"Prefer": f"count={count}"}) if count else Headers()
+
+        # the params here are params to be sent to the RPC and not the queryparams!
+        return SyncRPCFilterRequestBuilder[Any](
+            self.session, f"/rpc/{func}", method, headers, QueryParams(), json=params
+        )
diff --git a/.venv/lib/python3.12/site-packages/postgrest/_sync/request_builder.py b/.venv/lib/python3.12/site-packages/postgrest/_sync/request_builder.py
new file mode 100644
index 00000000..8b0eb160
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/postgrest/_sync/request_builder.py
@@ -0,0 +1,415 @@
+from __future__ import annotations
+
+from json import JSONDecodeError
+from typing import Any, Generic, Optional, TypeVar, Union
+
+from httpx import Headers, QueryParams
+from pydantic import ValidationError
+
+from ..base_request_builder import (
+    APIResponse,
+    BaseFilterRequestBuilder,
+    BaseRPCRequestBuilder,
+    BaseSelectRequestBuilder,
+    CountMethod,
+    SingleAPIResponse,
+    pre_delete,
+    pre_insert,
+    pre_select,
+    pre_update,
+    pre_upsert,
+)
+from ..exceptions import APIError, generate_default_error_message
+from ..types import ReturnMethod
+from ..utils import SyncClient, get_origin_and_cast
+
+_ReturnT = TypeVar("_ReturnT")
+
+
+class SyncQueryRequestBuilder(Generic[_ReturnT]):
+    def __init__(
+        self,
+        session: SyncClient,
+        path: str,
+        http_method: str,
+        headers: Headers,
+        params: QueryParams,
+        json: Union[dict, list],
+    ) -> None:
+        self.session = session
+        self.path = path
+        self.http_method = http_method
+        self.headers = headers
+        self.params = params
+        self.json = None if http_method in {"GET", "HEAD"} else json
+
+    def execute(self) -> APIResponse[_ReturnT]:
+        """Execute the query.
+
+        .. tip::
+            This is the last method called, after the query is built.
+
+        Returns:
+            :class:`APIResponse`
+
+        Raises:
+            :class:`APIError` If the API raised an error.
+        """
+        r = self.session.request(
+            self.http_method,
+            self.path,
+            json=self.json,
+            params=self.params,
+            headers=self.headers,
+        )
+        try:
+            if r.is_success:
+                if self.http_method != "HEAD":
+                    body = r.text
+                    if self.headers.get("Accept") == "text/csv":
+                        return body
+                    if self.headers.get(
+                        "Accept"
+                    ) and "application/vnd.pgrst.plan" in self.headers.get("Accept"):
+                        if "+json" not in self.headers.get("Accept"):
+                            return body
+                return APIResponse[_ReturnT].from_http_request_response(r)
+            else:
+                raise APIError(r.json())
+        except ValidationError as e:
+            raise APIError(r.json()) from e
+        except JSONDecodeError:
+            raise APIError(generate_default_error_message(r))
+
+
+class SyncSingleRequestBuilder(Generic[_ReturnT]):
+    def __init__(
+        self,
+        session: SyncClient,
+        path: str,
+        http_method: str,
+        headers: Headers,
+        params: QueryParams,
+        json: dict,
+    ) -> None:
+        self.session = session
+        self.path = path
+        self.http_method = http_method
+        self.headers = headers
+        self.params = params
+        self.json = json
+
+    def execute(self) -> SingleAPIResponse[_ReturnT]:
+        """Execute the query.
+
+        .. tip::
+            This is the last method called, after the query is built.
+
+        Returns:
+            :class:`SingleAPIResponse`
+
+        Raises:
+            :class:`APIError` If the API raised an error.
+        """
+        r = self.session.request(
+            self.http_method,
+            self.path,
+            json=self.json,
+            params=self.params,
+            headers=self.headers,
+        )
+        try:
+            if (
+                200 <= r.status_code <= 299
+            ):  # Response.ok from JS (https://developer.mozilla.org/en-US/docs/Web/API/Response/ok)
+                return SingleAPIResponse[_ReturnT].from_http_request_response(r)
+            else:
+                raise APIError(r.json())
+        except ValidationError as e:
+            raise APIError(r.json()) from e
+        except JSONDecodeError:
+            raise APIError(generate_default_error_message(r))
+
+
+class SyncMaybeSingleRequestBuilder(SyncSingleRequestBuilder[_ReturnT]):
+    def execute(self) -> Optional[SingleAPIResponse[_ReturnT]]:
+        r = None
+        try:
+            r = SyncSingleRequestBuilder[_ReturnT].execute(self)
+        except APIError as e:
+            if e.details and "The result contains 0 rows" in e.details:
+                return None
+        if not r:
+            raise APIError(
+                {
+                    "message": "Missing response",
+                    "code": "204",
+                    "hint": "Please check traceback of the code",
+                    "details": "Postgrest couldn't retrieve response, please check traceback of the code. Please create an issue in `supabase-community/postgrest-py` if needed.",
+                }
+            )
+        return r
+
+
+# ignoring type checking as a workaround for https://github.com/python/mypy/issues/9319
+class SyncFilterRequestBuilder(BaseFilterRequestBuilder[_ReturnT], SyncQueryRequestBuilder[_ReturnT]):  # type: ignore
+    def __init__(
+        self,
+        session: SyncClient,
+        path: str,
+        http_method: str,
+        headers: Headers,
+        params: QueryParams,
+        json: dict,
+    ) -> None:
+        get_origin_and_cast(BaseFilterRequestBuilder[_ReturnT]).__init__(
+            self, session, headers, params
+        )
+        get_origin_and_cast(SyncQueryRequestBuilder[_ReturnT]).__init__(
+            self, session, path, http_method, headers, params, json
+        )
+
+
+# this exists for type-safety. see https://gist.github.com/anand2312/93d3abf401335fd3310d9e30112303bf
+class SyncRPCFilterRequestBuilder(
+    BaseRPCRequestBuilder[_ReturnT], SyncSingleRequestBuilder[_ReturnT]
+):
+    def __init__(
+        self,
+        session: SyncClient,
+        path: str,
+        http_method: str,
+        headers: Headers,
+        params: QueryParams,
+        json: dict,
+    ) -> None:
+        get_origin_and_cast(BaseFilterRequestBuilder[_ReturnT]).__init__(
+            self, session, headers, params
+        )
+        get_origin_and_cast(SyncSingleRequestBuilder[_ReturnT]).__init__(
+            self, session, path, http_method, headers, params, json
+        )
+
+
+# ignoring type checking as a workaround for https://github.com/python/mypy/issues/9319
+class SyncSelectRequestBuilder(BaseSelectRequestBuilder[_ReturnT], SyncQueryRequestBuilder[_ReturnT]):  # type: ignore
+    def __init__(
+        self,
+        session: SyncClient,
+        path: str,
+        http_method: str,
+        headers: Headers,
+        params: QueryParams,
+        json: dict,
+    ) -> None:
+        get_origin_and_cast(BaseSelectRequestBuilder[_ReturnT]).__init__(
+            self, session, headers, params
+        )
+        get_origin_and_cast(SyncQueryRequestBuilder[_ReturnT]).__init__(
+            self, session, path, http_method, headers, params, json
+        )
+
+    def single(self) -> SyncSingleRequestBuilder[_ReturnT]:
+        """Specify that the query will only return a single row in response.
+
+        .. caution::
+            The API will raise an error if the query returned more than one row.
+        """
+        self.headers["Accept"] = "application/vnd.pgrst.object+json"
+        return SyncSingleRequestBuilder[_ReturnT](
+            headers=self.headers,
+            http_method=self.http_method,
+            json=self.json,
+            params=self.params,
+            path=self.path,
+            session=self.session,  # type: ignore
+        )
+
+    def maybe_single(self) -> SyncMaybeSingleRequestBuilder[_ReturnT]:
+        """Retrieves at most one row from the result. Result must be at most one row (e.g. using `eq` on a UNIQUE column), otherwise this will result in an error."""
+        self.headers["Accept"] = "application/vnd.pgrst.object+json"
+        return SyncMaybeSingleRequestBuilder[_ReturnT](
+            headers=self.headers,
+            http_method=self.http_method,
+            json=self.json,
+            params=self.params,
+            path=self.path,
+            session=self.session,  # type: ignore
+        )
+
+    def text_search(
+        self, column: str, query: str, options: dict[str, Any] = {}
+    ) -> SyncFilterRequestBuilder[_ReturnT]:
+        type_ = options.get("type")
+        type_part = ""
+        if type_ == "plain":
+            type_part = "pl"
+        elif type_ == "phrase":
+            type_part = "ph"
+        elif type_ == "web_search":
+            type_part = "w"
+        config_part = f"({options.get('config')})" if options.get("config") else ""
+        self.params = self.params.add(column, f"{type_part}fts{config_part}.{query}")
+
+        return SyncQueryRequestBuilder[_ReturnT](
+            headers=self.headers,
+            http_method=self.http_method,
+            json=self.json,
+            params=self.params,
+            path=self.path,
+            session=self.session,  # type: ignore
+        )
+
+    def csv(self) -> SyncSingleRequestBuilder[str]:
+        """Specify that the query must retrieve data as a single CSV string."""
+        self.headers["Accept"] = "text/csv"
+        return SyncSingleRequestBuilder[str](
+            session=self.session,  # type: ignore
+            path=self.path,
+            http_method=self.http_method,
+            headers=self.headers,
+            params=self.params,
+            json=self.json,
+        )
+
+
+class SyncRequestBuilder(Generic[_ReturnT]):
+    def __init__(self, session: SyncClient, path: str) -> None:
+        self.session = session
+        self.path = path
+
+    def select(
+        self,
+        *columns: str,
+        count: Optional[CountMethod] = None,
+        head: Optional[bool] = None,
+    ) -> SyncSelectRequestBuilder[_ReturnT]:
+        """Run a SELECT query.
+
+        Args:
+            *columns: The names of the columns to fetch.
+            count: The method to use to get the count of rows returned.
+        Returns:
+            :class:`SyncSelectRequestBuilder`
+        """
+        method, params, headers, json = pre_select(*columns, count=count, head=head)
+        return SyncSelectRequestBuilder[_ReturnT](
+            self.session, self.path, method, headers, params, json
+        )
+
+    def insert(
+        self,
+        json: Union[dict, list],
+        *,
+        count: Optional[CountMethod] = None,
+        returning: ReturnMethod = ReturnMethod.representation,
+        upsert: bool = False,
+        default_to_null: bool = True,
+    ) -> SyncQueryRequestBuilder[_ReturnT]:
+        """Run an INSERT query.
+
+        Args:
+            json: The row to be inserted.
+            count: The method to use to get the count of rows returned.
+            returning: Either 'minimal' or 'representation'
+            upsert: Whether the query should be an upsert.
+            default_to_null: Make missing fields default to `null`.
+                Otherwise, use the default value for the column.
+                Only applies for bulk inserts.
+        Returns:
+            :class:`SyncQueryRequestBuilder`
+        """
+        method, params, headers, json = pre_insert(
+            json,
+            count=count,
+            returning=returning,
+            upsert=upsert,
+            default_to_null=default_to_null,
+        )
+        return SyncQueryRequestBuilder[_ReturnT](
+            self.session, self.path, method, headers, params, json
+        )
+
+    def upsert(
+        self,
+        json: Union[dict, list],
+        *,
+        count: Optional[CountMethod] = None,
+        returning: ReturnMethod = ReturnMethod.representation,
+        ignore_duplicates: bool = False,
+        on_conflict: str = "",
+        default_to_null: bool = True,
+    ) -> SyncQueryRequestBuilder[_ReturnT]:
+        """Run an upsert (INSERT ... ON CONFLICT DO UPDATE) query.
+
+        Args:
+            json: The row to be inserted.
+            count: The method to use to get the count of rows returned.
+            returning: Either 'minimal' or 'representation'
+            ignore_duplicates: Whether duplicate rows should be ignored.
+            on_conflict: Specified columns to be made to work with UNIQUE constraint.
+            default_to_null: Make missing fields default to `null`. Otherwise, use the
+                default value for the column. This only applies when inserting new rows,
+                not when merging with existing rows under `ignoreDuplicates: false`.
+                This also only applies when doing bulk upserts.
+        Returns:
+            :class:`SyncQueryRequestBuilder`
+        """
+        method, params, headers, json = pre_upsert(
+            json,
+            count=count,
+            returning=returning,
+            ignore_duplicates=ignore_duplicates,
+            on_conflict=on_conflict,
+            default_to_null=default_to_null,
+        )
+        return SyncQueryRequestBuilder[_ReturnT](
+            self.session, self.path, method, headers, params, json
+        )
+
+    def update(
+        self,
+        json: dict,
+        *,
+        count: Optional[CountMethod] = None,
+        returning: ReturnMethod = ReturnMethod.representation,
+    ) -> SyncFilterRequestBuilder[_ReturnT]:
+        """Run an UPDATE query.
+
+        Args:
+            json: The updated fields.
+            count: The method to use to get the count of rows returned.
+            returning: Either 'minimal' or 'representation'
+        Returns:
+            :class:`SyncFilterRequestBuilder`
+        """
+        method, params, headers, json = pre_update(
+            json,
+            count=count,
+            returning=returning,
+        )
+        return SyncFilterRequestBuilder[_ReturnT](
+            self.session, self.path, method, headers, params, json
+        )
+
+    def delete(
+        self,
+        *,
+        count: Optional[CountMethod] = None,
+        returning: ReturnMethod = ReturnMethod.representation,
+    ) -> SyncFilterRequestBuilder[_ReturnT]:
+        """Run a DELETE query.
+
+        Args:
+            count: The method to use to get the count of rows returned.
+            returning: Either 'minimal' or 'representation'
+        Returns:
+            :class:`SyncFilterRequestBuilder`
+        """
+        method, params, headers, json = pre_delete(
+            count=count,
+            returning=returning,
+        )
+        return SyncFilterRequestBuilder[_ReturnT](
+            self.session, self.path, method, headers, params, json
+        )