polars-api 0.1.5__py3-none-any.whl → 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- polars_api/api.py +235 -3
- {polars_api-0.1.5.dist-info → polars_api-0.1.6.dist-info}/METADATA +3 -2
- polars_api-0.1.6.dist-info/RECORD +9 -0
- polars_api-0.1.5.dist-info/RECORD +0 -9
- {polars_api-0.1.5.dist-info → polars_api-0.1.6.dist-info}/LICENSE +0 -0
- {polars_api-0.1.5.dist-info → polars_api-0.1.6.dist-info}/WHEEL +0 -0
- {polars_api-0.1.5.dist-info → polars_api-0.1.6.dist-info}/top_level.txt +0 -0
polars_api/api.py
CHANGED
@@ -2,61 +2,242 @@ import asyncio
|
|
2
2
|
from typing import Optional
|
3
3
|
|
4
4
|
import httpx
|
5
|
+
import nest_asyncio
|
5
6
|
import polars as pl
|
6
7
|
|
7
8
|
|
8
|
-
def
|
9
|
+
def _check_status_code(status_code):
|
10
|
+
"""
|
11
|
+
Check if the status code indicates a successful response.
|
12
|
+
|
13
|
+
Parameters
|
14
|
+
----------
|
15
|
+
status_code : int
|
16
|
+
The HTTP status code to check.
|
17
|
+
|
18
|
+
Returns
|
19
|
+
-------
|
20
|
+
bool
|
21
|
+
True if the status code is between 200 and 299, False otherwise.
|
22
|
+
"""
|
9
23
|
return status_code >= 200 and status_code < 300
|
10
24
|
|
11
25
|
|
12
26
|
@pl.api.register_expr_namespace("api")
|
13
27
|
class Api:
|
14
28
|
def __init__(self, url: pl.Expr) -> None:
|
29
|
+
"""
|
30
|
+
Initialize the Api class with a URL expression.
|
31
|
+
|
32
|
+
Parameters
|
33
|
+
----------
|
34
|
+
url : pl.Expr
|
35
|
+
The URL expression.
|
36
|
+
"""
|
15
37
|
self._url = url
|
16
38
|
|
17
39
|
@staticmethod
|
18
40
|
def _get(url: str, params: Optional[dict[str, str]] = None, timeout: Optional[float] = None) -> Optional[str]:
|
41
|
+
"""
|
42
|
+
Perform a synchronous GET request.
|
43
|
+
|
44
|
+
Parameters
|
45
|
+
----------
|
46
|
+
url : str
|
47
|
+
The URL to send the GET request to.
|
48
|
+
params : dict[str, str], optional
|
49
|
+
The query parameters to include in the request.
|
50
|
+
timeout : float, optional
|
51
|
+
The timeout for the request.
|
52
|
+
|
53
|
+
Returns
|
54
|
+
-------
|
55
|
+
str or None
|
56
|
+
The response text if the request is successful, None otherwise.
|
57
|
+
"""
|
19
58
|
result = httpx.get(url, params=params, timeout=timeout)
|
20
|
-
if
|
59
|
+
if _check_status_code(result.status_code):
|
21
60
|
return result.text
|
22
61
|
else:
|
23
62
|
return None
|
24
63
|
|
25
64
|
@staticmethod
|
26
65
|
def _post(url: str, params: dict[str, str], body: str, timeout: float) -> Optional[str]:
|
66
|
+
"""
|
67
|
+
Perform a synchronous POST request.
|
68
|
+
|
69
|
+
Parameters
|
70
|
+
----------
|
71
|
+
url : str
|
72
|
+
The URL to send the POST request to.
|
73
|
+
params : dict[str, str]
|
74
|
+
The query parameters to include in the request.
|
75
|
+
body : str
|
76
|
+
The JSON body to include in the request.
|
77
|
+
timeout : float
|
78
|
+
The timeout for the request.
|
79
|
+
|
80
|
+
Returns
|
81
|
+
-------
|
82
|
+
str or None
|
83
|
+
The response text if the request is successful, None otherwise.
|
84
|
+
"""
|
27
85
|
result = httpx.post(url, params=params, json=body, timeout=timeout)
|
28
|
-
if
|
86
|
+
if _check_status_code(result.status_code):
|
29
87
|
return result.text
|
30
88
|
else:
|
31
89
|
return None
|
32
90
|
|
33
91
|
@staticmethod
|
34
92
|
async def _aget_one(url: str, params: str, timeout: float) -> str:
|
93
|
+
"""
|
94
|
+
Perform an asynchronous GET request.
|
95
|
+
|
96
|
+
Parameters
|
97
|
+
----------
|
98
|
+
url : str
|
99
|
+
The URL to send the GET request to.
|
100
|
+
params : str
|
101
|
+
The query parameters to include in the request.
|
102
|
+
timeout : float
|
103
|
+
The timeout for the request.
|
104
|
+
|
105
|
+
Returns
|
106
|
+
-------
|
107
|
+
str
|
108
|
+
The response text.
|
109
|
+
"""
|
35
110
|
async with httpx.AsyncClient() as client:
|
36
111
|
r = await client.get(url, params=params, timeout=timeout)
|
37
112
|
return r.text
|
38
113
|
|
39
114
|
async def _aget_all(self, x, params, timeout):
|
115
|
+
"""
|
116
|
+
Perform multiple asynchronous GET requests.
|
117
|
+
|
118
|
+
Parameters
|
119
|
+
----------
|
120
|
+
x : list
|
121
|
+
List of URLs to send the GET requests to.
|
122
|
+
params : list
|
123
|
+
List of query parameters for each request.
|
124
|
+
timeout : float
|
125
|
+
The timeout for the requests.
|
126
|
+
|
127
|
+
Returns
|
128
|
+
-------
|
129
|
+
list
|
130
|
+
List of response texts.
|
131
|
+
"""
|
40
132
|
return await asyncio.gather(*[self._aget_one(url, param, timeout) for url, param in zip(x, params)])
|
41
133
|
|
42
134
|
def _aget(self, x, params, timeout):
|
135
|
+
"""
|
136
|
+
Wrapper for performing multiple asynchronous GET requests.
|
137
|
+
|
138
|
+
Parameters
|
139
|
+
----------
|
140
|
+
x : list
|
141
|
+
List of URLs to send the GET requests to.
|
142
|
+
params : list
|
143
|
+
List of query parameters for each request.
|
144
|
+
timeout : float
|
145
|
+
The timeout for the requests.
|
146
|
+
|
147
|
+
Returns
|
148
|
+
-------
|
149
|
+
pl.Series
|
150
|
+
Series of response texts.
|
151
|
+
"""
|
43
152
|
return pl.Series(asyncio.run(self._aget_all(x, params, timeout)))
|
44
153
|
|
45
154
|
@staticmethod
|
46
155
|
async def _apost_one(url: str, params: str, body: str, timeout: Optional[float]) -> str:
|
156
|
+
"""
|
157
|
+
Perform an asynchronous POST request.
|
158
|
+
|
159
|
+
Parameters
|
160
|
+
----------
|
161
|
+
url : str
|
162
|
+
The URL to send the POST request to.
|
163
|
+
params : str
|
164
|
+
The query parameters to include in the request.
|
165
|
+
body : str
|
166
|
+
The JSON body to include in the request.
|
167
|
+
timeout : float, optional
|
168
|
+
The timeout for the request.
|
169
|
+
|
170
|
+
Returns
|
171
|
+
-------
|
172
|
+
str
|
173
|
+
The response text.
|
174
|
+
"""
|
47
175
|
async with httpx.AsyncClient() as client:
|
48
176
|
r = await client.post(url, params=params, json=body, timeout=timeout)
|
49
177
|
return r.text
|
50
178
|
|
51
179
|
async def _apost_all(self, x, params, body, timeout):
|
180
|
+
"""
|
181
|
+
Perform multiple asynchronous POST requests.
|
182
|
+
|
183
|
+
Parameters
|
184
|
+
----------
|
185
|
+
x : list
|
186
|
+
List of URLs to send the POST requests to.
|
187
|
+
params : list
|
188
|
+
List of query parameters for each request.
|
189
|
+
body : list
|
190
|
+
List of JSON bodies for each request.
|
191
|
+
timeout : float
|
192
|
+
The timeout for the requests.
|
193
|
+
|
194
|
+
Returns
|
195
|
+
-------
|
196
|
+
list
|
197
|
+
List of response texts.
|
198
|
+
"""
|
52
199
|
return await asyncio.gather(*[
|
53
200
|
self._apost_one(url, _params, _body, timeout) for url, _params, _body in zip(x, params, body)
|
54
201
|
])
|
55
202
|
|
56
203
|
def _apost(self, x, params, body, timeout):
|
204
|
+
"""
|
205
|
+
Wrapper for performing multiple asynchronous POST requests.
|
206
|
+
|
207
|
+
Parameters
|
208
|
+
----------
|
209
|
+
x : list
|
210
|
+
List of URLs to send the POST requests to.
|
211
|
+
params : list
|
212
|
+
List of query parameters for each request.
|
213
|
+
body : list
|
214
|
+
List of JSON bodies for each request.
|
215
|
+
timeout : float
|
216
|
+
The timeout for the requests.
|
217
|
+
|
218
|
+
Returns
|
219
|
+
-------
|
220
|
+
pl.Series
|
221
|
+
Series of response texts.
|
222
|
+
"""
|
57
223
|
return pl.Series(asyncio.run(self._apost_all(x, params, body, timeout)))
|
58
224
|
|
59
225
|
def get(self, params: Optional[pl.Expr] = None, timeout: Optional[float] = None) -> pl.Expr:
|
226
|
+
"""
|
227
|
+
Perform a synchronous GET request for each URL in the expression.
|
228
|
+
|
229
|
+
Parameters
|
230
|
+
----------
|
231
|
+
params : pl.Expr, optional
|
232
|
+
The query parameters expression.
|
233
|
+
timeout : float, optional
|
234
|
+
The timeout for the requests.
|
235
|
+
|
236
|
+
Returns
|
237
|
+
-------
|
238
|
+
pl.Expr
|
239
|
+
Expression containing the response texts.
|
240
|
+
"""
|
60
241
|
if params is None:
|
61
242
|
params = pl.lit(None)
|
62
243
|
return pl.struct(self._url.alias("url"), params.alias("params")).map_elements(
|
@@ -67,6 +248,23 @@ class Api:
|
|
67
248
|
def post(
|
68
249
|
self, params: Optional[pl.Expr] = None, body: Optional[pl.Expr] = None, timeout: Optional[float] = None
|
69
250
|
) -> pl.Expr:
|
251
|
+
"""
|
252
|
+
Perform a synchronous POST request for each URL in the expression.
|
253
|
+
|
254
|
+
Parameters
|
255
|
+
----------
|
256
|
+
params : pl.Expr, optional
|
257
|
+
The query parameters expression.
|
258
|
+
body : pl.Expr, optional
|
259
|
+
The JSON body expression.
|
260
|
+
timeout : float, optional
|
261
|
+
The timeout for the requests.
|
262
|
+
|
263
|
+
Returns
|
264
|
+
-------
|
265
|
+
pl.Expr
|
266
|
+
Expression containing the response texts.
|
267
|
+
"""
|
70
268
|
if params is None:
|
71
269
|
params = pl.lit(None)
|
72
270
|
if body is None:
|
@@ -77,6 +275,22 @@ class Api:
|
|
77
275
|
)
|
78
276
|
|
79
277
|
def aget(self, params: Optional[pl.Expr] = None, timeout: Optional[float] = None) -> pl.Expr:
|
278
|
+
"""
|
279
|
+
Perform an asynchronous GET request for each URL in the expression.
|
280
|
+
|
281
|
+
Parameters
|
282
|
+
----------
|
283
|
+
params : pl.Expr, optional
|
284
|
+
The query parameters expression.
|
285
|
+
timeout : float, optional
|
286
|
+
The timeout for the requests.
|
287
|
+
|
288
|
+
Returns
|
289
|
+
-------
|
290
|
+
pl.Expr
|
291
|
+
Expression containing the response texts.
|
292
|
+
"""
|
293
|
+
nest_asyncio.apply()
|
80
294
|
if params is None:
|
81
295
|
params = pl.lit(None)
|
82
296
|
return pl.struct(self._url.alias("url"), params.alias("params")).map_batches(
|
@@ -86,6 +300,24 @@ class Api:
|
|
86
300
|
def apost(
|
87
301
|
self, params: Optional[pl.Expr] = None, body: Optional[pl.Expr] = None, timeout: Optional[float] = None
|
88
302
|
) -> pl.Expr:
|
303
|
+
"""
|
304
|
+
Perform an asynchronous POST request for each URL in the expression.
|
305
|
+
|
306
|
+
Parameters
|
307
|
+
----------
|
308
|
+
params : pl.Expr, optional
|
309
|
+
The query parameters expression.
|
310
|
+
body : pl.Expr, optional
|
311
|
+
The JSON body expression.
|
312
|
+
timeout : float, optional
|
313
|
+
The timeout for the requests.
|
314
|
+
|
315
|
+
Returns
|
316
|
+
-------
|
317
|
+
pl.Expr
|
318
|
+
Expression containing the response texts.
|
319
|
+
"""
|
320
|
+
nest_asyncio.apply()
|
89
321
|
if params is None:
|
90
322
|
params = pl.lit(None)
|
91
323
|
if body is None:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: polars-api
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.6
|
4
4
|
Summary: Polars extension for dealing with REST APIs
|
5
5
|
Author-email: Diego Garcia Lozano <diegoglozano96@gmail.com>
|
6
6
|
Project-URL: Homepage, https://diegoglozano.github.io/polars-api/
|
@@ -20,7 +20,8 @@ Requires-Python: <4.0,>=3.9
|
|
20
20
|
Description-Content-Type: text/markdown
|
21
21
|
License-File: LICENSE
|
22
22
|
Requires-Dist: httpx>=0.28.1
|
23
|
-
Requires-Dist:
|
23
|
+
Requires-Dist: nest-asyncio>=1.6.0
|
24
|
+
Requires-Dist: polars>=1.0.0
|
24
25
|
|
25
26
|
# polars-api
|
26
27
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
examples/test.py,sha256=e-4VmxKdfRJZ01UN_3IAyAdnENTDGSZsrhGzJOtHwh0,927
|
2
|
+
polars_api/__init__.py,sha256=JoRS_iy8pZLEz_ADKooXOqOPlUQcd5wvdcSa_PMuGLs,40
|
3
|
+
polars_api/api.py,sha256=Dd94nz5C7qCt_rmDZuwWh-xtMS1YvvBT0ptWyaIILvs,9811
|
4
|
+
tests/test_api.py,sha256=1OfyzFM1fUecl8TnY9CUkWt_zpUNgoIYnN_Ma9ZN77w,32
|
5
|
+
polars_api-0.1.6.dist-info/LICENSE,sha256=Ms_a-6jJtWdrIBCOaYS_hKFCODG2QXHcNgsQJnbujnA,1076
|
6
|
+
polars_api-0.1.6.dist-info/METADATA,sha256=kunT_W9Gz1eoShBIYnTgYPPcPPwJWB-F3sSJPuXUspE,3737
|
7
|
+
polars_api-0.1.6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
8
|
+
polars_api-0.1.6.dist-info/top_level.txt,sha256=irGgxpseyd3aPqxnvE54AITFumMlSLGg1O9-zg5Gpac,26
|
9
|
+
polars_api-0.1.6.dist-info/RECORD,,
|
@@ -1,9 +0,0 @@
|
|
1
|
-
examples/test.py,sha256=e-4VmxKdfRJZ01UN_3IAyAdnENTDGSZsrhGzJOtHwh0,927
|
2
|
-
polars_api/__init__.py,sha256=JoRS_iy8pZLEz_ADKooXOqOPlUQcd5wvdcSa_PMuGLs,40
|
3
|
-
polars_api/api.py,sha256=Pqfc7LJ3o4yx__s2JQ4lTwB12PjdtzImYvmO8pKxGOs,3830
|
4
|
-
tests/test_api.py,sha256=1OfyzFM1fUecl8TnY9CUkWt_zpUNgoIYnN_Ma9ZN77w,32
|
5
|
-
polars_api-0.1.5.dist-info/LICENSE,sha256=Ms_a-6jJtWdrIBCOaYS_hKFCODG2QXHcNgsQJnbujnA,1076
|
6
|
-
polars_api-0.1.5.dist-info/METADATA,sha256=eUtaFcZwWBXlcPc_sIpsQoTSi1YheIche_dxPVArs6M,3703
|
7
|
-
polars_api-0.1.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
8
|
-
polars_api-0.1.5.dist-info/top_level.txt,sha256=irGgxpseyd3aPqxnvE54AITFumMlSLGg1O9-zg5Gpac,26
|
9
|
-
polars_api-0.1.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|