Async API testing framework with pluggable authentication for Python 3.12+
Project description
test-api-x
Async API testing framework with pluggable authentication for Python 3.12+
Requirements
- Python 3.12 or higher
- Poetry 1.5+ (for development)
Installation
pip install test-api-x
Features
- Async HTTP Client: Built on httpx with automatic retries and timeout handling
- Secure Logging: Automatic credential masking with correlation IDs for request tracing
- Fluent Assertions: Chainable assertions for response validation
- Enhanced Response: Rich response objects with JSON path queries and validation
- Pluggable Authentication: Support for Basic Auth and Auth0 with automatic session management
- User Registry: Multi-persona authentication with pool-based organization and environment variable substitution
- Factory Methods: Ergonomic client creation with built-in authentication
- Plugin System: Extensible architecture for custom fixtures and authentication providers
Quick Start
Basic Usage
from test_api_x import Client, assert_that
async with Client(base_url="https://api.example.com") as client:
response = await client.get("/users")
assert_that(response).has_status(200).has_json_path("users")
With Authentication
from test_api_x import Client
# Basic Authentication
async with Client.with_basic_auth(
username="admin",
password="secret123",
base_url="https://api.example.com"
) as client:
response = await client.get("/protected")
assert_that(response).has_status(200)
# Auth0 Authentication
async with Client.with_auth0(
domain="your-tenant.auth0.com",
client_id="your-client-id",
client_secret="your-client-secret",
username="user@example.com",
password="password",
base_url="https://api.example.com"
) as client:
response = await client.get("/protected")
assert_that(response).has_status(200)
With User Registry
from test_api_x import UserRegistry, Client
# Load users from YAML
registry = UserRegistry.from_yaml("users.yaml")
# Get client for specific persona
async with Client.from_registry(
registry=registry,
persona="admin",
base_url="https://api.example.com"
) as client:
response = await client.get("/admin/users")
assert_that(response).has_status(200)
Logging
test-api-x includes secure logging with automatic credential masking to prevent sensitive data leaks.
Basic Usage
from test_api_x import get_logger
logger = get_logger("my_module")
logger.info("Starting test execution")
Automatic Request/Response Logging
The Client automatically logs all HTTP requests and responses with correlation IDs for tracing:
import os
os.environ["TESTAPIX_LOG_LEVEL"] = "DEBUG"
async with Client(base_url="https://api.example.com") as client:
# Automatically logs request/response with correlation ID
response = await client.post("/auth", json={
"username": "admin",
"password": "secret123" # Automatically masked in logs
})
Credential Masking
Sensitive data is automatically detected and masked in:
- HTTP headers (Authorization, X-API-Key, etc.)
- Request/response bodies (password, token, api_key fields)
- URLs (query parameters and basic auth)
Masked data appears as ***REDACTED*** in logs.
Log Levels
Set the log level via environment variable:
export TESTAPIX_LOG_LEVEL=DEBUG # DEBUG, INFO, WARNING, ERROR
User Registry
Manage multiple test users with different personas and authentication methods.
Basic YAML Structure
users:
- user_id: admin_user
persona: admin
auth_method: basic
username: admin
password: admin123
- user_id: auth0_user
persona: standard_user
auth_method: auth0
domain: your-tenant.auth0.com
client_id: your-client-id
client_secret: your-client-secret
username: user@example.com
password: password
Pool-Based Organization
Organize users into pools for different environments:
pools:
dev:
users:
- user_id: dev_admin
persona: admin
auth_method: basic
username: dev_admin
password: dev_pass
staging:
users:
- user_id: staging_admin
persona: admin
auth_method: basic
username: staging_admin
password: staging_pass
Usage:
# Get user from specific pool
async with Client.from_registry(
registry=registry,
persona="admin",
pool="staging",
base_url="https://staging-api.example.com"
) as client:
response = await client.get("/users")
Environment Variable Substitution
Use environment variables for sensitive credentials:
users:
- user_id: admin_user
persona: admin
auth_method: basic
username: ${ADMIN_USERNAME}
password: ${ADMIN_PASSWORD}
The registry automatically substitutes ${VAR_NAME} with environment variable values.
Plugin System
Extend test-api-x with custom fixtures and authentication providers.
Using Plugins
from test_api_x.plugins import PluginManager
# Automatically discover installed plugins
manager = PluginManager()
manager.discover_plugins()
# Use plugin fixtures
helper = manager.get_fixture("example_helper")()
result = helper.greet("World")
Creating Plugins
from test_api_x.plugins import Plugin
class MyPlugin(Plugin):
@property
def name(self) -> str:
return "my_plugin"
def register_fixtures(self) -> dict:
return {"my_helper": self._my_helper_fixture}
def register_auth_providers(self) -> dict:
return {}
def _my_helper_fixture(self):
return MyHelper()
See Plugin Development Guide for details.
Response Assertions
Validate API responses with fluent assertions:
# Status code assertions
assert_that(response).has_status(200)
assert_that(response).has_status_in_range(200, 299)
# JSON assertions
assert_that(response).has_json_matching({"status": "success"})
assert_that(response).has_json_path("data.users[0].id")
# Header assertions
assert_that(response).has_header("Content-Type", "application/json")
# Response time assertions
assert_that(response).responded_within(1000) # milliseconds
Development
Setup
# Clone the repository
git clone https://github.com/yourusername/test-api-x.git
cd test-api-x
# Install dependencies
poetry install
Running Quality Checks
# Run all tests (285 tests, 96.50% coverage)
poetry run pytest
# Run only unit tests (up to 198 tests)
poetry run pytest -m unit
# Run only integration tests (21 tests)
poetry run pytest -m integration
# Run tests with coverage report
poetry run pytest --cov=src/test_api_x --cov-report=html
# Format code
poetry run black src/ tests/
# Lint code
poetry run ruff check src/ tests/
# Type check
poetry run mypy src/
Development Workflow
The project includes a pre-commit hook that automatically runs:
- Black code formatting check
- Ruff linting
- MyPy type checking
All checks must pass before commits are accepted.
Project Status
Phase 3 In Progress - Plugin system implemented
Completed:
- Core HTTP client with retries and timeout handling
- Enhanced response objects with JSON path queries
- Fluent assertion API
- Secure logging with automatic credential masking
- Correlation IDs for request tracing
- Pluggable authentication system (Basic Auth, Auth0)
- Session management with automatic caching
- User registry with multi-persona support
- Pool-based user organization
- Environment variable substitution
- Factory methods for ergonomic client creation
- Plugin system with entry point discovery
- 96.50% test coverage (285 tests: 198 unit, 21 integration)
Coming Soon:
- Official plugins (AWS, Database, Mocking)
- Enhanced retry strategies
- Request/response middleware
- Performance optimizations
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file test_api_x-0.3.0.tar.gz.
File metadata
- Download URL: test_api_x-0.3.0.tar.gz
- Upload date:
- Size: 27.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.4 CPython/3.12.8 Darwin/24.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9fa0df1216be8bd99c73f7350a4b79fc62b382173df6d55c3f9580d83e186bf
|
|
| MD5 |
ecd9ea012d4d725c0351107ca222919e
|
|
| BLAKE2b-256 |
afab5d5e542c07f6ad9ccdd541a011cd07b3b31e42d8306d5a987e868518b163
|
File details
Details for the file test_api_x-0.3.0-py3-none-any.whl.
File metadata
- Download URL: test_api_x-0.3.0-py3-none-any.whl
- Upload date:
- Size: 33.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.4 CPython/3.12.8 Darwin/24.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ebf9fad904fc76e0d2eae4bcae4b9cfe350fd9920d1bb6ff1b0738cd129ad977
|
|
| MD5 |
67bf1055c64a21a266e3f0c76646e0e6
|
|
| BLAKE2b-256 |
1c440f005304e04b2c729878adc49c7254c742890d6588919b706e9a627b12f8
|