Skip to main content

kopya

Record your app's real API calls once. Replay them offline, forever.

kopya (Filipino for "copy") is a single static binary that sits between your app and the internet. Run your test suite once against the real API, and every call after that is served from a fixture file — no network, no API bill, no flakes.

$ kopya record -- pytest tests/
...
kopya recorded 47 calls → .kopya/fixtures.json
  Secrets were redacted. Review the file before committing it.

$ kopya replay -- pytest tests/
kopya loaded 47 recorded calls from .kopya/fixtures.json
...
kopya replayed 47 calls · 0 live
  Saved ~128,400 tokens and 94.2s.

Your application code does not change. No mock library, no dependency injection, no monkeypatching.

Why

Tests that hit OpenAI, Anthropic, Stripe or any other third-party API are slow, nondeterministic, and cost real money. The existing answers all have a catch: language -bound mock libraries only cover one runtime, and the proxy-based tools need Python or a JVM in your CI image.

kopya is one ~7MB binary with no runtime. It boots instantly in a container and works the same for Python, Node, Go, Rust, Ruby, Java or curl.

Install

Whichever ecosystem you already have. All three install the same prebuilt binary — there is no Node or Python runtime involved once it is on disk.

npx @kopya/cli --help     # Node
uvx kopya --help          # Python
cargo install kopya       # Rust

(The npm package is scoped @kopya/cli; the installed command is still kopya.)

Or grab a binary from the releases page. Prebuilt for macOS (Intel and Apple Silicon), Linux (x64 and arm64, statically linked against musl) and Windows x64.

How it works

kopya runs an HTTP/HTTPS proxy on 127.0.0.1 and launches your command with the proxy and CA environment variables already set:

Variable Why
HTTP_PROXY / HTTPS_PROXY Routes traffic through kopya
NODE_USE_ENV_PROXY=1 Node's built-in fetch ignores HTTP_PROXY without it
NODE_EXTRA_CA_CERTS Node uses its own CA bundle, not the system keychain
REQUESTS_CA_BUNDLE Python requests / httpx use certifi
SSL_CERT_FILE, CURL_CA_BUNDLE OpenSSL and curl

This matters: trusting a root CA in the system keychain is not enough for Node, Python or Java. Setting these per-process is what makes "zero code changes" actually true. If you point an already-running process at kopya instead, run kopya ca trust and export the variables it prints.

Commands

kopya record -- <command>     # run <command>, save its outbound calls
kopya replay -- <command>     # run <command> against the saved calls
kopya ca path                 # print the root CA path (creates it on first run)
kopya ca trust                # install the root CA into the system trust store
kopya ca untrust              # remove it

Useful flags:

  • --out / --in — fixture file path (default .kopya/fixtures.json)
  • --port — proxy port (default 8888)
  • --allow-live — let unmatched requests reach the network instead of failing
  • --realtime — reproduce the original timing of recorded streams
  • --no-redact — keep credentials in the fixture. Don't.

Running kopya record or kopya replay with no -- command starts the proxy in the foreground so you can point an existing process at it.

Streaming responses

text/event-stream responses — every streaming LLM API — are recorded frame by frame, with the offset each frame arrived at, and replayed with those boundaries intact. A recording is passed through to your app live as it happens, so the run you record behaves exactly like an unproxied one.

By default replay emits the frames as fast as the client will take them, because the point of replay is to make a slow test fast:

recorded   7 frames over 1015ms
replayed   7 frames over 7ms          # 145x faster, same frames
replayed   7 frames over 1012ms       # with --realtime

Use --realtime when the thing under test is the streaming behaviour itself — time-to-first-token, incremental rendering, or a client-side timeout.

Token usage is parsed out of the final frame, so the summary can report what a replayed run would have cost.

Strict by default

In replay, a request with no recorded match returns 502 and fails the run, even if your test swallowed the error. A green replay run therefore proves the suite is genuinely hermetic. Pass --allow-live when you want the softer behaviour.

Fixtures are meant to be committed

The fixture file is the artifact your team shares, so it is designed to survive code review:

  • Headers are stored in sorted maps and bodies as plain text, so diffs stay readable
  • Credentials are redacted before anything touches disk — Authorization, Cookie, x-api-key and friends, plus bare sk-/ghp_/AKIA-style tokens found in bodies
  • Binary payloads are dropped rather than base64-inflating the file

Always read a fixture before committing it the first time. Redaction is conservative by design, not a guarantee.

Status

Early. 0.1 covers HTTP/1.1 record and replay, including server-sent event streams, with redaction, response decompression and strict matching.

Roadmap: HTTP/2, a GitHub Action, Homebrew, request-count assertions, and latency + error injection.

Not planned for 0.1: gRPC, WebSocket, a GUI, declarative YAML rule files.

License

Licensed under the Apache License, Version 2.0.

Contributions are accepted under the same license, per section 5 of the Apache 2.0 terms — no separate CLA.

Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

kopya-0.1.1-py3-none-win_amd64.whl (3.3 MB view details)

Uploaded Python 3Windows x86-64

kopya-0.1.1-py3-none-manylinux_2_39_x86_64.whl (3.6 MB view details)

Uploaded Python 3manylinux: glibc 2.39+ x86-64

kopya-0.1.1-py3-none-manylinux_2_39_aarch64.whl (3.3 MB view details)

Uploaded Python 3manylinux: glibc 2.39+ ARM64

kopya-0.1.1-py3-none-macosx_11_0_arm64.whl (3.2 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

kopya-0.1.1-py3-none-macosx_10_12_x86_64.whl (3.5 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file kopya-0.1.1-py3-none-win_amd64.whl.

File metadata

  • Download URL: kopya-0.1.1-py3-none-win_amd64.whl
  • Upload date:
  • Size: 3.3 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for kopya-0.1.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 e73dadeb5c5b684411a65aa29567578f70168e87d0776e7679e2c10d0635ebd5
MD5 fb3c8d15c62b8557e9b4e9f6141008d4
BLAKE2b-256 afd956b2013de7abbc3dad625699d0b9045103989cd434277129a61aea801e7e

See more details on using hashes here.

Provenance

The following attestation bundles were made for kopya-0.1.1-py3-none-win_amd64.whl:

Publisher: release.yml on thinkgrid-labs/kopya

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file kopya-0.1.1-py3-none-manylinux_2_39_x86_64.whl.

File metadata

File hashes

Hashes for kopya-0.1.1-py3-none-manylinux_2_39_x86_64.whl
Algorithm Hash digest
SHA256 3ead6cdec4241f8e7464d907ef6bb6d5c7c1ef162fab323389a12fb36b1225e9
MD5 aa6160c32663f67bbf95601d3d4b7a88
BLAKE2b-256 df3794d0bbb9e211a78496f5668535f0fbf41bff133b6294060dd7e5a1c8af45

See more details on using hashes here.

Provenance

The following attestation bundles were made for kopya-0.1.1-py3-none-manylinux_2_39_x86_64.whl:

Publisher: release.yml on thinkgrid-labs/kopya

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file kopya-0.1.1-py3-none-manylinux_2_39_aarch64.whl.

File metadata

File hashes

Hashes for kopya-0.1.1-py3-none-manylinux_2_39_aarch64.whl
Algorithm Hash digest
SHA256 4750f16707161ec0ffad02236dfbb3dc2283119dc99867c9726b9a998bee996c
MD5 65db5f8e512e05678a3c1d06d2cc232e
BLAKE2b-256 90fb4140a14b46ef72c3ceb8787989b06a78201a7541f77ff8d323e3980d0ec7

See more details on using hashes here.

Provenance

The following attestation bundles were made for kopya-0.1.1-py3-none-manylinux_2_39_aarch64.whl:

Publisher: release.yml on thinkgrid-labs/kopya

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file kopya-0.1.1-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: kopya-0.1.1-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 3.2 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for kopya-0.1.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2d86fabc7bf2ff223fd191c108cf7d1cd851ed986ec84eed38a3a4bbe5e0278b
MD5 e11967eefb9ca1f97c851aeea956750e
BLAKE2b-256 dc1c5435712b29b2c97dc309f88bea12baa09ace5afd25c50273e39820fbf16d

See more details on using hashes here.

Provenance

The following attestation bundles were made for kopya-0.1.1-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on thinkgrid-labs/kopya

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file kopya-0.1.1-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for kopya-0.1.1-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f8bd3d9b7cbae35fe531cb35c84b977818a8273aff03c63023dd0de485920b2c
MD5 3d9271905d81f779e6f03426a8814157
BLAKE2b-256 0be2609b67435eb807255eb01874c1ac091fe4f55ab1e316800bbbc6e20b4c95

See more details on using hashes here.

Provenance

The following attestation bundles were made for kopya-0.1.1-py3-none-macosx_10_12_x86_64.whl:

Publisher: release.yml on thinkgrid-labs/kopya

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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