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.
- atomhttp/__init__.py +76 -0
- atomhttp/adapters/__init__.py +4 -0
- atomhttp/adapters/http_adapter.py +102 -0
- atomhttp/adapters/mock_adapter.py +130 -0
- atomhttp/auth/__init__.py +4 -0
- atomhttp/auth/basic_auth.py +90 -0
- atomhttp/auth/bearer_auth.py +83 -0
- atomhttp/client.py +577 -0
- atomhttp/core/__init__.py +19 -0
- atomhttp/core/adapters.py +687 -0
- atomhttp/core/config.py +186 -0
- atomhttp/core/defaults.py +212 -0
- atomhttp/core/form_data.py +282 -0
- atomhttp/core/request.py +240 -0
- atomhttp/core/response.py +101 -0
- atomhttp/errors/__init__.py +13 -0
- atomhttp/errors/http_errors.py +142 -0
- atomhttp/interceptors/__init__.py +5 -0
- atomhttp/interceptors/manager.py +136 -0
- atomhttp/interceptors/request_interceptor.py +18 -0
- atomhttp/interceptors/response_interceptor.py +18 -0
- atomhttp/progress/__init__.py +3 -0
- atomhttp/progress/upload_progress.py +89 -0
- atomhttp/transforms/__init__.py +5 -0
- atomhttp/transforms/data_serializer.py +96 -0
- atomhttp/transforms/request_transform.py +96 -0
- atomhttp/transforms/response_transform.py +73 -0
- atomhttp/utils/__init__.py +5 -0
- atomhttp/utils/cookies.py +128 -0
- atomhttp/utils/helpers.py +111 -0
- atomhttp/utils/redirect.py +107 -0
- atomhttp-1.0.0.dist-info/METADATA +165 -0
- atomhttp-1.0.0.dist-info/RECORD +36 -0
- atomhttp-1.0.0.dist-info/WHEEL +5 -0
- atomhttp-1.0.0.dist-info/licenses/LICENSE +21 -0
- atomhttp-1.0.0.dist-info/top_level.txt +1 -0
atomhttp/__init__.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AtomHTTP - Professional HTTP Client for Python
|
|
3
|
+
===============================================
|
|
4
|
+
|
|
5
|
+
A comprehensive, asynchronous HTTP client for Python with features including:
|
|
6
|
+
- Full HTTP method support (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)
|
|
7
|
+
- Request and response interceptors
|
|
8
|
+
- Upload and download progress tracking
|
|
9
|
+
- FormData (multipart/form-data) with file uploads
|
|
10
|
+
- Blob, ArrayBuffer, and stream response types
|
|
11
|
+
- Concurrent request helpers (all, spread)
|
|
12
|
+
- Base URL configuration
|
|
13
|
+
- Automatic JSON serialization/deserialization
|
|
14
|
+
- Comprehensive error handling with typed exceptions
|
|
15
|
+
- Type hints for better IDE support
|
|
16
|
+
- Mock adapter for testing
|
|
17
|
+
- Keep-alive connection pooling
|
|
18
|
+
- Proxy support
|
|
19
|
+
- Unix socket path support
|
|
20
|
+
- Configurable timeouts and redirect limits
|
|
21
|
+
|
|
22
|
+
This module exports the main AtomHTTP client class along with all necessary
|
|
23
|
+
types, exceptions, and utilities for making HTTP requests.
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
>>> import asyncio
|
|
27
|
+
>>> from atomhttp import AtomHTTP
|
|
28
|
+
>>>
|
|
29
|
+
>>> async def main():
|
|
30
|
+
... client = AtomHTTP({'baseURL': 'https://api.example.com'})
|
|
31
|
+
... response = await client.get('/users')
|
|
32
|
+
... print(response.status, response.data)
|
|
33
|
+
... await client.close()
|
|
34
|
+
>>>
|
|
35
|
+
>>> asyncio.run(main())
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
from .client import AtomHTTP
|
|
39
|
+
from .errors.http_errors import (
|
|
40
|
+
AtomHTTPError,
|
|
41
|
+
AtomHTTPRequestError,
|
|
42
|
+
AtomHTTPNetworkError,
|
|
43
|
+
AtomHTTPTimeoutError
|
|
44
|
+
)
|
|
45
|
+
from .core.response import Response
|
|
46
|
+
from .core.config import RequestConfig
|
|
47
|
+
from .core.form_data import FormData
|
|
48
|
+
from .core.adapters import HTTPAdapter, MockAdapter
|
|
49
|
+
from .interceptors.manager import InterceptorManager
|
|
50
|
+
|
|
51
|
+
__version__ = "2.0.0"
|
|
52
|
+
|
|
53
|
+
__all__ = [
|
|
54
|
+
# Main client
|
|
55
|
+
"AtomHTTP",
|
|
56
|
+
|
|
57
|
+
# Exception classes
|
|
58
|
+
"AtomHTTPError",
|
|
59
|
+
"AtomHTTPRequestError",
|
|
60
|
+
"AtomHTTPNetworkError",
|
|
61
|
+
"AtomHTTPTimeoutError",
|
|
62
|
+
|
|
63
|
+
# Core types
|
|
64
|
+
"Response",
|
|
65
|
+
"RequestConfig",
|
|
66
|
+
|
|
67
|
+
# Interceptor management
|
|
68
|
+
"InterceptorManager",
|
|
69
|
+
|
|
70
|
+
# Data types
|
|
71
|
+
"FormData",
|
|
72
|
+
|
|
73
|
+
# Adapters
|
|
74
|
+
"HTTPAdapter",
|
|
75
|
+
"MockAdapter",
|
|
76
|
+
]
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""
|
|
2
|
+
HTTP Adapter Module
|
|
3
|
+
-------------------
|
|
4
|
+
This module provides the base HTTP adapter for making asynchronous HTTP requests
|
|
5
|
+
using aiohttp. It handles request execution, timeout management, proxy support,
|
|
6
|
+
and response processing.
|
|
7
|
+
|
|
8
|
+
The HTTPAdapter is the default transport layer for the AtomHTTP client,
|
|
9
|
+
responsible for converting RequestConfig objects into actual HTTP requests
|
|
10
|
+
and wrapping responses into AtomHTTP Response objects.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import aiohttp
|
|
14
|
+
from typing import Optional
|
|
15
|
+
from ..core.config import RequestConfig
|
|
16
|
+
from ..core.response import Response
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class HTTPAdapter:
|
|
20
|
+
"""
|
|
21
|
+
HTTP adapter for making asynchronous HTTP requests using aiohttp.
|
|
22
|
+
|
|
23
|
+
This adapter serves as the transport layer for the AtomHTTP client,
|
|
24
|
+
handling the low-level details of HTTP communication including connection
|
|
25
|
+
management, timeout handling, proxy configuration, and response parsing.
|
|
26
|
+
|
|
27
|
+
Attributes:
|
|
28
|
+
proxy (Optional[str]): Proxy server URL to use for requests.
|
|
29
|
+
Format: 'http://proxy.example.com:8080'
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, proxy: Optional[str] = None):
|
|
33
|
+
"""
|
|
34
|
+
Initialize the HTTP adapter with optional proxy configuration.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
proxy (Optional[str]): Proxy server URL. If provided, all requests
|
|
38
|
+
will be routed through this proxy.
|
|
39
|
+
"""
|
|
40
|
+
self.proxy = proxy
|
|
41
|
+
|
|
42
|
+
async def send(self, config: RequestConfig) -> Response:
|
|
43
|
+
"""
|
|
44
|
+
Execute an HTTP request based on the provided configuration.
|
|
45
|
+
|
|
46
|
+
This method performs the actual HTTP request using aiohttp,
|
|
47
|
+
handling all aspects of the request lifecycle including connection
|
|
48
|
+
establishment, timeout management, request headers and body,
|
|
49
|
+
redirect following, and response parsing.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
config (RequestConfig): Request configuration object containing all
|
|
53
|
+
request parameters such as URL, method,
|
|
54
|
+
headers, data, timeout, etc.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Response: A AtomHTTP Response object containing the parsed response
|
|
58
|
+
data, status code, headers, and original configuration.
|
|
59
|
+
|
|
60
|
+
Raises:
|
|
61
|
+
aiohttp.ClientError: If a network-related error occurs
|
|
62
|
+
asyncio.TimeoutError: If the request exceeds the configured timeout
|
|
63
|
+
json.JSONDecodeError: If response_type='json' and response is invalid JSON
|
|
64
|
+
"""
|
|
65
|
+
# Configure timeout with total request duration limit
|
|
66
|
+
timeout = aiohttp.ClientTimeout(total=config.timeout)
|
|
67
|
+
|
|
68
|
+
# Create TCP connector if proxy is configured
|
|
69
|
+
connector = None
|
|
70
|
+
if self.proxy:
|
|
71
|
+
connector = aiohttp.TCPConnector()
|
|
72
|
+
|
|
73
|
+
# Create a new client session for this request
|
|
74
|
+
# Using async context manager ensures proper cleanup
|
|
75
|
+
async with aiohttp.ClientSession(connector=connector) as session:
|
|
76
|
+
# Execute the HTTP request with all configured parameters
|
|
77
|
+
async with session.request(
|
|
78
|
+
method=config.method,
|
|
79
|
+
url=config.url,
|
|
80
|
+
headers=config.headers,
|
|
81
|
+
params=config.params,
|
|
82
|
+
data=config.data,
|
|
83
|
+
timeout=timeout,
|
|
84
|
+
max_redirects=config.maxRedirects
|
|
85
|
+
) as response:
|
|
86
|
+
# Parse response body based on expected response type
|
|
87
|
+
# JSON responses are automatically deserialized to dict/list
|
|
88
|
+
# Non-JSON responses are returned as plain text
|
|
89
|
+
if config.responseType == 'json':
|
|
90
|
+
data = await response.json()
|
|
91
|
+
else:
|
|
92
|
+
data = await response.text()
|
|
93
|
+
|
|
94
|
+
# Wrap the aiohttp response in AtomHTTP's Response object
|
|
95
|
+
return Response(
|
|
96
|
+
data=data,
|
|
97
|
+
status=response.status,
|
|
98
|
+
status_text=response.reason,
|
|
99
|
+
headers=dict(response.headers),
|
|
100
|
+
config=config,
|
|
101
|
+
request=config
|
|
102
|
+
)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Mock Adapter Module
|
|
3
|
+
-------------------
|
|
4
|
+
This module provides a mock HTTP adapter for testing purposes.
|
|
5
|
+
|
|
6
|
+
The MockAdapter allows developers to simulate HTTP responses without making
|
|
7
|
+
actual network requests. This is useful for unit testing, integration testing,
|
|
8
|
+
and development scenarios where external APIs are unavailable or undesirable
|
|
9
|
+
to call directly.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from typing import Dict, Any, Optional
|
|
13
|
+
from ..core.config import RequestConfig
|
|
14
|
+
from ..core.response import Response
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MockAdapter:
|
|
18
|
+
"""
|
|
19
|
+
Mock adapter for testing HTTP requests without actual network calls.
|
|
20
|
+
|
|
21
|
+
This adapter stores predefined responses for specific request patterns
|
|
22
|
+
and returns them when matching requests are made. It enables isolated
|
|
23
|
+
testing of code that depends on HTTP responses without external dependencies.
|
|
24
|
+
|
|
25
|
+
Features:
|
|
26
|
+
- Register mock responses for specific HTTP methods and URLs
|
|
27
|
+
- Customizable response data, status codes, and status texts
|
|
28
|
+
- Automatic 404 response for unregistered endpoints
|
|
29
|
+
- No actual network connections are established
|
|
30
|
+
|
|
31
|
+
Attributes:
|
|
32
|
+
_responses (Dict[str, Dict]): Internal storage mapping request keys
|
|
33
|
+
to their configured mock responses.
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
>>> mock = MockAdapter()
|
|
37
|
+
>>> mock.on('GET', 'https://api.test/users', {'users': []}, 200)
|
|
38
|
+
>>> response = await mock.send(config)
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self):
|
|
42
|
+
"""
|
|
43
|
+
Initialize an empty mock adapter with no predefined responses.
|
|
44
|
+
|
|
45
|
+
Use the on() method to register mock responses before sending requests.
|
|
46
|
+
"""
|
|
47
|
+
self._responses: Dict[str, Dict] = {}
|
|
48
|
+
|
|
49
|
+
def on(self, method: str, url: str, response_data: Any, status: int = 200):
|
|
50
|
+
"""
|
|
51
|
+
Register a mock response for a specific HTTP method and URL.
|
|
52
|
+
|
|
53
|
+
When a request with the matching method and URL is sent through this
|
|
54
|
+
adapter, the registered response will be returned instead of making
|
|
55
|
+
an actual network request.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
method (str): HTTP method (GET, POST, PUT, DELETE, etc.)
|
|
59
|
+
url (str): Full URL or path that this mock should respond to
|
|
60
|
+
response_data (Any): Data to be returned as the response body.
|
|
61
|
+
Can be dict, list, string, or any JSON-serializable type.
|
|
62
|
+
status (int): HTTP status code to return. Defaults to 200.
|
|
63
|
+
|
|
64
|
+
Note:
|
|
65
|
+
If multiple responses are registered for the same method and URL,
|
|
66
|
+
the last registration will overwrite previous ones.
|
|
67
|
+
|
|
68
|
+
Example:
|
|
69
|
+
>>> mock = MockAdapter()
|
|
70
|
+
>>> mock.on('GET', 'https://api.test/users', {'users': []}, 200)
|
|
71
|
+
>>> mock.on('POST', 'https://api.test/users', {'id': 1}, 201)
|
|
72
|
+
>>> mock.on('GET', 'https://api.test/users/1', {'name': 'John'}, 200)
|
|
73
|
+
"""
|
|
74
|
+
# Create a unique key combining method and URL for lookup
|
|
75
|
+
key = f"{method}:{url}"
|
|
76
|
+
|
|
77
|
+
# Store the mock response configuration
|
|
78
|
+
self._responses[key] = {
|
|
79
|
+
'data': response_data,
|
|
80
|
+
'status': status,
|
|
81
|
+
'status_text': 'OK' if status == 200 else 'Error'
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async def send(self, config: RequestConfig) -> Response:
|
|
85
|
+
"""
|
|
86
|
+
Send a mock request and return a predefined response.
|
|
87
|
+
|
|
88
|
+
This method looks up the request method and URL in the registered
|
|
89
|
+
responses. If a match is found, the corresponding mock response is
|
|
90
|
+
returned. Otherwise, a 404 Not Found response is returned.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
config (RequestConfig): Request configuration containing method and URL.
|
|
94
|
+
Other config fields (headers, data, etc.) are
|
|
95
|
+
ignored in mock mode.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Response: A AtomHTTP Response object containing either the registered
|
|
99
|
+
mock data or a 404 error response.
|
|
100
|
+
|
|
101
|
+
Note:
|
|
102
|
+
No actual HTTP request is made. The response is constructed entirely
|
|
103
|
+
from in-memory mock data, making this adapter suitable for tests
|
|
104
|
+
that require deterministic, repeatable responses.
|
|
105
|
+
"""
|
|
106
|
+
# Build lookup key from request configuration
|
|
107
|
+
key = f"{config.method}:{config.url}"
|
|
108
|
+
|
|
109
|
+
# Check if a mock response is registered for this request
|
|
110
|
+
if key in self._responses:
|
|
111
|
+
mock = self._responses[key]
|
|
112
|
+
# Return the registered mock response
|
|
113
|
+
return Response(
|
|
114
|
+
data=mock['data'],
|
|
115
|
+
status=mock['status'],
|
|
116
|
+
status_text=mock['status_text'],
|
|
117
|
+
headers={},
|
|
118
|
+
config=config,
|
|
119
|
+
request=config
|
|
120
|
+
)
|
|
121
|
+
else:
|
|
122
|
+
# Return default 404 response for unregistered endpoints
|
|
123
|
+
return Response(
|
|
124
|
+
data={'error': 'No mock found'},
|
|
125
|
+
status=404,
|
|
126
|
+
status_text='Not Found',
|
|
127
|
+
headers={},
|
|
128
|
+
config=config,
|
|
129
|
+
request=config
|
|
130
|
+
)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Basic Authentication Module
|
|
3
|
+
---------------------------
|
|
4
|
+
This module provides Basic HTTP Authentication support for the AtomHTTP client.
|
|
5
|
+
|
|
6
|
+
Basic Authentication is a simple authentication scheme built into the HTTP
|
|
7
|
+
protocol. The client sends the username and password encoded in base64 within
|
|
8
|
+
the Authorization header.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import base64
|
|
12
|
+
from typing import Dict
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BasicAuth:
|
|
16
|
+
"""
|
|
17
|
+
Basic Authentication handler for HTTP requests.
|
|
18
|
+
|
|
19
|
+
This class implements the HTTP Basic Authentication scheme as defined in
|
|
20
|
+
RFC 7617. It handles the encoding of username and password credentials
|
|
21
|
+
into the standard Basic authentication header format.
|
|
22
|
+
|
|
23
|
+
How Basic Auth Works:
|
|
24
|
+
1. Credentials are combined as "username:password"
|
|
25
|
+
2. The combined string is encoded using Base64
|
|
26
|
+
3. The encoded string is prefixed with "Basic " and sent in the
|
|
27
|
+
Authorization header
|
|
28
|
+
|
|
29
|
+
Security Considerations:
|
|
30
|
+
- Base64 encoding is NOT encryption; it's easily reversible
|
|
31
|
+
- Basic Auth should ONLY be used over HTTPS connections
|
|
32
|
+
- Credentials are sent with every request
|
|
33
|
+
|
|
34
|
+
Attributes:
|
|
35
|
+
username (str): The authentication username
|
|
36
|
+
password (str): The authentication password
|
|
37
|
+
|
|
38
|
+
Example:
|
|
39
|
+
>>> auth = BasicAuth('admin', 'secret123')
|
|
40
|
+
>>> headers = auth.get_header()
|
|
41
|
+
>>> response = await client.get('/protected', headers=headers)
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def __init__(self, username: str, password: str):
|
|
45
|
+
"""
|
|
46
|
+
Initialize Basic Authentication with username and password.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
username (str): The username for authentication
|
|
50
|
+
password (str): The password for authentication
|
|
51
|
+
|
|
52
|
+
Note:
|
|
53
|
+
Username and password are stored in plain text in memory.
|
|
54
|
+
Always use HTTPS when using Basic Authentication.
|
|
55
|
+
"""
|
|
56
|
+
self.username = username
|
|
57
|
+
self.password = password
|
|
58
|
+
|
|
59
|
+
def get_header(self) -> Dict[str, str]:
|
|
60
|
+
"""
|
|
61
|
+
Generate the HTTP Authorization header for Basic Authentication.
|
|
62
|
+
|
|
63
|
+
This method encodes the username and password credentials according
|
|
64
|
+
to the Basic Authentication scheme and returns a dictionary ready
|
|
65
|
+
to be merged into request headers.
|
|
66
|
+
|
|
67
|
+
The encoding process:
|
|
68
|
+
1. Combine username and password with a colon: "user:pass"
|
|
69
|
+
2. Encode the result to bytes using UTF-8
|
|
70
|
+
3. Apply Base64 encoding to the bytes
|
|
71
|
+
4. Decode back to string and prefix with "Basic "
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
Dict[str, str]: A dictionary containing the Authorization header.
|
|
75
|
+
Format: {'Authorization': 'Basic <base64-credentials>'}
|
|
76
|
+
|
|
77
|
+
Example:
|
|
78
|
+
>>> auth = BasicAuth('john', 'secret')
|
|
79
|
+
>>> header = auth.get_header()
|
|
80
|
+
>>> print(header)
|
|
81
|
+
{'Authorization': 'Basic am9objpzZWNyZXQ='}
|
|
82
|
+
"""
|
|
83
|
+
# Combine username and password with colon separator as per RFC 7617
|
|
84
|
+
credentials = f"{self.username}:{self.password}"
|
|
85
|
+
|
|
86
|
+
# Encode to bytes, then apply Base64 encoding
|
|
87
|
+
encoded = base64.b64encode(credentials.encode()).decode()
|
|
88
|
+
|
|
89
|
+
# Return the complete Authorization header
|
|
90
|
+
return {'Authorization': f'Basic {encoded}'}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Bearer Token Authentication Module
|
|
3
|
+
----------------------------------
|
|
4
|
+
This module provides Bearer Token authentication support for the AtomHTTP client.
|
|
5
|
+
|
|
6
|
+
Bearer Token authentication (also known as Token-based authentication) is widely
|
|
7
|
+
used in RESTful APIs, particularly with OAuth 2.0. The client sends a token
|
|
8
|
+
in the Authorization header to prove identity.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from typing import Dict
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BearerAuth:
|
|
15
|
+
"""
|
|
16
|
+
Bearer Token authentication handler for HTTP requests.
|
|
17
|
+
|
|
18
|
+
This class implements the Bearer Token authentication scheme as defined in
|
|
19
|
+
RFC 6750. It adds an Authorization header with the Bearer token to HTTP
|
|
20
|
+
requests, which is the standard way to authenticate with OAuth 2.0 and
|
|
21
|
+
many modern REST APIs.
|
|
22
|
+
|
|
23
|
+
How Bearer Auth Works:
|
|
24
|
+
1. Client obtains a token (JWT, opaque string, etc.) from an auth server
|
|
25
|
+
2. Token is sent in the Authorization header as "Bearer <token>"
|
|
26
|
+
3. Server validates the token and grants access if valid
|
|
27
|
+
|
|
28
|
+
Security Considerations:
|
|
29
|
+
- Tokens should be kept secure and never exposed in logs or URLs
|
|
30
|
+
- Tokens typically have expiration times for security
|
|
31
|
+
- Always use HTTPS to prevent token interception
|
|
32
|
+
- Consider implementing token refresh mechanisms
|
|
33
|
+
|
|
34
|
+
Attributes:
|
|
35
|
+
token (str): The bearer token string used for authentication
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
>>> auth = BearerAuth('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...')
|
|
39
|
+
>>> headers = auth.get_header()
|
|
40
|
+
>>> response = await client.get('/api/protected', headers=headers)
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def __init__(self, token: str):
|
|
44
|
+
"""
|
|
45
|
+
Initialize Bearer Token authentication with a token string.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
token (str): The bearer token string. This is typically a JWT
|
|
49
|
+
(JSON Web Token) or an opaque string provided by
|
|
50
|
+
the authentication server.
|
|
51
|
+
|
|
52
|
+
Note:
|
|
53
|
+
The token is stored in plain text in memory. Ensure proper
|
|
54
|
+
handling and cleanup of tokens when no longer needed.
|
|
55
|
+
|
|
56
|
+
Example:
|
|
57
|
+
>>> auth = BearerAuth('your-api-token-here')
|
|
58
|
+
"""
|
|
59
|
+
self.token = token
|
|
60
|
+
|
|
61
|
+
def get_header(self) -> Dict[str, str]:
|
|
62
|
+
"""
|
|
63
|
+
Generate the HTTP Authorization header for Bearer Token authentication.
|
|
64
|
+
|
|
65
|
+
This method creates the standard Authorization header format required
|
|
66
|
+
by RFC 6750 for Bearer token authentication. The token is prefixed
|
|
67
|
+
with "Bearer " to indicate the authentication scheme.
|
|
68
|
+
|
|
69
|
+
The resulting header format:
|
|
70
|
+
Authorization: Bearer <token>
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Dict[str, str]: A dictionary containing the Authorization header.
|
|
74
|
+
Format: {'Authorization': 'Bearer <token>'}
|
|
75
|
+
|
|
76
|
+
Example:
|
|
77
|
+
>>> auth = BearerAuth('abc123xyz')
|
|
78
|
+
>>> header = auth.get_header()
|
|
79
|
+
>>> print(header)
|
|
80
|
+
{'Authorization': 'Bearer abc123xyz'}
|
|
81
|
+
"""
|
|
82
|
+
# Return the Authorization header with Bearer scheme prefix
|
|
83
|
+
return {'Authorization': f'Bearer {self.token}'}
|