Skip to main content

Async API testing framework with pluggable authentication for Python 3.12+

Project description

test-api-x

PyPI version Python 3.12+ License: MIT Tests Coverage

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

test_api_x-0.3.0.tar.gz (27.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

test_api_x-0.3.0-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

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

Hashes for test_api_x-0.3.0.tar.gz
Algorithm Hash digest
SHA256 a9fa0df1216be8bd99c73f7350a4b79fc62b382173df6d55c3f9580d83e186bf
MD5 ecd9ea012d4d725c0351107ca222919e
BLAKE2b-256 afab5d5e542c07f6ad9ccdd541a011cd07b3b31e42d8306d5a987e868518b163

See more details on using hashes here.

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

Hashes for test_api_x-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ebf9fad904fc76e0d2eae4bcae4b9cfe350fd9920d1bb6ff1b0738cd129ad977
MD5 67bf1055c64a21a266e3f0c76646e0e6
BLAKE2b-256 1c440f005304e04b2c729878adc49c7254c742890d6588919b706e9a627b12f8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page