A next generation HTTP client for Python 3 with HTTP/2 support, async/await capabilities, and requests-compatible API.
—
URL handling, headers management, query parameters, cookies, and other data structures used throughout the HTTP client. These models provide powerful and flexible ways to work with HTTP data while maintaining type safety and providing convenient access patterns.
Comprehensive URL parsing, manipulation, and validation with support for international domains and relative URLs.
class URL:
def __init__(self, url, allow_relative=False, params=None):
"""
Create a URL object with parsing and validation.
Parameters:
- url (URLTypes): URL string or URL object
- allow_relative (bool): Whether to allow relative URLs (default: False)
- params (QueryParamTypes, optional): Query parameters to append
Raises:
InvalidURL: If URL is malformed or missing required components
"""
@property
def scheme(self) -> str:
"""URL scheme (http, https, etc.)."""
@property
def authority(self) -> str:
"""URL authority (host:port)."""
@property
def username(self) -> str:
"""Username from URL authority."""
@property
def password(self) -> str:
"""Password from URL authority."""
@property
def host(self) -> str:
"""Hostname."""
@property
def port(self) -> int:
"""Port number (defaults to 80 for http, 443 for https)."""
@property
def path(self) -> str:
"""URL path."""
@property
def query(self) -> str:
"""Query string."""
@property
def full_path(self) -> str:
"""Path with query string."""
@property
def fragment(self) -> str:
"""URL fragment."""
@property
def is_ssl(self) -> bool:
"""True if URL uses HTTPS."""
@property
def is_absolute_url(self) -> bool:
"""True if URL is absolute (has scheme and host)."""
@property
def is_relative_url(self) -> bool:
"""True if URL is relative."""
@property
def origin(self) -> "Origin":
"""Origin object for this URL."""
def copy_with(self, **kwargs) -> "URL":
"""
Create a copy with modified components.
Parameters:
- **kwargs: URL components to modify (scheme, host, path, etc.)
Returns:
URL: New URL with modifications
"""
def join(self, relative_url) -> "URL":
"""
Join with a relative URL.
Parameters:
- relative_url (URLTypes): Relative URL to join
Returns:
URL: New absolute URL
"""Usage Example:
import http3
# Basic URL creation
url = http3.URL('https://api.example.com/users?limit=10')
print(url.scheme) # 'https'
print(url.host) # 'api.example.com'
print(url.path) # '/users'
print(url.query) # 'limit=10'
# URL with parameters
url = http3.URL('https://api.example.com/search', params={'q': 'python', 'limit': 5})
print(url) # 'https://api.example.com/search?q=python&limit=5'
# URL manipulation
base_url = http3.URL('https://api.example.com')
full_url = base_url.join('/users/123')
print(full_url) # 'https://api.example.com/users/123'
# URL modification
modified = url.copy_with(path='/v2/search', port=8080)
print(modified) # 'https://api.example.com:8080/v2/search?q=python&limit=5'Represents the origin (scheme + host + port) of a URL.
class Origin:
def __init__(self, url):
"""Create an Origin from a URL."""
@property
def scheme(self) -> str:
"""Origin scheme."""
@property
def host(self) -> str:
"""Origin host."""
@property
def port(self) -> int:
"""Origin port."""
@property
def is_ssl(self) -> bool:
"""True if origin uses SSL/TLS."""Case-insensitive HTTP headers container with comprehensive manipulation methods.
class Headers:
def __init__(self, headers=None):
"""
Create a headers container.
Parameters:
- headers (HeaderTypes, optional): Initial headers
"""
def __getitem__(self, key: str) -> str:
"""Get header value (case-insensitive)."""
def __setitem__(self, key: str, value: str):
"""Set header value (case-insensitive)."""
def __delitem__(self, key: str):
"""Delete header (case-insensitive)."""
def __contains__(self, key: str) -> bool:
"""Check if header exists (case-insensitive)."""
def __iter__(self):
"""Iterate over header names."""
def get(self, key: str, default=None):
"""
Get header value with default.
Parameters:
- key (str): Header name (case-insensitive)
- default: Default value if header not found
Returns:
Header value or default
"""
def get_list(self, key: str) -> List[str]:
"""
Get all values for a header as a list.
Parameters:
- key (str): Header name (case-insensitive)
Returns:
list: All values for the header
"""
def update(self, headers):
"""
Update headers with new values.
Parameters:
- headers (HeaderTypes): Headers to merge
"""
def keys(self):
"""Get all header names."""
def values(self):
"""Get all header values."""
def items(self):
"""Get (name, value) pairs."""Usage Example:
import http3
# Create headers
headers = http3.Headers({
'Content-Type': 'application/json',
'Authorization': 'Bearer token123'
})
# Case-insensitive access
print(headers['content-type']) # 'application/json'
print(headers['CONTENT-TYPE']) # 'application/json'
# Header manipulation
headers['User-Agent'] = 'MyApp/1.0'
del headers['authorization']
# Check for headers
if 'Content-Type' in headers:
content_type = headers.get('Content-Type', 'text/plain')
# Multiple values (e.g., Set-Cookie)
headers = http3.Headers([
('Set-Cookie', 'session=abc123'),
('Set-Cookie', 'user=john')
])
cookies = headers.get_list('Set-Cookie') # ['session=abc123', 'user=john']Flexible query parameter handling with encoding and multiple value support.
class QueryParams:
def __init__(self, params=None):
"""
Create a query parameters container.
Parameters:
- params (QueryParamTypes, optional): Initial parameters
"""
def __getitem__(self, key: str) -> str:
"""Get parameter value."""
def __setitem__(self, key: str, value: str):
"""Set parameter value."""
def __delitem__(self, key: str):
"""Delete parameter."""
def __contains__(self, key: str) -> bool:
"""Check if parameter exists."""
def __iter__(self):
"""Iterate over parameter names."""
def get(self, key: str, default=None):
"""
Get parameter value with default.
Parameters:
- key (str): Parameter name
- default: Default value if parameter not found
Returns:
Parameter value or default
"""
def get_list(self, key: str) -> List[str]:
"""
Get all values for a parameter as a list.
Parameters:
- key (str): Parameter name
Returns:
list: All values for the parameter
"""
def update(self, params):
"""
Update parameters with new values.
Parameters:
- params (QueryParamTypes): Parameters to merge
"""
def keys(self):
"""Get all parameter names."""
def values(self):
"""Get all parameter values."""
def items(self):
"""Get (name, value) pairs."""Usage Example:
import http3
# Create query parameters
params = http3.QueryParams({'q': 'python', 'limit': '10'})
# Alternative creation methods
params = http3.QueryParams([('q', 'python'), ('category', 'programming')])
params = http3.QueryParams('q=python&limit=10')
# Parameter access
search_term = params['q']
limit = params.get('limit', '20')
# Multiple values
params = http3.QueryParams([
('tag', 'python'),
('tag', 'web'),
('tag', 'api')
])
tags = params.get_list('tag') # ['python', 'web', 'api']
# Use with URL
url = http3.URL('https://api.example.com/search', params=params)Comprehensive cookie handling with persistence and automatic management.
class Cookies:
def __init__(self, cookies=None):
"""
Create a cookies container.
Parameters:
- cookies (CookieTypes, optional): Initial cookies
"""
def __getitem__(self, key: str) -> str:
"""Get cookie value."""
def __setitem__(self, key: str, value: str):
"""Set cookie value."""
def __delitem__(self, key: str):
"""Delete cookie."""
def __contains__(self, key: str) -> bool:
"""Check if cookie exists."""
def __iter__(self):
"""Iterate over cookie names."""
def get(self, name: str, default=None, domain=None, path=None):
"""
Get cookie value with optional domain/path filtering.
Parameters:
- name (str): Cookie name
- default: Default value if cookie not found
- domain (str, optional): Filter by domain
- path (str, optional): Filter by path
Returns:
Cookie value or default
"""
def set(self, name: str, value: str, domain=None, path=None):
"""
Set cookie with optional domain/path.
Parameters:
- name (str): Cookie name
- value (str): Cookie value
- domain (str, optional): Cookie domain
- path (str, optional): Cookie path
"""
def delete(self, name: str, domain=None, path=None):
"""
Delete cookie with optional domain/path filtering.
Parameters:
- name (str): Cookie name
- domain (str, optional): Filter by domain
- path (str, optional): Filter by path
"""
def clear(self, domain=None, path=None):
"""
Clear cookies with optional domain/path filtering.
Parameters:
- domain (str, optional): Filter by domain
- path (str, optional): Filter by path
"""
def update(self, cookies):
"""
Update cookies with new values.
Parameters:
- cookies (CookieTypes): Cookies to merge
"""
def keys(self):
"""Get all cookie names."""
def values(self):
"""Get all cookie values."""
def items(self):
"""Get (name, value) pairs."""Usage Example:
import http3
# Create cookies
cookies = http3.Cookies({'session': 'abc123', 'user': 'john'})
# Alternative creation
cookies = http3.Cookies([('session', 'abc123'), ('preferences', 'dark-mode')])
# Cookie access
session_id = cookies['session']
user = cookies.get('user', 'anonymous')
# Cookie manipulation
cookies['theme'] = 'dark'
del cookies['session']
# Domain-specific cookies
cookies.set('tracking', 'enabled', domain='.example.com')
tracking = cookies.get('tracking', domain='.example.com')
# Use with client
client = http3.Client(cookies=cookies)Flexible type aliases for various data inputs:
# URL types
URLTypes = Union[URL, str]
# Query parameter types
QueryParamTypes = Union[
QueryParams,
Mapping[str, str],
List[Tuple[Any, Any]],
str
]
# Header types
HeaderTypes = Union[
Headers,
Dict[AnyStr, AnyStr],
List[Tuple[AnyStr, AnyStr]]
]
# Cookie types
CookieTypes = Union[Cookies, CookieJar, Dict[str, str]]
# Authentication types
AuthTypes = Union[
Tuple[Union[str, bytes], Union[str, bytes]], # Basic auth
Callable[[AsyncRequest], AsyncRequest] # Custom auth
]
# Request data types
RequestData = Union[dict, str, bytes, Iterator[bytes]]
AsyncRequestData = Union[dict, str, bytes, AsyncIterator[bytes]]
# File upload types
RequestFiles = Dict[str, Union[
IO[AnyStr], # Simple file
Tuple[str, IO[AnyStr]], # (filename, file)
Tuple[str, IO[AnyStr], str] # (filename, file, content_type)
]]
# Response content types
ResponseContent = Union[bytes, Iterator[bytes]]
AsyncResponseContent = Union[bytes, AsyncIterator[bytes]]import http3
# International domain names
url = http3.URL('https://пример.рф/path')
print(url.host) # Automatically converted to ASCII
# URL normalization
url = http3.URL('HTTPS://Example.COM:443/Path/../Other')
print(url) # Normalized formimport http3
# Custom headers for specific use cases
headers = http3.Headers()
headers['X-API-Key'] = 'secret-key'
headers['X-Request-ID'] = 'req-123'
# Handle multi-value headers
headers.update([
('Accept', 'application/json'),
('Accept', 'text/plain')
])
# Get all Accept values
accept_types = headers.get_list('Accept')import http3
# Complex parameter structures
params = http3.QueryParams([
('filter[status]', 'active'),
('filter[type]', 'user'),
('sort', 'created_at'),
('include[]', 'profile'),
('include[]', 'permissions')
])
url = http3.URL('https://api.example.com/users', params=params)
# Results in: https://api.example.com/users?filter%5Bstatus%5D=active&...Install with Tessl CLI
npx tessl i tessl/pypi-http3