polars-api 0.1.4__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 CHANGED
@@ -2,90 +2,328 @@ 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 check_status_code(status_code):
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
- def _get(url: str, params: Optional[dict[str, str]] = None) -> Optional[str]:
19
- result = httpx.get(url, params=params)
20
- if check_status_code(result.status_code):
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
+ """
58
+ result = httpx.get(url, params=params, timeout=timeout)
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
- def _post(url: str, params: dict[str, str], body: str) -> Optional[str]:
27
- result = httpx.post(url, params=params, json=body)
28
- if check_status_code(result.status_code):
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
+ """
85
+ result = httpx.post(url, params=params, json=body, timeout=timeout)
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
- async def _aget_one(url: str, params: str) -> str:
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
- r = await client.get(url, params=params)
111
+ r = await client.get(url, params=params, timeout=timeout)
37
112
  return r.text
38
113
 
39
- async def _aget_all(self, x, params):
40
- return await asyncio.gather(*[self._aget_one(url, param) for url, param in zip(x, params)])
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
+ """
132
+ return await asyncio.gather(*[self._aget_one(url, param, timeout) for url, param in zip(x, params)])
41
133
 
42
- def _aget(self, x, params):
43
- return pl.Series(asyncio.run(self._aget_all(x, params)))
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
+ """
152
+ return pl.Series(asyncio.run(self._aget_all(x, params, timeout)))
44
153
 
45
154
  @staticmethod
46
- async def _apost_one(url: str, params: str, body: str) -> str:
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
- r = await client.post(url, params=params, json=body)
176
+ r = await client.post(url, params=params, json=body, timeout=timeout)
49
177
  return r.text
50
178
 
51
- async def _apost_all(self, x, params, body):
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
- self._apost_one(url, _params, _body) for url, _params, _body in zip(x, params, body)
200
+ self._apost_one(url, _params, _body, timeout) for url, _params, _body in zip(x, params, body)
54
201
  ])
55
202
 
56
- def _apost(self, x, params, body):
57
- return pl.Series(asyncio.run(self._apost_all(x, params, body)))
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
+ """
223
+ return pl.Series(asyncio.run(self._apost_all(x, params, body, timeout)))
224
+
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.
58
235
 
59
- def get(self, params: Optional[pl.Expr] = None) -> pl.Expr:
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(
63
- lambda x: self._get(x["url"], params=x["params"]),
244
+ lambda x: self._get(x["url"], params=x["params"], timeout=timeout),
64
245
  return_dtype=pl.Utf8,
65
246
  )
66
247
 
67
- def post(self, params: Optional[pl.Expr] = None, body: Optional[pl.Expr] = None) -> pl.Expr:
248
+ def post(
249
+ self, params: Optional[pl.Expr] = None, body: Optional[pl.Expr] = None, timeout: Optional[float] = None
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
+ """
68
268
  if params is None:
69
269
  params = pl.lit(None)
70
270
  if body is None:
71
271
  body = pl.lit(None)
72
272
  return pl.struct(self._url.alias("url"), params.alias("params"), body.alias("body")).map_elements(
73
- lambda x: self._post(x["url"], params=x["params"], body=x["body"]),
273
+ lambda x: self._post(x["url"], params=x["params"], body=x["body"], timeout=timeout),
74
274
  return_dtype=pl.Utf8,
75
275
  )
76
276
 
77
- def aget(self, params: Optional[pl.Expr] = None) -> pl.Expr:
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()
78
294
  if params is None:
79
295
  params = pl.lit(None)
80
296
  return pl.struct(self._url.alias("url"), params.alias("params")).map_batches(
81
- lambda x: self._aget(x.struct.field("url"), params=x.struct.field("params"))
297
+ lambda x: self._aget(x.struct.field("url"), params=x.struct.field("params"), timeout=timeout)
82
298
  )
83
299
 
84
- def apost(self, params: Optional[pl.Expr] = None, body: Optional[pl.Expr] = None) -> pl.Expr:
300
+ def apost(
301
+ self, params: Optional[pl.Expr] = None, body: Optional[pl.Expr] = None, timeout: Optional[float] = None
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()
85
321
  if params is None:
86
322
  params = pl.lit(None)
87
323
  if body is None:
88
324
  body = pl.lit(None)
89
325
  return pl.struct(self._url.alias("url"), params.alias("params"), body.alias("body")).map_batches(
90
- lambda x: self._apost(x.struct.field("url"), params=x.struct.field("params"), body=x.struct.field("body"))
326
+ lambda x: self._apost(
327
+ x.struct.field("url"), params=x.struct.field("params"), body=x.struct.field("body"), timeout=timeout
328
+ )
91
329
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: polars-api
3
- Version: 0.1.4
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: polars>=1.19.0
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=XjGJu4Hhg_7aN_FmMqeH953sD7V1l1OS2F5JcNKJBaY,3341
4
- tests/test_api.py,sha256=1OfyzFM1fUecl8TnY9CUkWt_zpUNgoIYnN_Ma9ZN77w,32
5
- polars_api-0.1.4.dist-info/LICENSE,sha256=Ms_a-6jJtWdrIBCOaYS_hKFCODG2QXHcNgsQJnbujnA,1076
6
- polars_api-0.1.4.dist-info/METADATA,sha256=8Vra2wJdHNE-h1MgOI8rNTUmT9pFDOD9VyRbyKaFp8U,3703
7
- polars_api-0.1.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
- polars_api-0.1.4.dist-info/top_level.txt,sha256=irGgxpseyd3aPqxnvE54AITFumMlSLGg1O9-zg5Gpac,26
9
- polars_api-0.1.4.dist-info/RECORD,,