rapid-api-client 0.7.2__tar.gz → 0.7.4__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.3
2
2
  Name: rapid-api-client
3
- Version: 0.7.2
3
+ Version: 0.7.4
4
4
  Summary: Rapidly develop your API clients using decorators and annotations
5
5
  Author: Sébastien MB
6
6
  Author-email: seb@essembeh.org
@@ -27,8 +27,8 @@ Classifier: Topic :: Software Development :: Libraries
27
27
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
28
28
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
29
29
  Classifier: Typing :: Typed
30
- Requires-Dist: httpx (>=0.28.1,<0.29.0)
31
- Requires-Dist: pydantic (>=2.9.2,<3.0.0)
30
+ Requires-Dist: httpx (==0.*)
31
+ Requires-Dist: pydantic (==2.*)
32
32
  Project-URL: Homepage, https://github.com/essembeh/rapid-api-client
33
33
  Project-URL: Issues, https://github.com/essembeh/rapid-api-client/issues
34
34
  Project-URL: Repository, https://github.com/essembeh/rapid-api-client
@@ -3,7 +3,7 @@ name = "rapid-api-client"
3
3
 
4
4
  [tool.poetry]
5
5
  name = "rapid-api-client"
6
- version = "0.7.2"
6
+ version = "0.7.4"
7
7
  description = "Rapidly develop your API clients using decorators and annotations"
8
8
  authors = ["Sébastien MB <seb@essembeh.org>"]
9
9
  readme = "README.md"
@@ -38,8 +38,8 @@ Issues = "https://github.com/essembeh/rapid-api-client/issues"
38
38
 
39
39
  [tool.poetry.dependencies]
40
40
  python = "^3.11"
41
- pydantic = "^2.9.2"
42
- httpx = "^0.28.1"
41
+ pydantic = "2.*"
42
+ httpx = "0.*"
43
43
 
44
44
  [tool.poetry.group.dev.dependencies]
45
45
  pytest = "*"
@@ -0,0 +1,96 @@
1
+ """
2
+ Client classes for the rapid-api-client library.
3
+
4
+ This module provides the core classes for building API clients:
5
+ - RapidApi: Base class for API clients
6
+ - ParameterManager: Manages parameters for API requests
7
+ - RapidParameter: Represents a function parameter with its annotation
8
+
9
+ These classes handle the extraction of parameters from function signatures,
10
+ the resolution of path templates, and the building of HTTP requests.
11
+ They work together with the decorator module to provide a declarative way
12
+ to define API clients.
13
+ """
14
+
15
+ from typing import (
16
+ Any,
17
+ Dict,
18
+ )
19
+
20
+ from httpx import AsyncClient, Client
21
+
22
+
23
+ class RapidApi:
24
+ """
25
+ Base class for API clients.
26
+
27
+ This class represents an API client. Subclasses should define methods
28
+ decorated with @http (or @get, @post, etc.) which represent API endpoints.
29
+
30
+ Example:
31
+ >>> from rapid_api_client import RapidApi, get, post
32
+ >>> from typing import Annotated
33
+ >>>
34
+ >>> class MyApi(RapidApi):
35
+ ... @get("/users/{user_id}")
36
+ ... def get_user(self, user_id: Annotated[int, Path()]): ...
37
+ ...
38
+ ... @post("/users")
39
+ ... def create_user(self, user: Annotated[dict, JsonBody()]): ...
40
+ >>>
41
+ >>> api = MyApi(base_url="https://api.example.com")
42
+ >>> user = api.get_user(123)
43
+ """
44
+
45
+ def __init__(
46
+ self,
47
+ *,
48
+ client: Client | None = None,
49
+ async_client: AsyncClient | None = None,
50
+ **kwargs: Any,
51
+ ) -> None:
52
+ """
53
+ Initialize a RapidApi instance.
54
+
55
+ Args:
56
+ client: An existing httpx.Client instance to use for synchronous requests
57
+ async_client: An existing httpx.AsyncClient instance to use for asynchronous requests
58
+ **kwargs: Additional arguments to pass to the httpx.Client and httpx.AsyncClient
59
+ constructors when creating new clients. Common arguments include:
60
+ - base_url: The base URL for the API
61
+ - headers: Default headers to include in all requests
62
+ - timeout: Default timeout for requests
63
+ """
64
+ self._client: Client | None = client
65
+ self._async_client: AsyncClient | None = async_client
66
+ self.client_factory_args: Dict[str, Any] = kwargs
67
+
68
+ @property
69
+ def client(self) -> Client:
70
+ """
71
+ Get the synchronous HTTP client.
72
+
73
+ If no client was provided in the constructor, a new one is created
74
+ using the arguments provided in the constructor.
75
+
76
+ Returns:
77
+ The httpx.Client instance for making synchronous requests
78
+ """
79
+ if self._client is None:
80
+ self._client = Client(**self.client_factory_args)
81
+ return self._client
82
+
83
+ @property
84
+ def async_client(self) -> AsyncClient:
85
+ """
86
+ Get the asynchronous HTTP client.
87
+
88
+ If no async client was provided in the constructor, a new one is created
89
+ using the arguments provided in the constructor.
90
+
91
+ Returns:
92
+ The httpx.AsyncClient instance for making asynchronous requests
93
+ """
94
+ if self._async_client is None:
95
+ self._async_client = AsyncClient(**self.client_factory_args)
96
+ return self._async_client
@@ -17,11 +17,12 @@ sending the requests, and processing the responses.
17
17
  import inspect
18
18
  from functools import partial, wraps
19
19
  from inspect import signature
20
- from typing import Any, Dict, Type
20
+ from typing import Any, Callable, Dict, Optional, Type
21
21
 
22
- from httpx import Response
22
+ from httpx import Request, Response
23
23
 
24
- from .client import ParameterManager, RapidApi
24
+ from .client import RapidApi
25
+ from .parameters import ParameterManager
25
26
  from .utils import process_response
26
27
 
27
28
 
@@ -31,6 +32,7 @@ def http(
31
32
  timeout: float | None = None,
32
33
  headers: Dict[str, str] | None = None,
33
34
  raise_for_status: bool = True,
35
+ request_tweaker: Optional[Callable[[Request], Request]] = None,
34
36
  ) -> Any:
35
37
  """
36
38
  Main decorator used to generate an HTTP request and return its result.
@@ -49,6 +51,7 @@ def http(
49
51
  timeout: Optional timeout for the request in seconds
50
52
  headers: Optional additional headers to include in the request
51
53
  raise_for_status: Whether to raise an exception for non-2xx status codes
54
+ request_tweaker: An optional function to modify the built request before sending it
52
55
 
53
56
  Returns:
54
57
  A decorator function that wraps the API endpoint method
@@ -95,11 +98,15 @@ def http(
95
98
  for k, v in headers.items():
96
99
  build_kwargs["headers"].setdefault(k, v)
97
100
 
98
- return (
101
+ out = (
99
102
  api.async_client.build_request(method, resolved_path, **build_kwargs)
100
103
  if is_async
101
104
  else api.client.build_request(method, resolved_path, **build_kwargs)
102
105
  )
106
+ # If a request tweaker is given, apply it
107
+ if request_tweaker is not None:
108
+ out = request_tweaker(out)
109
+ return out
103
110
 
104
111
  @wraps(func)
105
112
  async def async_wrapper(api: RapidApi, *args, **kwargs):
@@ -23,7 +23,6 @@ from typing import (
23
23
  Tuple,
24
24
  )
25
25
 
26
- from httpx import AsyncClient, Client
27
26
  from pydantic import BaseModel, TypeAdapter
28
27
  from pydantic_core import PydanticUndefined
29
28
 
@@ -310,79 +309,3 @@ class ParameterManager:
310
309
  return "content", value
311
310
 
312
311
  return (None, None)
313
-
314
-
315
- class RapidApi:
316
- """
317
- Base class for API clients.
318
-
319
- This class represents an API client. Subclasses should define methods
320
- decorated with @http (or @get, @post, etc.) which represent API endpoints.
321
-
322
- Example:
323
- >>> from rapid_api_client import RapidApi, get, post
324
- >>> from typing import Annotated
325
- >>>
326
- >>> class MyApi(RapidApi):
327
- ... @get("/users/{user_id}")
328
- ... def get_user(self, user_id: Annotated[int, Path()]): ...
329
- ...
330
- ... @post("/users")
331
- ... def create_user(self, user: Annotated[dict, JsonBody()]): ...
332
- >>>
333
- >>> api = MyApi(base_url="https://api.example.com")
334
- >>> user = api.get_user(123)
335
- """
336
-
337
- def __init__(
338
- self,
339
- *,
340
- client: Client | None = None,
341
- async_client: AsyncClient | None = None,
342
- **kwargs: Any,
343
- ) -> None:
344
- """
345
- Initialize a RapidApi instance.
346
-
347
- Args:
348
- client: An existing httpx.Client instance to use for synchronous requests
349
- async_client: An existing httpx.AsyncClient instance to use for asynchronous requests
350
- **kwargs: Additional arguments to pass to the httpx.Client and httpx.AsyncClient
351
- constructors when creating new clients. Common arguments include:
352
- - base_url: The base URL for the API
353
- - headers: Default headers to include in all requests
354
- - timeout: Default timeout for requests
355
- """
356
- self._client: Client | None = client
357
- self._async_client: AsyncClient | None = async_client
358
- self.client_factory_args: Dict[str, Any] = kwargs
359
-
360
- @property
361
- def client(self) -> Client:
362
- """
363
- Get the synchronous HTTP client.
364
-
365
- If no client was provided in the constructor, a new one is created
366
- using the arguments provided in the constructor.
367
-
368
- Returns:
369
- The httpx.Client instance for making synchronous requests
370
- """
371
- if self._client is None:
372
- self._client = Client(**self.client_factory_args)
373
- return self._client
374
-
375
- @property
376
- def async_client(self) -> AsyncClient:
377
- """
378
- Get the asynchronous HTTP client.
379
-
380
- If no async client was provided in the constructor, a new one is created
381
- using the arguments provided in the constructor.
382
-
383
- Returns:
384
- The httpx.AsyncClient instance for making asynchronous requests
385
- """
386
- if self._async_client is None:
387
- self._async_client = AsyncClient(**self.client_factory_args)
388
- return self._async_client