atomhttp 1.0.0__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.
@@ -0,0 +1,107 @@
1
+ """
2
+ Redirect Handler Module
3
+ -----------------------
4
+ Handles HTTP redirect responses for the AtomHTTP client.
5
+
6
+ This module provides the RedirectHandler class which manages redirect
7
+ following logic, including checking redirect status codes, tracking
8
+ redirect counts, and constructing absolute URLs from relative redirect
9
+ locations.
10
+ """
11
+
12
+ from typing import Optional
13
+ from urllib.parse import urlparse, urlunparse
14
+
15
+
16
+ class RedirectHandler:
17
+ """
18
+ Handle HTTP redirect responses and manage redirect limits.
19
+
20
+ This class tracks the number of redirects followed and provides
21
+ utilities for determining when to follow redirects and how to
22
+ construct absolute redirect URLs from relative locations.
23
+
24
+ The handler supports standard HTTP redirect status codes:
25
+ - 301: Moved Permanently
26
+ - 302: Found (Temporary Redirect)
27
+ - 303: See Other
28
+ - 307: Temporary Redirect
29
+ - 308: Permanent Redirect
30
+
31
+ Attributes:
32
+ max_redirects (int): Maximum number of redirects to follow
33
+ redirect_count (int): Current count of redirects followed
34
+ """
35
+
36
+ def __init__(self, max_redirects: int = 5):
37
+ """
38
+ Initialize redirect handler with maximum redirect limit.
39
+
40
+ Args:
41
+ max_redirects (int): Maximum number of redirects to follow.
42
+ Defaults to 5, which is the standard for
43
+ most HTTP clients.
44
+ """
45
+ self.max_redirects = max_redirects
46
+ self.redirect_count = 0
47
+
48
+ def should_redirect(self, status_code: int) -> bool:
49
+ """
50
+ Determine if a status code indicates a redirect response.
51
+
52
+ This method checks if the HTTP status code is one of the standard
53
+ redirect codes that should be followed automatically.
54
+
55
+ Args:
56
+ status_code (int): HTTP status code from response
57
+
58
+ Returns:
59
+ bool: True if status code is a redirect (301, 302, 303, 307, 308),
60
+ False otherwise
61
+ """
62
+ return status_code in (301, 302, 303, 307, 308)
63
+
64
+ def is_max_reached(self) -> bool:
65
+ """
66
+ Check if the maximum number of redirects has been reached.
67
+
68
+ Returns:
69
+ bool: True if redirect_count >= max_redirects, False otherwise
70
+
71
+ Note:
72
+ When this returns True, the client should stop following
73
+ redirects to avoid infinite loops.
74
+ """
75
+ return self.redirect_count >= self.max_redirects
76
+
77
+ def get_redirect_url(self, location: str, original_url: str) -> str:
78
+ """
79
+ Convert a redirect location header to an absolute URL.
80
+
81
+ The Location header in HTTP redirects may be either absolute
82
+ (complete URL) or relative (path only). This method resolves
83
+ relative locations to absolute URLs using the original request URL.
84
+
85
+ Args:
86
+ location (str): The Location header value from redirect response
87
+ original_url (str): The original URL that was requested
88
+
89
+ Returns:
90
+ str: Absolute URL to redirect to
91
+ """
92
+ # If location is already absolute, return it directly
93
+ if location.startswith(('http://', 'https://')):
94
+ return location
95
+
96
+ # Parse the original URL to extract scheme and host
97
+ parsed = urlparse(original_url)
98
+ base = f"{parsed.scheme}://{parsed.netloc}"
99
+
100
+ # Handle absolute path (starts with '/')
101
+ if location.startswith('/'):
102
+ return base + location
103
+
104
+ # Handle relative path (no leading '/')
105
+ # Remove the last segment from the original path to get directory
106
+ path = parsed.path.rsplit('/', 1)[0]
107
+ return base + path + '/' + location
@@ -0,0 +1,165 @@
1
+ Metadata-Version: 2.4
2
+ Name: atomhttp
3
+ Version: 1.0.0
4
+ Summary: Professional asynchronous HTTP client for Python — interceptors, progress tracking, FormData, Blob, concurrent requests, and full type hints
5
+ Author-email: Abolfazl Hosseini <tryuzr@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/inject3r/atomhttp
8
+ Project-URL: Repository, https://github.com/inject3r/atomhttp.git
9
+ Project-URL: Documentation, https://inject3r.github.io/atomhttp
10
+ Project-URL: Issues, https://github.com/inject3r/atomhttp/issues
11
+ Project-URL: Changelog, https://github.com/inject3r/atomhttp/releases
12
+ Keywords: http,client,async,await,aiohttp,rest,api,interceptor,progress,formdata
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: License :: OSI Approved :: MIT License
21
+ Classifier: Operating System :: OS Independent
22
+ Classifier: Development Status :: 5 - Production/Stable
23
+ Classifier: Intended Audience :: Developers
24
+ Classifier: Topic :: Internet :: WWW/HTTP
25
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Classifier: Framework :: AsyncIO
27
+ Requires-Python: >=3.8
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: aiohttp>=3.8.0
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
33
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
34
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
35
+ Requires-Dist: black>=22.0.0; extra == "dev"
36
+ Requires-Dist: isort>=5.10.0; extra == "dev"
37
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
38
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
39
+ Provides-Extra: test
40
+ Requires-Dist: pytest>=7.0.0; extra == "test"
41
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
42
+ Requires-Dist: pytest-cov>=4.0.0; extra == "test"
43
+ Provides-Extra: all
44
+ Requires-Dist: aiohttp>=3.8.0; extra == "all"
45
+ Requires-Dist: pytest>=7.0.0; extra == "all"
46
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "all"
47
+ Requires-Dist: pytest-cov>=4.0.0; extra == "all"
48
+ Dynamic: license-file
49
+
50
+ <p align="center">
51
+ <img src="https://inject3r.github.io/atomhttp/logo.jpg" alt="AtomHTTP Logo" width="350">
52
+ </p>
53
+
54
+ # AtomHTTP
55
+
56
+ A professional, feature-rich asynchronous HTTP client for Python — designed for developers who need reliability, flexibility, and performance.
57
+
58
+ **[Full Documentation](https://inject3r.github.io/atomhttp)** — Complete API reference, advanced guides, and examples
59
+
60
+ <br/>
61
+
62
+ ## Features
63
+
64
+ - **Full HTTP Method Support**: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS with async/await syntax
65
+ - **Request & Response Interceptors**: Modify requests before sending and responses before returning
66
+ - **Upload & Download Progress Tracking**: Real-time callbacks for monitoring data transfer
67
+ - **FormData Support**: Multipart/form-data and URL-encoded form handling with file uploads
68
+ - **Multiple Response Types**: JSON (auto-parsed), text, blob, arraybuffer, and stream
69
+ - **Concurrent Request Helpers**: Execute multiple requests in parallel with `all()` and `spread()`
70
+ - **Base URL Configuration**: Set a base URL once and use relative paths
71
+ - **Automatic JSON Serialization**: No need to manually encode/decode JSON
72
+ - **Authentication**: Basic Auth and Bearer Token support
73
+ - **Comprehensive Error Handling**: Typed exceptions with standardized error codes
74
+ - **Timeout & Redirect Control**: Configurable timeouts and maximum redirect limits
75
+ - **Keep-Alive & Connection Pooling**: Reuse connections for better performance
76
+ - **Proxy Support**: Route requests through HTTP proxies
77
+ - **Unix Socket Path Support**: Connect via Unix domain sockets
78
+ - **Size Limits**: Configure maximum request body and response content lengths
79
+ - **Status Code Validation**: Custom validation functions for HTTP status codes
80
+ - **CSRF Protection**: Built-in support for XSRF token headers
81
+ - **Automatic Decompression**: Handles gzip and deflate compressed responses
82
+ - **Mock Adapter for Testing**: Simulate responses without network calls
83
+ - **Type Hints**: Full typing support for excellent IDE autocompletion
84
+
85
+ ## Installation
86
+
87
+ ```bash
88
+ pip install atomhttp
89
+ ```
90
+
91
+ With development dependencies:
92
+
93
+ ```bash
94
+ pip install atomhttp[dev]
95
+ ```
96
+
97
+ ## Quick Start
98
+
99
+ ```python
100
+ import asyncio
101
+ from atomhttp import AtomHTTP
102
+
103
+ async def main():
104
+ client = AtomHTTP({'baseURL': 'https://api.example.com'})
105
+ response = await client.get('/users')
106
+ print(response.status, response.data)
107
+ await client.close()
108
+
109
+ asyncio.run(main())
110
+ ```
111
+
112
+ ## Documentation
113
+
114
+ For complete documentation, API reference, and advanced usage examples, visit:
115
+
116
+ **[https://inject3r.github.io/atomhttp](https://inject3r.github.io/atomhttp)**
117
+
118
+ The documentation includes:
119
+
120
+ - Detailed API reference for all classes and methods
121
+ - Advanced usage patterns and best practices
122
+ - Configuration options and their effects
123
+ - Error handling strategies
124
+ - Migration guides from other HTTP clients
125
+
126
+ ## Requirements
127
+
128
+ - Python 3.8+
129
+ - aiohttp 3.8.0+
130
+
131
+ ## Running Tests
132
+
133
+ ```bash
134
+ # Run all tests with coverage
135
+ ./scripts/tests.sh
136
+
137
+ # Clean test output files
138
+ ./scripts/test_clean.sh
139
+ ```
140
+
141
+ ## License
142
+
143
+ This project is licensed under the MIT License.
144
+
145
+ ## Author
146
+
147
+ **Abolfazl Hosseini**
148
+
149
+ - Email: tryuzr@gmail.com
150
+ - GitHub: [@inject3r](https://github.com/inject3r)
151
+
152
+ ## Contributing
153
+
154
+ Contributions are welcome! Please feel free to submit a Pull Request.
155
+
156
+ 1. Fork the repository
157
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
158
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
159
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
160
+ 5. Open a Pull Request
161
+
162
+ ## Acknowledgments
163
+
164
+ - [aiohttp](https://docs.aiohttp.org/) - Async HTTP client/server framework
165
+ - All contributors and users of this project
@@ -0,0 +1,36 @@
1
+ atomhttp/__init__.py,sha256=mJTLw2s70Z8hosMQ-IfD2whldI0WLbqczamxhylo79s,2121
2
+ atomhttp/client.py,sha256=sHupALERyHvOCh-ZaJJJUfr8Lc2iEtbf8mLmLGP9DVo,20752
3
+ atomhttp/adapters/__init__.py,sha256=waRdw1NYqVo7CNzboCt0zmszXy1OTXc3j0jsGUVmRg8,117
4
+ atomhttp/adapters/http_adapter.py,sha256=kzYNGlXsEMl-LsfEcFnHZOglzPFnpuVTL4zFvX4Cjz0,4173
5
+ atomhttp/adapters/mock_adapter.py,sha256=OxeJvqIfGMqvg_4WP_rZEL_-hna-rCtKzb_T-cUmlkk,5179
6
+ atomhttp/auth/__init__.py,sha256=7OSniKBhYho-GvVA9gchOgf4RWwvEnT4Zi2PYkTBt7Q,108
7
+ atomhttp/auth/basic_auth.py,sha256=iu3qnm1Yzdf3wXe_FQ73loxQaz2ctgTUUdowOOo5-54,3350
8
+ atomhttp/auth/bearer_auth.py,sha256=8M9F_FeGKQz1Xi1pt0vaU1TF2Llcfq9d31iPFYs83Zc,3161
9
+ atomhttp/core/__init__.py,sha256=80CeSPFTVE5EtPfoiBqXFmSQamKTMoLC81VsziuNfWA,465
10
+ atomhttp/core/adapters.py,sha256=JxE3kTL8gXP29Kw55HQI5Qc0gxnp1uRJWiYkG4bpsRE,27054
11
+ atomhttp/core/config.py,sha256=15Zuov_FQWj1lDj4liOkwzrbY_-cqmIzcS7IdglPUtM,7401
12
+ atomhttp/core/defaults.py,sha256=G41lw8ynFE_Xd4lvd-O0-qkq8WYZHLH6LF5sZqN4bSw,7836
13
+ atomhttp/core/form_data.py,sha256=VLpDYAAfo4kMA46uB5btcEsAO2hrdjnACw0kTKsfyPs,10259
14
+ atomhttp/core/request.py,sha256=xdUozOaiHzjud8i2WFQIJNT_wWWsJQ4mBCccWQ4yPYA,10062
15
+ atomhttp/core/response.py,sha256=6K1ROg4rGjxTm1LAfoGGJB6yR4J3ce4iiHjkxhsZ1Rk,3372
16
+ atomhttp/errors/__init__.py,sha256=BUEU5qQcvlMeS7_ZUikZaj7829N_95H8LZygsFsg66k,246
17
+ atomhttp/errors/http_errors.py,sha256=jpCAfVD3cfMNgbk6SGdaRsruoBA0zV-u7Xndlwdqw4Y,4775
18
+ atomhttp/interceptors/__init__.py,sha256=djVVrsMK-mTWUTPzajBybwrHkjRQwe8ZvMOTNDdauzo,224
19
+ atomhttp/interceptors/manager.py,sha256=I2uidox4MjEZOq76IqM2I5APW1IjjqVMUW9uoabY_wA,5466
20
+ atomhttp/interceptors/request_interceptor.py,sha256=K8T0VbC37Z5DwTa6e_SiklGaqQZXKJxrxIvIAAFUOYA,721
21
+ atomhttp/interceptors/response_interceptor.py,sha256=so92WxoBflIwhUv8nXP_EAHMxFI2Al1C6gmv-TLTXjA,718
22
+ atomhttp/progress/__init__.py,sha256=pD_ea5iV-yabnro2It0iHQ3JSM17Pf6ChUiU74wNrXQ,75
23
+ atomhttp/progress/upload_progress.py,sha256=bVu39oCZKcaoAIx2Qip4zYTf5FTRuvNcen28MfeI8zw,3465
24
+ atomhttp/transforms/__init__.py,sha256=rO3nPoftABf3bUolztfRSluNJKtBv6-JzrprXKbIv_0,220
25
+ atomhttp/transforms/data_serializer.py,sha256=GGT1VV-pGa2vTQliHhhjHaoq_l2eR-tECdz9QtJn8ec,3245
26
+ atomhttp/transforms/request_transform.py,sha256=Sh9mqaz29xBMvyezA9ERwJ1yMXwQ4kRQzJRXiXxe70g,4147
27
+ atomhttp/transforms/response_transform.py,sha256=EBUVHdDaL505CvyyyNEh7hzEznWEOMpzjP4q45HJavk,2826
28
+ atomhttp/utils/__init__.py,sha256=tHngX0GRgmo3peV9eBaxwd3PltGgEemIHde7Fmcn7eo,226
29
+ atomhttp/utils/cookies.py,sha256=4ore5vu48BpR6m4oijEqwvywIjWJIDcqKei5KkfzEp8,4610
30
+ atomhttp/utils/helpers.py,sha256=RJSDuVUlKjeP9UTrfkesNbpXlkeGsp9ktym_odjbs2c,3958
31
+ atomhttp/utils/redirect.py,sha256=yRvQfm4aHTBODbREaHeHMEzvfAINgvCp1saAdbgBP3I,3835
32
+ atomhttp-1.0.0.dist-info/licenses/LICENSE,sha256=aCMFMZNf1JWWTFSFgxhyAMhACSjlaC_Q9vYbFMP_JH8,1073
33
+ atomhttp-1.0.0.dist-info/METADATA,sha256=i_sGyftTTqapcNq4g7UJd1OBQANLbAX95q9nigZxUwc,5911
34
+ atomhttp-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
35
+ atomhttp-1.0.0.dist-info/top_level.txt,sha256=Wx-x5YQAk-KfplY7qqB_kU9T2_JxXv49zVEdu7ZSQCo,9
36
+ atomhttp-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Abolfazl Hosseini
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.
@@ -0,0 +1 @@
1
+ atomhttp