Skip to main content

Vexfox 🦊

Deterministic HTTP interaction recording, sanitization, and replay for Python tests.
Version 0.1.0 — Initial Pre-Release


The Problem

Modern applications depend heavily on external HTTP APIs: payment gateways, auth providers, AI platforms, and microservices. When testing code that calls these services, developers commonly face three frustrating trade-offs:

  1. Live API calls: Flaky test suites, network latency, unpredictable external service outages, and rate limit exhaustion.
  2. Manual mocks (unittest.mock): Tedious to write, prone to drift from real API behavior, and blind to actual HTTP protocol semantics.
  3. Legacy record/replay tools: Often monkey-patch global sockets, accidentally persist raw API keys and authentication tokens into git-tracked fixture files, or fail when query parameters change ordering.

The Vexfox Solution

Vexfox captures real HTTP traffic directly at the transport layer, scrubs sensitive credentials in-memory before writing fixtures to disk, and deterministically replays recorded responses during automated test runs with strictly zero network access.

               +-------------------------------------------+
               |        Your Application Code / Tests       |
               +-------------------------------------------+
                                     |
                               (HTTPX Calls)
                                     v
+-------------------------------------------------------------------------+
|                              VEXFOX                                     |
|                                                                         |
|  [Record Mode]                                    [Replay Mode]         |
|  1. Pass through to real API                      1. Normalize incoming |
|  2. Intercept response                               request            |
|  3. Scrub auth headers, tokens,                   2. Semantic matching  |
|     query secrets, JSON fields                       (method, URL,      |
|  4. Atomically persist to disk                       query, JSON body)  |
|                                                   3. Return response    |
|                                                   * STRICTLY OFFLINE *  |
+-------------------------------------------------------------------------+
            |                                             |
            v                                             v
  +-------------------+                         +-------------------+
  | Real External API |                         | Cassette Fixture  |
  +-------------------+                         | (Sanitized JSON)  |
                                                +-------------------+

Key Features

  • Zero Network Flakiness: In RecordMode.REPLAY, Vexfox guarantees that zero outbound network requests can escape.
  • Pre-Persistence Redaction: Secrets (passwords, auth tokens, session cookies, API keys) are scrubbed before cassette files touch the filesystem.
  • Semantic Request Matching: Matches HTTP requests by method, normalized URL, order-insensitive query parameters, and structural JSON bodies (whitespace and key-ordering independent).
  • HTTPX Native: Deep integration with both httpx.Client and httpx.AsyncClient via clean transport wrappers without invasive global socket monkey-patching.
  • Isolated Concurrency: Test contexts are isolated per thread and task using contextvars.
  • Pytest Plugin: First-class pytest fixture (vexfox) with automatic context cleanup.
  • CLI Management Toolkit: Inspect, list, and validate recorded cassette fixtures right from the command line.

Installation

pip install vexfox

System Requirements

  • Python: >= 3.11
  • HTTPX: >= 0.25.0

Verified Quick Start

Synchronous Client

import httpx
import vexfox

# First run: records the live response to fixtures/users.json with credentials redacted.
# Subsequent runs: deterministically replays the recorded response completely offline.
with vexfox.use_cassette("fixtures/users.json"):
    response = httpx.get("https://api.example.com/v1/users")
    assert response.status_code == 200

Asynchronous Client

import httpx
import vexfox


async def test_async_service():
    async with vexfox.use_cassette("fixtures/async_users.json"):
        async with httpx.AsyncClient() as client:
            response = await client.get("https://api.example.com/v1/users")
            assert response.status_code == 200

Recording Modes

Configure recording behavior explicitly using RecordMode:

from vexfox import RecordMode, use_cassette

with use_cassette("fixtures/orders.json", mode=RecordMode.REPLAY):
    ...
Mode Semantics
once (default) Records real interaction if cassette file does not exist; replays if it does.
record Always makes real network requests and updates/overwrites cassette data.
replay Strictly replays from existing cassette. Fails if cassette is missing or if an unrecorded request is made. Zero network calls allowed.
none Passthrough mode. Makes real network requests without recording or intercepting.

Security Boundaries & Redaction

Protecting sensitive credentials is a core design guarantee of Vexfox. Redaction is applied in-memory before writing to disk:

Default Scrubbed Targets

  1. Headers: Authorization, Proxy-Authorization, Cookie, Set-Cookie, X-Api-Key, X-Auth-Token, ApiKey.
  2. Query Parameters: api_key, token, secret, password, access_token, auth, client_secret.
  3. JSON Body Keys: Recursive traversal redacts password, secret, api_key, token, client_secret, private_key, access_token.
  4. Pattern Matching: High-entropy regex scanners identify and scrub Bearer tokens, OpenAI (sk-...), Stripe (sk_live_...), JWT tokens, and AWS access keys (AKIA...).
  5. Basic Auth URLs: URLs containing embedded credentials (https://user:pass@host/) are scrubbed to https://user:[REDACTED]@host/.

Customizing Redaction Rules

from vexfox import VexfoxConfig, use_cassette

config = VexfoxConfig(
    sensitive_headers={"x-organization-token", "x-internal-key"},
    sensitive_query_params={"session_token"},
    sensitive_body_keys={"ssn", "payment_method"},
    redaction_marker="[REDACTED]",
)

with use_cassette("fixtures/custom_auth.json", config=config):
    ...

Request Matching & Diagnostics

When replaying, incoming requests are compared against recorded interactions using semantic rules:

  1. HTTP Method: Case-insensitive match (GET, POST, PUT, DELETE, etc.).
  2. Normalized URL: Normalizes scheme, port, and trailing slashes.
  3. Query Parameters: Order-insensitive comparison while preserving duplicate query parameters.
  4. Request Body:
    • JSON (application/json): Compared structurally. Key ordering, indentations, and whitespace formatting do not cause false mismatches.
    • Text / Binary: Byte-accurate matching.
  5. Headers (Optional): Specific header matching can be enabled via match_headers=("content-type",).

Secret-Safe Diagnostics

If an incoming request does not match any interaction in the cassette, Vexfox produces a detailed diagnostic failure report without leaking any query secrets or token parameters:

vexfox.exceptions.RequestMismatchError: No matching recorded interaction found for request: POST https://api.example.com/items

Mismatch diagnostics:
  - Interaction #1: JSON body mismatch at key 'role': expected 'member', got 'superadmin'

Recorded interactions in cassette:
  * [1] POST https://api.example.com/items

Pytest Integration

Vexfox automatically registers a vexfox pytest fixture:

import httpx


def test_user_profile(vexfox):
    with vexfox("fixtures/user_profile.json"):
        response = httpx.get("https://api.example.com/profile")
        assert response.status_code == 200

Command-Line Toolkit

Vexfox includes a command-line tool for inspecting and verifying cassette files:

# Verify environment and system readiness
vexfox doctor

# List recorded cassettes in a directory with interaction counts
vexfox list ./fixtures

# Inspect cassette interactions (status, methods, sanitized URLs)
vexfox inspect fixtures/users.json

# Validate cassette JSON schema integrity
vexfox validate fixtures/users.json

Supported Workflows & Known Boundaries

  • Supported Clients: Currently targets HTTPX (httpx.Client and httpx.AsyncClient).
  • Binary Payloads: Preserved accurately using base64 encoding with explicit is_binary metadata.
  • Multipart Uploads: Captured as binary payloads in the current release. Custom field-level multipart parsing and per-field masking is scheduled for v0.2.
  • Cassette Format: Persists using standard JSON (Schema v1) with atomic file writes to prevent corrupted fixture files during interrupted test runs.
  • No Global Monkey-Patching: Interception is handled cleanly via transport wrappers without altering Python's global socket module.

Testing & Contributing

We welcome contributions! Please review CONTRIBUTING.md and SECURITY.md before submitting pull requests.

# Clone the repository
git clone https://github.com/TanishJain13/Vexfox.git
cd vexfox

# Install with test dependencies
pip install -e ".[test]"

# Run test suite
pytest

# Run linter and formatting checks
ruff check .
ruff format --check .

License

MIT License. See LICENSE for details.

Metadata

Release files for vexfox 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vexfox 0.1.0
File Size Uploaded Provenance Actions
vexfox-0.1.0.tar.gz 32.3 kB With provenance Details for vexfox-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for vexfox 0.1.0
File Interpreter ABI Platform Actions
vexfox-0.1.0-py3-none-any.whl Python 3 none any Details for vexfox-0.1.0-py3-none-any.whl

Total release size: 58.0 kB

Release files / vexfox-0.1.0.tar.gz

Download URL vexfox-0.1.0.tar.gz
Size 32.3 kB
Tags Source
SHA-256 checksum
How to use checksums
f329ba55feb68cb790d44791224b07235c84673774633aa9687dfdb8198ff6a6
BLAKE2b-256 checksum
How to use checksums
ff7c9672a24072d55c4b9fa69725fd545d16d57dbaa24ad63319331ad52782f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Release files / vexfox-0.1.0-py3-none-any.whl

Download URL vexfox-0.1.0-py3-none-any.whl
Size 25.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3dc7e34d2371b7e834d1b4d423937311365bcdf044fb0cf1884d938acca50679
BLAKE2b-256 checksum
How to use checksums
8a065db8d351b64850ed590713af3da21d43f895a7d198d068e18fe2d11d2f44
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

Security for vexfox 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for vexfox-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 28, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page