httpr 0.1.0__cp39-abi3-win_amd64.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.

Potentially problematic release.


This version of httpr might be problematic. Click here for more details.

httpr/__init__.py ADDED
@@ -0,0 +1,205 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import sys
5
+ from functools import partial
6
+ from typing import TYPE_CHECKING, TypedDict
7
+
8
+ if sys.version_info <= (3, 11):
9
+ from typing_extensions import Unpack
10
+ else:
11
+ from typing import Unpack
12
+
13
+
14
+ from .httpr import RClient
15
+
16
+ if TYPE_CHECKING:
17
+ from .httpr import ClientRequestParams, HttpMethod, RequestParams, Response
18
+ else:
19
+
20
+ class _Unpack:
21
+ @staticmethod
22
+ def __getitem__(*args, **kwargs):
23
+ pass
24
+
25
+ Unpack = _Unpack()
26
+ RequestParams = ClientRequestParams = TypedDict
27
+
28
+
29
+ class Client(RClient):
30
+ """Initializes an HTTP client"""
31
+
32
+ def __init__(
33
+ self,
34
+ auth: tuple[str, str | None] | None = None,
35
+ auth_bearer: str | None = None,
36
+ params: dict[str, str] | None = None,
37
+ headers: dict[str, str] | None = None,
38
+ cookies: dict[str, str] | None = None,
39
+ cookie_store: bool | None = True,
40
+ referer: bool | None = True,
41
+ proxy: str | None = None,
42
+ timeout: float | None = 30,
43
+ follow_redirects: bool | None = True,
44
+ max_redirects: int | None = 20,
45
+ verify: bool | None = True,
46
+ ca_cert_file: str | None = None,
47
+ client_pem: str | None = None,
48
+ https_only: bool | None = False,
49
+ # http2_only: bool | None = False,
50
+ ):
51
+ """
52
+ Args:
53
+ auth: a tuple containing the username and an optional password for basic authentication. Default is None.
54
+ auth_bearer: a string representing the bearer token for bearer token authentication. Default is None.
55
+ params: a map of query parameters to append to the URL. Default is None.
56
+ headers: an optional map of HTTP headers to send with requests.
57
+ cookies: an optional map of cookies to send with requests as the `Cookie` header.
58
+ cookie_store: enable a persistent cookie store. Received cookies will be preserved and included
59
+ in additional requests. Default is True.
60
+ referer: automatic setting of the `Referer` header. Default is True.
61
+ proxy: proxy URL for HTTP requests, example: "socks5://127.0.0.1:9150". Default is None.
62
+ timeout: timeout for HTTP requests in seconds. Default is 30.
63
+ follow_redirects: a boolean to enable or disable following redirects. Default is True.
64
+ max_redirects: the maximum number of redirects if `follow_redirects` is True. Default is 20.
65
+ verify: an optional boolean indicating whether to verify SSL certificates. Default is True.
66
+ ca_cert_file: path to CA certificate store. Default is None.
67
+ client_pem: path to client certificate file. Default is None.
68
+ https_only: restrict the Client to be used with HTTPS only requests. Default is False.
69
+ http2_only: if true - use only HTTP/2, if false - use only HTTP/1. Default is False.
70
+ """
71
+ super().__init__()
72
+
73
+ def __enter__(self) -> Client:
74
+ return self
75
+
76
+ def __exit__(self, *args):
77
+ del self
78
+
79
+ def request(self, method: HttpMethod, url: str, **kwargs: Unpack[RequestParams]) -> Response:
80
+ # Validate the HTTP method. Raise an exception if it's not supported.
81
+ if method not in ["GET", "HEAD", "OPTIONS", "DELETE", "POST", "PUT", "PATCH"]:
82
+ raise ValueError(f"Unsupported HTTP method: {method}")
83
+ return super().request(method=method, url=url, **kwargs)
84
+
85
+ def get(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
86
+ return self.request(method="GET", url=url, **kwargs)
87
+
88
+ def head(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
89
+ return self.request(method="HEAD", url=url, **kwargs)
90
+
91
+ def options(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
92
+ return self.request(method="OPTIONS", url=url, **kwargs)
93
+
94
+ def delete(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
95
+ return self.request(method="DELETE", url=url, **kwargs)
96
+
97
+ def post(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
98
+ return self.request(method="POST", url=url, **kwargs)
99
+
100
+ def put(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
101
+ return self.request(method="PUT", url=url, **kwargs)
102
+
103
+ def patch(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
104
+ return self.request(method="PATCH", url=url, **kwargs)
105
+
106
+
107
+ class AsyncClient(Client):
108
+ def __init__(self, *args, **kwargs):
109
+ super().__init__(*args, **kwargs)
110
+
111
+ async def __aenter__(self) -> AsyncClient:
112
+ return self
113
+
114
+ async def __aexit__(self, *args):
115
+ del self
116
+
117
+ async def _run_sync_asyncio(self, fn, *args, **kwargs):
118
+ loop = asyncio.get_running_loop()
119
+ return await loop.run_in_executor(None, partial(fn, *args, **kwargs))
120
+
121
+ async def request(self, method: HttpMethod, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
122
+ return await self._run_sync_asyncio(super().request, method=method, url=url, **kwargs)
123
+
124
+ async def get(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
125
+ return await self.request(method="GET", url=url, **kwargs)
126
+
127
+ async def head(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
128
+ return await self.request(method="HEAD", url=url, **kwargs)
129
+
130
+ async def options(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
131
+ return await self.request(method="OPTIONS", url=url, **kwargs)
132
+
133
+ async def delete(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
134
+ return await self.request(method="DELETE", url=url, **kwargs)
135
+
136
+ async def post(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
137
+ return await self.request(method="POST", url=url, **kwargs)
138
+
139
+ async def put(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
140
+ return await self.request(method="PUT", url=url, **kwargs)
141
+
142
+ async def patch(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
143
+ return await self.request(method="PATCH", url=url, **kwargs)
144
+
145
+
146
+ def request(
147
+ method: HttpMethod,
148
+ url: str,
149
+ verify: bool | None = True,
150
+ ca_cert_file: str | None = None,
151
+ client_pem: str | None = None,
152
+ **kwargs: Unpack[RequestParams],
153
+ ):
154
+ """
155
+ Args:
156
+ method: the HTTP method to use (e.g., "GET", "POST").
157
+ url: the URL to which the request will be made.
158
+ verify: an optional boolean indicating whether to verify SSL certificates. Default is True.
159
+ ca_cert_file: path to CA certificate store. Default is None.
160
+ client_pem: path to client certificate file. Default is None.
161
+ auth: a tuple containing the username and an optional password for basic authentication. Default is None.
162
+ auth_bearer: a string representing the bearer token for bearer token authentication. Default is None.
163
+ params: a map of query parameters to append to the URL. Default is None.
164
+ headers: an optional map of HTTP headers to send with requests. If `impersonate` is set, this will be ignored.
165
+ cookies: an optional map of cookies to send with requests as the `Cookie` header.
166
+ timeout: the timeout for the request in seconds. Default is 30.
167
+ content: the content to send in the request body as bytes. Default is None.
168
+ data: the form data to send in the request body. Default is None.
169
+ json: a JSON serializable object to send in the request body. Default is None.
170
+ files: a map of file fields to file paths to be sent as multipart/form-data. Default is None.
171
+ """
172
+ with Client(
173
+ verify=verify,
174
+ ca_cert_file=ca_cert_file,
175
+ client_pem=client_pem,
176
+ ) as client:
177
+ return client.request(method, url, **kwargs)
178
+
179
+
180
+ def get(url: str, **kwargs: Unpack[ClientRequestParams]):
181
+ return request(method="GET", url=url, **kwargs)
182
+
183
+
184
+ def head(url: str, **kwargs: Unpack[ClientRequestParams]):
185
+ return request(method="HEAD", url=url, **kwargs)
186
+
187
+
188
+ def options(url: str, **kwargs: Unpack[ClientRequestParams]):
189
+ return request(method="OPTIONS", url=url, **kwargs)
190
+
191
+
192
+ def delete(url: str, **kwargs: Unpack[ClientRequestParams]):
193
+ return request(method="DELETE", url=url, **kwargs)
194
+
195
+
196
+ def post(url: str, **kwargs: Unpack[ClientRequestParams]):
197
+ return request(method="POST", url=url, **kwargs)
198
+
199
+
200
+ def put(url: str, **kwargs: Unpack[ClientRequestParams]):
201
+ return request(method="PUT", url=url, **kwargs)
202
+
203
+
204
+ def patch(url: str, **kwargs: Unpack[ClientRequestParams]):
205
+ return request(method="PATCH", url=url, **kwargs)
httpr/httpr.pyd ADDED
Binary file
httpr/httpr.pyi ADDED
@@ -0,0 +1,101 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ from typing import Any, Literal, TypedDict
5
+
6
+ if sys.version_info <= (3, 11):
7
+ from typing_extensions import Unpack
8
+ else:
9
+ from typing import Unpack
10
+
11
+ HttpMethod = Literal["GET", "HEAD", "OPTIONS", "DELETE", "POST", "PUT", "PATCH"]
12
+
13
+ class RequestParams(TypedDict, total=False):
14
+ auth: tuple[str, str | None] | None
15
+ auth_bearer: str | None
16
+ params: dict[str, str] | None
17
+ headers: dict[str, str] | None
18
+ cookies: dict[str, str] | None
19
+ timeout: float | None
20
+ content: bytes | None
21
+ data: dict[str, Any] | None
22
+ json: Any | None
23
+ files: dict[str, str] | None
24
+
25
+ class ClientRequestParams(RequestParams):
26
+ verify: bool | None
27
+ ca_cert_file: str | None
28
+ client_pem: str | None
29
+
30
+ class Response:
31
+ @property
32
+ def content(self) -> bytes: ...
33
+ @property
34
+ def cookies(self) -> dict[str, str]: ...
35
+ @property
36
+ def headers(self) -> dict[str, str]: ...
37
+ @property
38
+ def status_code(self) -> int: ...
39
+ @property
40
+ def url(self) -> str: ...
41
+ @property
42
+ def encoding(self) -> str: ...
43
+ @property
44
+ def text(self) -> str: ...
45
+ def json(self) -> Any: ...
46
+ @property
47
+ def text_markdown(self) -> str: ...
48
+ @property
49
+ def text_plain(self) -> str: ...
50
+ @property
51
+ def text_rich(self) -> str: ...
52
+
53
+ class RClient:
54
+ def __init__(
55
+ self,
56
+ auth: tuple[str, str | None] | None = None,
57
+ auth_bearer: str | None = None,
58
+ params: dict[str, str] | None = None,
59
+ headers: dict[str, str] | None = None,
60
+ cookies: dict[str, str] | None = None,
61
+ timeout: float | None = None,
62
+ cookie_store: bool | None = True,
63
+ referer: bool | None = True,
64
+ proxy: str | None = None,
65
+ follow_redirects: bool | None = True,
66
+ max_redirects: int | None = 20,
67
+ verify: bool | None = True,
68
+ ca_cert_file: str | None = None,
69
+ client_pem: str | None = None,
70
+ https_only: bool | None = False,
71
+ http2_only: bool | None = False,
72
+ ): ...
73
+ @property
74
+ def headers(self) -> dict[str, str]: ...
75
+ @headers.setter
76
+ def headers(self, headers: dict[str, str]) -> None: ...
77
+ @property
78
+ def cookies(self) -> dict[str, str]: ...
79
+ @cookies.setter
80
+ def cookies(self, cookies: dict[str, str]) -> None: ...
81
+ @property
82
+ def proxy(self) -> str | None: ...
83
+ @proxy.setter
84
+ def proxy(self, proxy: str) -> None: ...
85
+ def request(self, method: HttpMethod, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
86
+ def get(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
87
+ def head(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
88
+ def options(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
89
+ def delete(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
90
+ def post(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
91
+ def put(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
92
+ def patch(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
93
+
94
+ def request(method: HttpMethod, url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
95
+ def get(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
96
+ def head(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
97
+ def options(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
98
+ def delete(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
99
+ def post(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
100
+ def put(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
101
+ def patch(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
httpr/py.typed ADDED
File without changes
@@ -0,0 +1,316 @@
1
+ Metadata-Version: 2.4
2
+ Name: httpr
3
+ Version: 0.1.0
4
+ Classifier: Programming Language :: Rust
5
+ Classifier: Programming Language :: Python :: 3
6
+ Classifier: Programming Language :: Python :: 3 :: Only
7
+ Classifier: Programming Language :: Python :: 3.8
8
+ Classifier: Programming Language :: Python :: 3.9
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Programming Language :: Python :: Implementation :: CPython
14
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
15
+ Classifier: Topic :: Internet :: WWW/HTTP
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Requires-Dist: certifi ; extra == 'dev'
18
+ Requires-Dist: pytest>=8.1.1 ; extra == 'dev'
19
+ Requires-Dist: pytest-asyncio>=0.25.3 ; extra == 'dev'
20
+ Requires-Dist: typing-extensions ; python_full_version < '3.12' and extra == 'dev'
21
+ Requires-Dist: mypy>=1.14.1 ; extra == 'dev'
22
+ Requires-Dist: ruff>=0.9.2 ; extra == 'dev'
23
+ Requires-Dist: maturin ; extra == 'dev'
24
+ Requires-Dist: trustme ; extra == 'dev'
25
+ Requires-Dist: mkdocs-material ; extra == 'docs'
26
+ Requires-Dist: httpr[dev] ; extra == 'scratch'
27
+ Requires-Dist: matplotlib ; extra == 'scratch'
28
+ Requires-Dist: pandas ; extra == 'scratch'
29
+ Requires-Dist: jupyter ; extra == 'scratch'
30
+ Requires-Dist: ipykernel ; extra == 'scratch'
31
+ Requires-Dist: httpx ; extra == 'scratch'
32
+ Requires-Dist: gunicorn ; extra == 'scratch'
33
+ Requires-Dist: uvicorn ; extra == 'scratch'
34
+ Requires-Dist: trustme ; extra == 'scratch'
35
+ Requires-Dist: starlette ; extra == 'scratch'
36
+ Requires-Dist: fastapi ; extra == 'scratch'
37
+ Provides-Extra: dev
38
+ Provides-Extra: docs
39
+ Provides-Extra: scratch
40
+ License-File: LICENSE
41
+ Summary: Fast HTTP client for Python
42
+ Keywords: python,request
43
+ Author: thomasht86
44
+ License: MIT License
45
+ Requires-Python: >=3.9
46
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
47
+
48
+ # httpr
49
+
50
+ **Blazing fast http-client** for Python in Rust 🦀 that can be used as drop-in replacement for `httpx` in most cases.
51
+
52
+ - **Fast**: httpr is built on top of `reqwests` which is a blazing fast http client in Rust. Check out the [benchmark](#benchmark).
53
+ - **Both async and sync**: httpr provides both a sync and async client.
54
+ - **Lightweight**: httpr is a lightweight http client with 0 python-dependencies.
55
+ - **Async**: first-class support for async/await.
56
+ - **http2**: httpr supports http2.
57
+ - **mTLS**: httpr supports mTLS.
58
+ - **Zero python dependencies**: httpr is a pure rust library with no python dependencies.
59
+
60
+ ## Table of Contents
61
+
62
+ - [httpr](#httpr)
63
+ - [Table of Contents](#table-of-contents)
64
+ - [Installation](#installation)
65
+ - [Install with uv](#install-with-uv)
66
+ - [Install from PyPI](#install-from-pypi)
67
+ - [Benchmark](#benchmark)
68
+ - [Usage](#usage)
69
+ - [I. Client](#i-client)
70
+ - [Client methods](#client-methods)
71
+ - [Response object](#response-object)
72
+ - [Examples](#examples)
73
+ - [II. AsyncClient](#ii-asyncclient)
74
+ - [Precompiled wheels](#precompiled-wheels)
75
+ - [Acknowledgements](#acknowledgements)
76
+
77
+ ## Installation
78
+
79
+ ### Install with uv
80
+
81
+ ```python
82
+ uv add httpr
83
+ ```
84
+
85
+ or
86
+
87
+ ```python
88
+ uv pip install httpr
89
+ ```
90
+
91
+ ### Install from PyPI
92
+
93
+ ```python
94
+ pip install -U httpr
95
+ ```
96
+
97
+ ## Benchmark
98
+
99
+ ![](https://github.com/thomasht86/httpr/blob/main/benchmark.jpg?raw=true)
100
+
101
+ ## Usage
102
+
103
+ ### I. Client
104
+
105
+ ```python
106
+ class Client:
107
+ """Initializes an HTTP client.
108
+
109
+ Args:
110
+ auth (tuple[str, str| None] | None): Username and password for basic authentication. Default is None.
111
+ auth_bearer (str | None): Bearer token for authentication. Default is None.
112
+ params (dict[str, str] | None): Default query parameters to include in all requests. Default is None.
113
+ headers (dict[str, str] | None): Default headers to send with requests.
114
+ cookies (dict[str, str] | None): - Map of cookies to send with requests as the `Cookie` header.
115
+ timeout (float | None): HTTP request timeout in seconds. Default is 30.
116
+ cookie_store (bool | None): Enable a persistent cookie store. Received cookies will be preserved and included
117
+ in additional requests. Default is True.
118
+ referer (bool | None): Enable or disable automatic setting of the `Referer` header. Default is True.
119
+ proxy (str | None): Proxy URL for HTTP requests. Example: "socks5://127.0.0.1:9150". Default is None.
120
+ follow_redirects (bool | None): Whether to follow redirects. Default is True.
121
+ max_redirects (int | None): Maximum redirects to follow. Default 20. Applies if `follow_redirects` is True.
122
+ verify (bool | None): Verify SSL certificates. Default is True.
123
+ ca_cert_file (str | None): Path to CA certificate store. Default is None.
124
+ https_only` (bool | None): Restrict the Client to be used with HTTPS only requests. Default is `false`.
125
+ http2_only` (bool | None): If true - use only HTTP/2; if false - use only HTTP/1. Default is `false`.
126
+
127
+ """
128
+ ```
129
+
130
+ #### Client methods
131
+
132
+ The `Client` class provides a set of methods for making HTTP requests: `get`, `head`, `options`, `delete`, `post`, `put`, `patch`, each of which internally utilizes the `request()` method for execution. The parameters for these methods closely resemble those in `httpx`.
133
+ ```python
134
+ def get(
135
+ url: str,
136
+ params: dict[str, str] | None = None,
137
+ headers: dict[str, str] | None = None,
138
+ cookies: dict[str, str] | None = None,
139
+ auth: tuple[str, str| None] | None = None,
140
+ auth_bearer: str | None = None,
141
+ timeout: float | None = 30,
142
+ ):
143
+ """Performs a GET request to the specified URL.
144
+
145
+ Args:
146
+ url (str): The URL to which the request will be made.
147
+ params (dict[str, str] | None): A map of query parameters to append to the URL. Default is None.
148
+ headers (dict[str, str] | None): A map of HTTP headers to send with the request. Default is None.
149
+ cookies (dict[str, str] | None): - An optional map of cookies to send with requests as the `Cookie` header.
150
+ auth (tuple[str, str| None] | None): A tuple containing the username and an optional password
151
+ for basic authentication. Default is None.
152
+ auth_bearer (str | None): A string representing the bearer token for bearer token authentication. Default is None.
153
+ timeout (float | None): The timeout for the request in seconds. Default is 30.
154
+
155
+ """
156
+ ```
157
+ ```python
158
+ def post(
159
+ url: str,
160
+ params: dict[str, str] | None = None,
161
+ headers: dict[str, str] | None = None,
162
+ cookies: dict[str, str] | None = None,
163
+ content: bytes | None = None,
164
+ data: dict[str, Any] | None = None,
165
+ json: Any | None = None,
166
+ files: dict[str, str] | None = None,
167
+ auth: tuple[str, str| None] | None = None,
168
+ auth_bearer: str | None = None,
169
+ timeout: float | None = 30,
170
+ ):
171
+ """Performs a POST request to the specified URL.
172
+
173
+ Args:
174
+ url (str): The URL to which the request will be made.
175
+ params (dict[str, str] | None): A map of query parameters to append to the URL. Default is None.
176
+ headers (dict[str, str] | None): A map of HTTP headers to send with the request. Default is None.
177
+ cookies (dict[str, str] | None): - An optional map of cookies to send with requests as the `Cookie` header.
178
+ content (bytes | None): The content to send in the request body as bytes. Default is None.
179
+ data (dict[str, Any] | None): The form data to send in the request body. Default is None.
180
+ json (Any | None): A JSON serializable object to send in the request body. Default is None.
181
+ files (dict[str, str] | None): A map of file fields to file paths to be sent as multipart/form-data. Default is None.
182
+ auth (tuple[str, str| None] | None): A tuple containing the username and an optional password
183
+ for basic authentication. Default is None.
184
+ auth_bearer (str | None): A string representing the bearer token for bearer token authentication. Default is None.
185
+ timeout (float | None): The timeout for the request in seconds. Default is 30.
186
+
187
+ """
188
+ ```
189
+
190
+ #### Response object
191
+
192
+ The `Client` class returns a `Response` object that contains the following attributes and methods:
193
+
194
+ ```python
195
+ resp.content
196
+ resp.cookies
197
+ resp.encoding
198
+ resp.headers
199
+ resp.json()
200
+ resp.status_code
201
+ resp.text
202
+ resp.text_markdown # html is converted to markdown text using html2text-rs
203
+ resp.text_plain # html is converted to plain text
204
+ resp.text_rich # html is converted to rich text
205
+ resp.url
206
+ ```
207
+
208
+ #### Examples
209
+
210
+ ```python
211
+ import httpr
212
+
213
+ # Initialize the client
214
+ client = httpr.Client()
215
+
216
+ # GET request
217
+ resp = client.get("https://tls.peet.ws/api/all")
218
+ print(resp.json())
219
+
220
+ # GET request with passing params and setting timeout
221
+ params = {"param1": "value1", "param2": "value2"}
222
+ resp = client.post(url="https://httpbin.org/anything", params=params, timeout=10)
223
+ print(r.text)
224
+
225
+ # POST Binary Request Data
226
+ content = b"some_data"
227
+ resp = client.post(url="https://httpbin.org/anything", content=content)
228
+ print(r.text)
229
+
230
+ # POST Form Encoded Data
231
+ data = {"key1": "value1", "key2": "value2"}
232
+ resp = client.post(url="https://httpbin.org/anything", data=data)
233
+ print(r.text)
234
+
235
+ # POST JSON Encoded Data
236
+ json = {"key1": "value1", "key2": "value2"}
237
+ resp = client.post(url="https://httpbin.org/anything", json=json)
238
+ print(r.text)
239
+
240
+ # POST Multipart-Encoded Files
241
+ files = {'file1': '/home/root/file1.txt', 'file2': 'home/root/file2.txt'}
242
+ r = client.post("https://httpbin.org/post", files=files)
243
+ print(r.text)
244
+
245
+ # Authentication using user/password
246
+ auth = ("user", "password")
247
+ resp = client.post(url="https://httpbin.org/anything", auth=auth)
248
+ print(r.text)
249
+
250
+ # Authentication using auth bearer
251
+ auth_bearer = "bearerXXXXXXXXXXXXXXXXXXXX"
252
+ resp = client.post(url="https://httpbin.org/anything", auth_bearer=auth_bearer)
253
+ print(r.text)
254
+
255
+ # Using proxy or env var HTTPR_PROXY
256
+ resp = httpr.Client(proxy="http://127.0.0.1:8080").get("https://tls.peet.ws/api/all")
257
+ print(resp.json())
258
+ export HTTPR_PROXY="socks5://127.0.0.1:1080"
259
+ resp = httpr.Client().get("https://tls.peet.ws/api/all")
260
+ print(resp.json())
261
+
262
+ # Using custom CA certificate store: env var HTTPR_CA_BUNDLE
263
+ resp = httpr.Client(ca_cert_file="/cert/cacert.pem").get("https://tls.peet.ws/api/all")
264
+ print(resp.json())
265
+ resp = httpr.Client(ca_cert_file=certifi.where()).get("https://tls.peet.ws/api/all")
266
+ print(resp.json())
267
+ export HTTPR_CA_BUNDLE="/home/user/Downloads/cert.pem"
268
+ resp = httpr.Client().get("https://tls.peet.ws/api/all")
269
+ print(resp.json())
270
+
271
+ # You can also use convenience functions that use a default Client instance under the hood:
272
+ # httpr.get() | httpr.head() | httpr.options() | httpr.delete() | httpr.post() | httpr.patch() | httpr.put()
273
+ resp = httpr.get("https://httpbin.org/anything")
274
+ print(r.text)
275
+ ```
276
+
277
+ ### II. AsyncClient
278
+
279
+ `httpr.AsyncClient()` is an asynchronous wrapper around the `httpr.Client` class, offering the same functions, behavior, and input arguments.
280
+
281
+ ```python
282
+ import asyncio
283
+ import logging
284
+
285
+ import httpr
286
+
287
+ async def aget_text(url):
288
+ async with httpr.AsyncClient() as client:
289
+ resp = await client.get(url)
290
+ return resp.text
291
+
292
+ async def main():
293
+ urls = ["https://nytimes.com/", "https://cnn.com/", "https://abcnews.go.com/"]
294
+ tasks = [aget_text(u) for u in urls]
295
+ results = await asyncio.gather(*tasks)
296
+
297
+ if __name__ == "__main__":
298
+ logging.basicConfig(level=logging.INFO)
299
+ asyncio.run(main())
300
+ ```
301
+
302
+ ## Precompiled wheels
303
+
304
+ Provides precompiled wheels for the following platforms:
305
+
306
+ - 🐧 linux: `amd64`, `aarch64`, `armv7` (aarch64 and armv7 builds are `manylinux_2_34` compatible. `ubuntu>=22.04`, `debian>=12`)
307
+ - 🐧 musllinux: `amd64`, `aarch64`
308
+ - 🪟 windows: `amd64`
309
+ - 🍏 macos: `amd64`, `aarch64`.
310
+
311
+ ## Acknowledgements
312
+
313
+ - [PRIMP](https://github.com/deedy5/primp): *A lot* of code is borrowed from PRIMP, that wraps rust library `rquest` for python in a similar way.
314
+ - [reqwests](https://github.com/seanmonstar/reqwest): The rust library that powers httpr.
315
+ - [pyo3](https://github.com/PyO3/pyo3)
316
+ - [maturin](https://github.com/PyO3/maturin)
@@ -0,0 +1,8 @@
1
+ httpr-0.1.0.dist-info/METADATA,sha256=QCm1NtyBhldWbNhFEZwp6KaOuoUlIYVQ5f_lu6OLT28,12325
2
+ httpr-0.1.0.dist-info/WHEEL,sha256=R8ZEnni7m2eO5M7FTZ3FjvjlbxsclsOWT9kw6XK1Agc,94
3
+ httpr-0.1.0.dist-info/licenses/LICENSE,sha256=O15TIxUAXq6sSpPu0K3CJu_dT5ZzCgIk7hQtZsf0lEk,1084
4
+ httpr/httpr.pyi,sha256=VbROFo3ZXTacg2Fe0kvQWZ0RXXrAK08F4ivUL0cvGtY,3830
5
+ httpr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ httpr/__init__.py,sha256=mJu6IccmRh6mzdliCqwFnQtpsYuKYPpeTvvcuYqQBdw,8833
7
+ httpr/httpr.pyd,sha256=fuRxnteKqCmw5LP4iCo13HS-AY8Gjhjsv9iJRdRSwLw,4543488
8
+ httpr-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.8.2)
3
+ Root-Is-Purelib: false
4
+ Tag: cp39-abi3-win_amd64
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 deedy5
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.