Skip to content

Commit

Permalink
Namespace change (#114)
Browse files Browse the repository at this point in the history
* docs: add rtd config

* chore: move to the postgrest namespace

* chore: move constants to its own file

* chore: pass headers/params down builders

We were earlier modifying session.headers/session.params for every
query. Instead of this we follow what postgrest-js does and add
headers and params as arguments to the query builders, and pass them
down the chain of builders, and finally pass it to the execute method.

* docs: add examples

* fix: order of filters in examples

* docs: add example for closing the client
  • Loading branch information
anand2312 committed Apr 18, 2022
1 parent 29e91a2 commit 6493154
Show file tree
Hide file tree
Showing 39 changed files with 435 additions and 227 deletions.
14 changes: 14 additions & 0 deletions .readthedocs.yaml
@@ -0,0 +1,14 @@
version: 2

build:
os: ubuntu-20.04
tools:
python: "3.9"

python:
install:
- requirements: docs/requirements.txt


- method: pip
path: .
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -25,4 +25,4 @@ clean_infra:
run_tests: tests

build_sync:
poetry run unasync postgrest_py tests
poetry run unasync postgrest tests
11 changes: 7 additions & 4 deletions README.md
Expand Up @@ -54,7 +54,7 @@ pip install postgrest-py

```py
import asyncio
from postgrest_py import AsyncPostgrestClient
from postgrest import AsyncPostgrestClient

async def main():
async with AsyncPostgrestClient("http://localhost:3000") as client:
Expand All @@ -74,24 +74,27 @@ await client.from_("countries").insert({ "name": "Việt Nam", "capital": "Hà N

```py
r = await client.from_("countries").select("id", "name").execute()
countries = r.json()
countries = r.data
```

### Update

```py
await client.from_("countries").eq("name", "Việt Nam").update({"capital": "Hà Nội"}).execute()
await client.from_("countries").update({"capital": "Hà Nội"}).eq("name", "Việt Nam").execute()
```

### Delete

```py
await client.from_("countries").eq("name", "Việt Nam").delete().execute()
await client.from_("countries").delete().eq("name", "Việt Nam").execute()
```

### General filters

### Stored procedures (RPC)
```py
await client.rpc("foobar", {"arg1": "value1", "arg2": "value2"}).execute()
```

## DEVELOPMENT

Expand Down
4 changes: 2 additions & 2 deletions docs/api/client.rst
Expand Up @@ -5,10 +5,10 @@ To run any queries, the first step is to construct a client.

The library offers both synchronous and asynchronous clients.

.. autoclass:: postgrest_py.AsyncPostgrestClient
.. autoclass:: postgrest.AsyncPostgrestClient
:members:
:inherited-members:

.. autoclass:: postgrest_py.SyncPostgrestClient
.. autoclass:: postgrest.SyncPostgrestClient
:members:
:inherited-members:
2 changes: 1 addition & 1 deletion docs/api/exceptions.rst
@@ -1,5 +1,5 @@
Exceptions
==========

.. autoexception:: postgrest_py.APIError
.. autoexception:: postgrest.APIError
:members:
8 changes: 6 additions & 2 deletions docs/api/filters.rst
Expand Up @@ -18,10 +18,14 @@ filter data during queries.
All the filter methods return a modified instance of the filter builder, allowing fluent chaining of filters.


.. autoclass:: postgrest_py.AsyncFilterRequestBuilder
.. autoclass:: postgrest.AsyncFilterRequestBuilder
:members:
:undoc-members:
:inherited-members:
:member-order: bysource

.. autoclass:: postgrest_py.SyncFilterRequestBuilder
.. autoclass:: postgrest.SyncFilterRequestBuilder
:members:
:undoc-members:
:inherited-members:
:member-order: bysource
12 changes: 6 additions & 6 deletions docs/api/request_builders.rst
Expand Up @@ -8,26 +8,26 @@ Request Builders
.. warning::
These classes are not meant to be constructed by the user.

.. autoclass:: postgrest_py.AsyncRequestBuilder
.. autoclass:: postgrest.AsyncRequestBuilder
:members:
:inherited-members:

.. autoclass:: postgrest_py.AsyncSelectRequestBuilder
.. autoclass:: postgrest.AsyncSelectRequestBuilder
:members:
:inherited-members:

.. autoclass:: postgrest_py.AsyncQueryRequestBuilder
.. autoclass:: postgrest.AsyncQueryRequestBuilder
:members:
:inherited-members:

.. autoclass:: postgrest_py.SyncRequestBuilder
.. autoclass:: postgrest.SyncRequestBuilder
:members:
:inherited-members:

.. autoclass:: postgrest_py.SyncSelectRequestBuilder
.. autoclass:: postgrest.SyncSelectRequestBuilder
:members:
:inherited-members:

.. autoclass:: postgrest_py.SyncQueryRequestBuilder
.. autoclass:: postgrest.SyncQueryRequestBuilder
:members:
:inherited-members:
4 changes: 2 additions & 2 deletions docs/api/responses.rst
@@ -1,7 +1,7 @@
Responses
=========

Once a query is run, the postgrest_py parses the server's response into an APIResponse object.
Once a query is run, the library parses the server's response into an APIResponse object.

.. autoclass:: postgrest_py.APIResponse
.. autoclass:: postgrest.APIResponse
:members:
8 changes: 4 additions & 4 deletions docs/api/types.rst
Expand Up @@ -3,14 +3,14 @@ Types

Some type aliases and enums used in the library.

.. autoclass:: postgrest_py.types.CountMethod
.. autoclass:: postgrest.types.CountMethod
:members:

.. autoclass:: postgrest_py.types.Filters
.. autoclass:: postgrest.types.Filters
:members:

.. autoclass:: postgrest_py.types.RequestMethod
.. autoclass:: postgrest.types.RequestMethod
:members:

.. autoclass:: postgrest_py.types.ReturnMethod
.. autoclass:: postgrest.types.ReturnMethod
:members:
6 changes: 3 additions & 3 deletions docs/conf.py
Expand Up @@ -16,10 +16,10 @@


# -- Project information -----------------------------------------------------
import postgrest_py
import postgrest

project = "postgrest-py"
version = postgrest_py.__version__
version = postgrest.__version__
release = version
copyright = (
"2022, Anand Krishna, Daniel Reinón García, Joel Lee, Leynier Gutiérrez González"
Expand Down Expand Up @@ -64,4 +64,4 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
html_static_path = []
68 changes: 68 additions & 0 deletions docs/examples/basic_queries.rst
@@ -0,0 +1,68 @@
Getting Started
===============

We connect to the API and authenticate, and fetch some data.

.. code-block:: python
:linenos:
import asyncio
from postgrest import AsyncPostgrestClient
async def main():
async with AsyncPostgrestClient("http://localhost:3000") as client:
client.auth("Bearer <token>")
r = await client.from_("countries").select("*").execute()
countries = r.data
asyncio.run(main())
**CRUD**

.. code-block:: python
await client.from_("countries").insert({ "name": "Việt Nam", "capital": "Hà Nội" }).execute()
.. code-block:: python
r = await client.from_("countries").select("id", "name").execute()
countries = r.data
.. code-block:: python
await client.from_("countries").update({"capital": "Hà Nội"}).eq("name", "Việt Nam").execute()
.. code-block:: python
await client.from_("countries").delete().eq("name", "Việt Nam").execute()
**Calling RPCs**

.. code-block:: python
await client.rpc("foo").execute()
.. code-block:: python
await client.rpc("bar", {"arg1": "value1", "arg2": "value2"}).execute()
**Closing the connection**

Once you have finished running your queries, close the connection:

.. code-block:: python
await client.aclose()
You can also use the client with a context manager, which will close the client for you.

.. code-block:: python
async with AsyncPostgrestClient("url") as client:
# run queries
# the client is closed when the async with block ends
12 changes: 11 additions & 1 deletion docs/examples/index.rst
@@ -1,4 +1,14 @@
Examples
========

Stay tuned! Examples are coming soon.
.. note::
The library offers both synchronous and asynchronous clients. In the examples, we use the
async client. However, they should work the same for the sync client as well.


.. toctree::
:maxdepth: 1
:caption: More examples:

Basic Queries <basic_queries>
Logging Requests <logging>
25 changes: 25 additions & 0 deletions docs/examples/logging.rst
@@ -0,0 +1,25 @@
Logging Requests
================

While debugging, you might want to see the API requests that are being sent for every query.
To do this, just set the logging level to "DEBUG":

.. code-block:: python
:linenos:
from logging import basicConfig, DEBUG
from postgrest import SyncPostgrestClient
basicConfig(level=DEBUG)
client = SyncPostgrestClient(...)
client.from_("test").select("*").eq("a", "b").execute()
client.from_("test").select("*").eq("foo", "bar").eq("baz", "spam").execute()
Output:

.. code-block::
DEBUG:httpx._client:HTTP Request: GET https://<URL>/rest/v1/test?select=%2A&a=eq.b "HTTP/1.1 200 OK"
DEBUG:httpx._client:HTTP Request: GET https://<URL>/rest/v1/test?select=%2A&foo=eq.bar&baz=eq.spam "HTTP/1.1 200 OK"
6 changes: 5 additions & 1 deletion docs/index.rst
Expand Up @@ -13,14 +13,18 @@ Requirements:
- Python >= 3.7

**With pip:**
::

pip install postgrest-py

**With poetry:**
::

poetry add postgrest-py


.. toctree::
:maxdepth: 3
:maxdepth: 2
:caption: Contents:

API Reference </api/index>
Expand Down
1 change: 1 addition & 0 deletions docs/requirements.txt
@@ -1 +1,2 @@
furo >= 2022.4.7
Sphinx == 4.3.2
2 changes: 1 addition & 1 deletion postgrest_py/__init__.py → postgrest/__init__.py
Expand Up @@ -18,8 +18,8 @@
SyncRequestBuilder,
SyncSelectRequestBuilder,
)
from .base_client import DEFAULT_POSTGREST_CLIENT_HEADERS
from .base_request_builder import APIResponse
from .constants import DEFAULT_POSTGREST_CLIENT_HEADERS
from .deprecated_client import Client, PostgrestClient
from .deprecated_get_request_builder import GetRequestBuilder
from .exceptions import APIError
File renamed without changes.
21 changes: 16 additions & 5 deletions postgrest_py/_async/client.py → postgrest/_async/client.py
Expand Up @@ -3,13 +3,13 @@
from typing import Dict, Union, cast

from deprecation import deprecated
from httpx import Timeout
from httpx import Headers, QueryParams, Timeout

from .. import __version__
from ..base_client import (
from ..base_client import BasePostgrestClient
from ..constants import (
DEFAULT_POSTGREST_CLIENT_HEADERS,
DEFAULT_POSTGREST_CLIENT_TIMEOUT,
BasePostgrestClient,
)
from ..utils import AsyncClient
from .request_builder import AsyncFilterRequestBuilder, AsyncRequestBuilder
Expand Down Expand Up @@ -73,7 +73,7 @@ def table(self, table: str) -> AsyncRequestBuilder:

@deprecated("0.2.0", "1.0.0", __version__, "Use self.from_() instead")
def from_table(self, table: str) -> AsyncRequestBuilder:
"""Alias to self.from_()."""
"""Alias to :meth:`from_`."""
return self.from_(table)

async def rpc(self, func: str, params: dict) -> AsyncFilterRequestBuilder:
Expand All @@ -84,5 +84,16 @@ async def rpc(self, func: str, params: dict) -> AsyncFilterRequestBuilder:
params: The parameters to be passed to the remote procedure.
Returns:
:class:`AsyncFilterRequestBuilder`
Example:
.. code-block:: python
await client.rpc("foobar", {"arg": "value"}).execute()
.. versionchanged:: 0.11.0
This method now returns a :class:`AsyncFilterRequestBuilder` which allows you to
filter on the RPC's resultset.
"""
return AsyncFilterRequestBuilder(self.session, f"/rpc/{func}", "POST", params)
# the params here are params to be sent to the RPC and not the queryparams!
return AsyncFilterRequestBuilder(
self.session, f"/rpc/{func}", "POST", Headers(), QueryParams(), json=params
)

0 comments on commit 6493154

Please sign in to comment.