api
Version: 6.8.5
wexample-api provides an AbstractGateway base class for building typed HTTP API client gateways in Python. It wraps requests with built-in rate limiting, configurable timeout, status-code validation, exponential-backoff retries, and structured error reporting via wexample-prompt, so a concrete gateway only needs to declare a base_url and call make_request. The package targets Python developers who integrate third-party REST APIs and want to centralise connection handling, logging, and error propagation without writing the same boilerplate for each service.
Table of Contents
- Installation
- Quickstart
- Tests
- Architecture
- Integration in the Suite
- Dependencies
- Versioning & Compatibility Policy
- License
- About us
- Known Limitations & Roadmap
- Status & Compatibility
- Useful Links
- Migration Notes
Installation
pip install wexample-api
Requires Python >=3.10.
Quickstart
Install the package:
pip install wexample-api
Subclass AbstractGateway, pass base_url and an IoManager, then call make_request:
from wexample_api.common.abstract_gateway import AbstractGateway
from wexample_api.enums.http import HttpMethod
from wexample_helpers.decorator.base_class import base_class
from wexample_prompt.common.io_manager import IoManager
@base_class
class JsonPlaceholderGateway(AbstractGateway):
def get_post(self, post_id: int) -> dict | None:
response = self.make_request(
endpoint=f"/posts/{post_id}",
method=HttpMethod.GET,
expected_status_codes=200,
)
return response.json() if response else None
gateway = JsonPlaceholderGateway(
base_url="https://jsonplaceholder.typicode.com",
io=IoManager(),
)
post = gateway.get_post(1)
print(post["title"])
# sunt aut facere repellat provident occaecati excepturi optio reprehenderit
make_request returns the raw requests.Response when the actual status code is in expected_status_codes, or None when it is not. Omitting expected_status_codes accepts any response. The @base_class decorator is required: AbstractGateway uses wexample_helpers field initialisation that depends on it.
A runnable, annotated version of this example lives at examples/common/http_request_example.py.
Tests
This project uses pytest for testing and pytest-cov for code coverage analysis.
Installation
First, install the required testing dependencies:
.venv/bin/python -m pip install pytest pytest-cov
Basic Usage
Run all tests with coverage:
.venv/bin/python -m pytest --cov --cov-report=html
Common Commands
# Run tests with coverage for a specific module
.venv/bin/python -m pytest --cov=your_module
# Show which lines are not covered
.venv/bin/python -m pytest --cov=your_module --cov-report=term-missing
# Generate an HTML coverage report
.venv/bin/python -m pytest --cov=your_module --cov-report=html
# Combine terminal and HTML reports
.venv/bin/python -m pytest --cov=your_module --cov-report=term-missing --cov-report=html
# Run specific test file with coverage
.venv/bin/python -m pytest tests/test_file.py --cov=your_module --cov-report=term-missing
Viewing HTML Reports
After generating an HTML report, open htmlcov/index.html in your browser to view detailed line-by-line coverage information.
Coverage Threshold
To enforce a minimum coverage percentage:
.venv/bin/python -m pytest --cov=your_module --cov-fail-under=80
This will cause the test suite to fail if coverage drops below 80%.
Architecture
wexample-api ships one thing: AbstractGateway, a base class callers subclass to build typed HTTP clients. The rest of the package feeds that class — enums for the HTTP vocabulary, a payload dataclass that carries each request's parameters, two error types for the failure modes gateways commonly signal, and a demo subclass that shows the pattern in use.
Modules
| File | Owns |
|---|---|
| src/wexample_api/common/abstract_gateway.py | AbstractGateway — the only class callers subclass |
| src/wexample_api/common/http_request_payload.py | HttpRequestPayload — value object assembled for each call |
| src/wexample_api/enums/http.py | HttpMethod, ContentType, Header enums |
| src/wexample_api/const/http.py | HTTP_METHOD_MAP — string-to-HttpMethod lookup |
| src/wexample_api/errors/gateway_connexion_error.py | GatewayConnectionError |
| src/wexample_api/errors/gateway_authentication_error.py | GatewayAuthenticationError |
| src/wexample_api/demo/demo_simple_gateway.py | DemoSimpleGateway — concrete subclass used in tests |
src/wexample_api/middleware/ and src/wexample_api/models/ are currently empty; they are stubs reserved for a planned rework documented in .wex/journal/todo/abstract-gateway-rework.md.
AbstractGateway
AbstractGateway inherits three mixins from wexample-helpers and wexample-prompt:
WithIoManager— exposesself.iofor structured terminal output (debug,error,properties)HasTwoStepInit— two-phase initialisation;setup()is the second phaseHasSnakeShortClassNameClassMixin—get_class_name_suffixstrips"GatewayService"from derived class names
Its public fields control the request lifecycle:
base_url— prepended to every endpointdefault_headers— merged into every call's header dictconnected/rate_limit_delay/timeout— connection and throttle configurationquiet— suppresses non-error log lines whenTruelast_exception/last_request_time— per-instance mutable state written after each call
Concrete subclasses declare domain methods (e.g. get_user, create_item) and delegate to self.make_request.
HttpRequestPayload
HttpRequestPayload is the internal transfer object for one HTTP call. make_request constructs it with HttpRequestPayload.from_endpoint(), which joins base_url and endpoint (stripping duplicate slashes) and coerces a bare int in expected_status_codes to a one-element list. The payload object then travels into handle_api_response, where it provides the URL, method, data, and call_origin for log lines and error details.
Call path through make_request
-
Retry wrapper. If
retries > 0, the call is handed toRetryableCallbackManagerfromwexample-helpers, which re-invokesmake_requestwithraise_exceptions=Trueand exponential back-off (backoff_base_seconds=3), retrying only onGatewayError. -
Payload assembly.
HttpRequestPayload.from_endpoint()constructs the full URL and normalises the status-code argument. -
Connection. If
self.connectedisFalse,connect()is called; the base implementation sets the flag and returnsTrue. Subclasses override this to perform real handshakes. -
Rate limiting.
_handle_rate_limiting()sleeps as needed so that consecutive calls are at leastrate_limit_delayseconds apart. -
Body dispatch. The content type of the merged headers determines how the body travels:
files=for multipart,data=forapplication/x-www-form-urlencoded,application/octet-stream, andtext/plain,json=for everything else (including when noContent-Typeis set). -
HTTP call.
requests.request(**request_kwargs)executes the call. OnRequestException, aGatewayErroris created, stored inlast_exception, and passed tohandle_api_responsewithresponse=None; ifraise_exceptions=Truethe error is raised instead. -
Status validation. If
expected_status_codeswas supplied and the response status is not in the set, aGatewayErroris created (and raised immediately whenraise_exceptions=True). -
Response handling.
handle_api_responselogs the outcome viaself.ioand returns therequests.Responseobject, orNonewhen the call failed andfatal_on_errorisFalse. Whenfatal_on_errorisTrue, it callsself.io.error(..., fatal=True), which terminates the process.
Errors
Both GatewayConnectionError and GatewayAuthenticationError subclass GatewayError from wexample-helpers. AbstractGateway.make_request itself raises only GatewayError; the two subclasses are available for concrete gateways that need callers to distinguish the failure mode.
External dependencies
AbstractGateway calls requests.request directly — the requests library is the only HTTP transport. wexample-prompt supplies IoManager for all output. wexample-helpers supplies RetryableCallbackManager, GatewayError, and the class infrastructure (base_class decorator, public_field, HasTwoStepInit).
Integration in the Suite
This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.
Related Packages
The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.
Visit the Wexample Suite documentation for the complete package ecosystem.
Dependencies
- attrs: >=23.1.0
- cattrs: >=23.1.0
- requests:
- wexample-helpers: >=20.1.0
- wexample-prompt: >=15.1.0
Versioning & Compatibility Policy
Wexample packages follow Semantic Versioning (SemVer):
- MAJOR: Breaking changes
- MINOR: New features, backward compatible
- PATCH: Bug fixes, backward compatible
We maintain backward compatibility within major versions and provide clear migration guides for breaking changes.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Free to use in both personal and commercial projects.
About us
Wexample stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.
This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.
Wexample cultivates a culture of mastery. Each package, each contribution carries the mark of a community that values precision, ethics, and innovation — a community proud to shape the future of digital craftsmanship.
Known Limitations & Roadmap
Current limitations and planned features are tracked in the GitHub issues.
See the project roadmap for upcoming features and improvements.
Status & Compatibility
Maturity: Production-ready
Python Support: >=3.10
OS Support: Linux, macOS, Windows
Status: Actively maintained
Useful Links
- Homepage: https://github.com/wexample/python-api
- Documentation: docs.wexample.com
- Issue Tracker: https://github.com/wexample/python-api/issues
- Discussions: https://github.com/wexample/python-api/discussions
- PyPI: pypi.org/project/wexample-api
Migration Notes
When upgrading between major versions, refer to the migration guides in the documentation.
Breaking changes are clearly documented with upgrade paths and examples.
Metadata
Release files for wexample-api 6.8.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| wexample_api-6.8.5.tar.gz | 17.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wexample_api-6.8.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.0 kB
Release files / wexample_api-6.8.5.tar.gz
| Download URL | wexample_api-6.8.5.tar.gz |
|---|---|
| Size | 17.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c590faaa78ade654576fe2a3b8d0776abead8127bf6c9300cc9b160cc2fca77a
|
|
BLAKE2b-256 checksum How to use checksums |
555698836c6f159838bd91a43ad1c8608d507996995a699386b98431398dc2a1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.25.9 CPython/3.12.3 Linux/6.8.0-139-generic
|
Release files / wexample_api-6.8.5-py3-none-any.whl
| Download URL | wexample_api-6.8.5-py3-none-any.whl |
|---|---|
| Size | 14.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ff5ca99cccd3ef2d8e82c7a2f219521d05d37f7629c9dd766893861c12892c58
|
|
BLAKE2b-256 checksum How to use checksums |
5a31636e53cbc133dc54f1084ee44d4cdd7a033009c9967c9c66d0f8bdac945e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
pdm/2.25.9 CPython/3.12.3 Linux/6.8.0-139-generic
|