polars-api 0.1.4__tar.gz → 0.1.6__tar.gz

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.
@@ -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,329 @@
1
+ import asyncio
2
+ from typing import Optional
3
+
4
+ import httpx
5
+ import nest_asyncio
6
+ import polars as pl
7
+
8
+
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
+ """
23
+ return status_code >= 200 and status_code < 300
24
+
25
+
26
+ @pl.api.register_expr_namespace("api")
27
+ class Api:
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
+ """
37
+ self._url = url
38
+
39
+ @staticmethod
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):
60
+ return result.text
61
+ else:
62
+ return None
63
+
64
+ @staticmethod
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):
87
+ return result.text
88
+ else:
89
+ return None
90
+
91
+ @staticmethod
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
+ """
110
+ async with httpx.AsyncClient() as client:
111
+ r = await client.get(url, params=params, timeout=timeout)
112
+ return r.text
113
+
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)])
133
+
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)))
153
+
154
+ @staticmethod
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
+ """
175
+ async with httpx.AsyncClient() as client:
176
+ r = await client.post(url, params=params, json=body, timeout=timeout)
177
+ return r.text
178
+
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
+ """
199
+ return await asyncio.gather(*[
200
+ self._apost_one(url, _params, _body, timeout) for url, _params, _body in zip(x, params, body)
201
+ ])
202
+
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.
235
+
236
+ Returns
237
+ -------
238
+ pl.Expr
239
+ Expression containing the response texts.
240
+ """
241
+ if params is None:
242
+ params = pl.lit(None)
243
+ return pl.struct(self._url.alias("url"), params.alias("params")).map_elements(
244
+ lambda x: self._get(x["url"], params=x["params"], timeout=timeout),
245
+ return_dtype=pl.Utf8,
246
+ )
247
+
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
+ """
268
+ if params is None:
269
+ params = pl.lit(None)
270
+ if body is None:
271
+ body = pl.lit(None)
272
+ return pl.struct(self._url.alias("url"), params.alias("params"), body.alias("body")).map_elements(
273
+ lambda x: self._post(x["url"], params=x["params"], body=x["body"], timeout=timeout),
274
+ return_dtype=pl.Utf8,
275
+ )
276
+
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()
294
+ if params is None:
295
+ params = pl.lit(None)
296
+ return pl.struct(self._url.alias("url"), params.alias("params")).map_batches(
297
+ lambda x: self._aget(x.struct.field("url"), params=x.struct.field("params"), timeout=timeout)
298
+ )
299
+
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()
321
+ if params is None:
322
+ params = pl.lit(None)
323
+ if body is None:
324
+ body = pl.lit(None)
325
+ return pl.struct(self._url.alias("url"), params.alias("params"), body.alias("body")).map_batches(
326
+ lambda x: self._apost(
327
+ x.struct.field("url"), params=x.struct.field("params"), body=x.struct.field("body"), timeout=timeout
328
+ )
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,3 @@
1
+ httpx>=0.28.1
2
+ nest-asyncio>=1.6.0
3
+ polars>=1.0.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "polars-api"
3
- version = "0.1.4"
3
+ version = "0.1.6"
4
4
  description = "Polars extension for dealing with REST APIs"
5
5
  authors = [{ name = "Diego Garcia Lozano", email = "diegoglozano96@gmail.com" }]
6
6
  readme = "README.md"
@@ -19,7 +19,8 @@ classifiers = [
19
19
  ]
20
20
  dependencies = [
21
21
  "httpx>=0.28.1",
22
- "polars>=1.19.0",
22
+ "nest-asyncio>=1.6.0",
23
+ "polars>=1.0.0",
23
24
  ]
24
25
 
25
26
  [project.urls]
@@ -1,91 +0,0 @@
1
- import asyncio
2
- from typing import Optional
3
-
4
- import httpx
5
- import polars as pl
6
-
7
-
8
- def check_status_code(status_code):
9
- return status_code >= 200 and status_code < 300
10
-
11
-
12
- @pl.api.register_expr_namespace("api")
13
- class Api:
14
- def __init__(self, url: pl.Expr) -> None:
15
- self._url = url
16
-
17
- @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):
21
- return result.text
22
- else:
23
- return None
24
-
25
- @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):
29
- return result.text
30
- else:
31
- return None
32
-
33
- @staticmethod
34
- async def _aget_one(url: str, params: str) -> str:
35
- async with httpx.AsyncClient() as client:
36
- r = await client.get(url, params=params)
37
- return r.text
38
-
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)])
41
-
42
- def _aget(self, x, params):
43
- return pl.Series(asyncio.run(self._aget_all(x, params)))
44
-
45
- @staticmethod
46
- async def _apost_one(url: str, params: str, body: str) -> str:
47
- async with httpx.AsyncClient() as client:
48
- r = await client.post(url, params=params, json=body)
49
- return r.text
50
-
51
- async def _apost_all(self, x, params, body):
52
- return await asyncio.gather(*[
53
- self._apost_one(url, _params, _body) for url, _params, _body in zip(x, params, body)
54
- ])
55
-
56
- def _apost(self, x, params, body):
57
- return pl.Series(asyncio.run(self._apost_all(x, params, body)))
58
-
59
- def get(self, params: Optional[pl.Expr] = None) -> pl.Expr:
60
- if params is None:
61
- params = pl.lit(None)
62
- return pl.struct(self._url.alias("url"), params.alias("params")).map_elements(
63
- lambda x: self._get(x["url"], params=x["params"]),
64
- return_dtype=pl.Utf8,
65
- )
66
-
67
- def post(self, params: Optional[pl.Expr] = None, body: Optional[pl.Expr] = None) -> pl.Expr:
68
- if params is None:
69
- params = pl.lit(None)
70
- if body is None:
71
- body = pl.lit(None)
72
- 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"]),
74
- return_dtype=pl.Utf8,
75
- )
76
-
77
- def aget(self, params: Optional[pl.Expr] = None) -> pl.Expr:
78
- if params is None:
79
- params = pl.lit(None)
80
- 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"))
82
- )
83
-
84
- def apost(self, params: Optional[pl.Expr] = None, body: Optional[pl.Expr] = None) -> pl.Expr:
85
- if params is None:
86
- params = pl.lit(None)
87
- if body is None:
88
- body = pl.lit(None)
89
- 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"))
91
- )
@@ -1,2 +0,0 @@
1
- httpx>=0.28.1
2
- polars>=1.19.0
File without changes
File without changes
File without changes
File without changes
File without changes