Skip to content

Commit 96fed3a

Browse files
committed
Complete basic features
1 parent 3c1cbf2 commit 96fed3a

File tree

4 files changed

+121
-15
lines changed

4 files changed

+121
-15
lines changed

TODO.md

+4
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
## ROADMAP
2+
3+
- [ ] Multi-criteria ordering
4+
- [ ] Exact match filtering
5+
- [ ] OR filter

postgrest_py/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from postgrest_py.client import Client

postgrest_py/client.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,29 @@ def __init__(self, base_url: str, *, schema="public") -> None:
1313
}
1414
self.session = AsyncClient(base_url=base_url, params={}, headers=headers)
1515

16-
async def __aenter__(self) -> Client:
16+
async def __aenter__(self):
1717
return self
1818

19-
async def __aexit__(self) -> None:
19+
async def __aexit__(self, exc_type, exc, tb) -> None:
2020
await self.aclose()
2121

2222
async def aclose(self) -> None:
2323
await self.session.aclose()
2424

25-
def auth(self, token: str) -> Client:
25+
def auth(self, token: str):
2626
self.session.headers["Authorization"] = f"Bearer {token}"
2727
return self
2828

29-
def schema(self, schema: str) -> Client:
29+
def schema(self, schema: str):
3030
self.session.merge_headers(
3131
{"Accept-Profile": schema, "Content-Profile": schema}
3232
)
3333
return self
3434

35-
def fromTable(self, table: str) -> RequestBuilder:
35+
def from_table(self, table: str) -> RequestBuilder:
3636
return RequestBuilder(self.session, f"/{table}")
37+
38+
def from_(self, table: str) -> RequestBuilder:
39+
"""Alias to Self.from_table()."""
40+
41+
return self.fromTable(table)

postgrest_py/request_builder.py

+106-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from httpx import AsyncClient
1+
from httpx import AsyncClient, Response
2+
3+
from postgrest_py.constants import FILTER_OPERATORS
24

35

46
class RequestBuilder:
@@ -8,54 +10,148 @@ def __init__(self, session: AsyncClient, path: str) -> None:
810
self.json = {}
911
self.http_method = "GET"
1012

11-
def select(self, columns: str) -> GetRequestBuilder:
13+
def select(self, columns: str):
1214
self.session.params["select"] = columns
1315
self.http_method = "GET"
1416
return GetRequestBuilder.from_request_builder(self)
1517

16-
def insert(self, json: dict, *, upsert=False) -> RequestBuilder:
18+
def insert(self, json: dict, *, upsert=False):
1719
self.session.headers[
1820
"Prefer"
1921
] = f"return=representation{',resolution=merge-duplicates' if upsert else ''}"
2022
self.json = json
2123
self.http_method = "POST"
2224
return self
2325

24-
def update(self, json: dict) -> RequestBuilder:
26+
def update(self, json: dict):
2527
self.session.headers["Prefer"] = "return=representation"
2628
self.json = json
2729
self.http_method = "PATCH"
2830
return self
2931

30-
def delete(self) -> RequestBuilder:
32+
def delete(self):
3133
self.http_method = "DELETE"
3234
return self
3335

36+
async def execute(self) -> Response:
37+
r = await self.session.request(self.http_method, self.path, json=self.json)
38+
return r
39+
40+
def filter_in(self, column: str, operator: str, criteria: str):
41+
self.session.params[column] = f"{operator}.{criteria}"
42+
return self
43+
44+
def filter(self, column: str, operator: str, criteria: str):
45+
"""Alias to Self.filter_in()."""
46+
47+
return self.filter_in(column, operator, criteria)
48+
49+
def filter_out(self, column: str, operator: str, criteria: str):
50+
self.session.params[column] = f"not.{operator}.{criteria}"
51+
return self
52+
53+
def not_(self, column: str, operator: str, criteria: str):
54+
"""Alias to Self.filter_out()."""
55+
56+
return self.filter_out(column, operator, criteria)
57+
58+
def eq(self, column: str, criteria: str):
59+
return self.filter_in(column, "eq", criteria)
60+
61+
def neq(self, column: str, criteria: str):
62+
return self.filter_in(column, "neq", criteria)
63+
64+
def gt(self, column: str, criteria: str):
65+
return self.filter_in(column, "gt", criteria)
66+
67+
def lt(self, column: str, criteria: str):
68+
return self.filter_in(column, "lt", criteria)
69+
70+
def gte(self, column: str, criteria: str):
71+
return self.filter_in(column, "gte", criteria)
72+
73+
def lte(self, column: str, criteria: str):
74+
return self.filter_in(column, "lte", criteria)
75+
76+
def like(self, column: str, criteria: str):
77+
return self.filter_in(column, "like", criteria)
78+
79+
def ilike(self, column: str, criteria: str):
80+
return self.filter_in(column, "ilike", criteria)
81+
82+
def is_(self, column: str, criteria: str):
83+
return self.filter_in(column, "is", criteria)
84+
85+
def in_(self, column: str, criteria: str):
86+
return self.filter_in(column, "in", criteria)
87+
88+
def fts(self, column: str, criteria: str):
89+
return self.filter_in(column, "fts", criteria)
90+
91+
def plfts(self, column: str, criteria: str):
92+
return self.filter_in(column, "plfts", criteria)
93+
94+
def phfts(self, column: str, criteria: str):
95+
return self.filter_in(column, "phfts", criteria)
96+
97+
def wfts(self, column: str, criteria: str):
98+
return self.filter_in(column, "wfts", criteria)
99+
100+
def cs(self, column: str, criteria: str):
101+
return self.filter_in(column, "cs", criteria)
102+
103+
def cd(self, column: str, criteria: str):
104+
return self.filter_in(column, "cd", criteria)
105+
106+
def ova(self, column: str, criteria: str):
107+
return self.filter_in(column, "ova", criteria)
108+
109+
def ovr(self, column: str, criteria: str):
110+
return self.filter_in(column, "ovr", criteria)
111+
112+
def sl(self, column: str, criteria: str):
113+
return self.filter_in(column, "sl", criteria)
114+
115+
def sr(self, column: str, criteria: str):
116+
return self.filter_in(column, "sr", criteria)
117+
118+
def nxr(self, column: str, criteria: str):
119+
return self.filter_in(column, "nxr", criteria)
120+
121+
def nxl(self, column: str, criteria: str):
122+
return self.filter_in(column, "nxl", criteria)
123+
124+
def adj(self, column: str, criteria: str):
125+
return self.filter_in(column, "adj", criteria)
126+
127+
# def or_(self, column: str, criteria: str):
128+
# return self.filter_in(column, "or", criteria)
129+
34130

35131
class GetRequestBuilder(RequestBuilder):
36132
@classmethod
37-
def from_request_builder(cls, builder: RequestBuilder) -> GetRequestBuilder:
133+
def from_request_builder(cls, builder: RequestBuilder):
38134
result = cls(builder.session, builder.path)
39135
result.json = builder.json
40136
result.http_method = builder.http_method
41137
return result
42138

43-
def order(self, column: str, *, desc=False, nullsfirst=False) -> GetRequestBuilder:
139+
def order(self, column: str, *, desc=False, nullsfirst=False):
44140
self.session.params[
45141
"order"
46142
] = f"{column}{'.desc' if desc else ''}{'.nullsfirst' if nullsfirst else ''}"
47143
return self
48144

49-
def limit(self, size: int, *, start=0) -> GetRequestBuilder:
145+
def limit(self, size: int, *, start=0):
50146
self.session.headers["Range-Unit"] = "items"
51147
self.session.headers["Range"] = f"{start}-{start + size - 1}"
52148
return self
53149

54-
def range(self, start: int, end: int) -> GetRequestBuilder:
150+
def range(self, start: int, end: int):
55151
self.session.headers["Range-Unit"] = "items"
56152
self.session.headers["Range"] = f"{start}-{end - 1}"
57153
return self
58154

59-
def single(self) -> GetRequestBuilder:
155+
def single(self):
60156
self.session.headers["Accept"] = "application/vnd.pgrst.object+json"
61157
return self

0 commit comments

Comments
 (0)