Skip to main content

NyaProxy

A lightweight API gateway for services that authenticate with API keys, bearer tokens, or custom request headers.

English | 简体中文 | 日本語

NyaProxy Banner

Centralize credential injection, quota-aware routing, rate limiting, retries, and observability for any HTTP API that uses keys or tokens.

License PyPI version Python versions PyPI Downloads Docker Pulls Ask DeepWiki
Code Coverage CodeQL & Dependencies Scan CI/CD Builds

Overview

NyaProxy sits between your applications and upstream APIs. Applications call NyaProxy with an internal proxy key; NyaProxy forwards each request to the configured upstream with the correct upstream credentials, rotating across a pool of keys while enforcing rate limits, retries, and path policies.

It is useful when a team needs one place to manage access to external or internal APIs such as AI providers, image generation APIs, SaaS APIs, data vendors, or private services.

Use NyaProxy only with credentials and traffic patterns that are allowed by the upstream service terms.

Features

Feature Description Config
Credential injection Add upstream credentials through headers without exposing them to clients headers, variables
Credential pooling Route traffic across multiple upstream keys or tokens variables.<name>
Load balancing round_robin, random, least_requests, fastest_response, and weighted selection load_balancing_strategy, key_weights
Rate limiting Endpoint, upstream key, client IP, and proxy user limits rate_limit
Queueing Hold requests until configured quota becomes available queue
Retry and failover Retry selected status codes, cool down the failing key, and rotate to the next one retry
Key quarantine Temporarily remove credentials that return configured upstream error statuses key_blocking
Request policy Allow or block paths and methods before forwarding allowed_paths, allowed_methods
Body transformation Set or remove JSON fields with conditional JMESPath rules request_body_substitution
Observability Web dashboard plus a Prometheus /metrics endpoint dashboard
Outbound proxy Send upstream traffic through an optional HTTP/SOCKS proxy server.proxy

Quick Start

Install From PyPI

pip install nya-proxy
nyaproxy

On first run, NyaProxy creates a starter config.yaml in the current directory and listens on 127.0.0.1:8080.

Important: the starter config has no server.api_key, so authentication is disabled. This is safe only while bound to loopback. Set server.api_key before using --host 0.0.0.0 or otherwise exposing the service.

Then open:

  • http://<host>:8080/config — configuration UI with validation
  • http://<host>:8080/dashboard — metrics, request history, and queue status
  • http://<host>:8080/info — configured API list and service status

Run With Your Own Config

nyaproxy --config config.yaml

Config changes made through the /config UI (or to the file, once you re-save through the UI) trigger an automatic restart so they take effect immediately. Pass --no-reload to disable the file-watch supervisor for production setups where restarts should be explicit.

Install From Source

git clone https://github.com/Nya-Foundation/nyaproxy.git
cd nyaproxy
pip install -e .
nyaproxy          # or: python -m nya

Docker

mkdir -p data
cp configs/openai.yaml data/config.yaml  # then replace every placeholder key

docker run -d \
  -p 8080:8080 \
  -v ${PWD}/data:/app \
  --user "$(id -u):$(id -g)" \
  k3scat/nya-proxy:latest --config /app/config.yaml --host 0.0.0.0

Mount the directory, not config.yaml itself. Saving from the /config UI writes a temporary file and renames it over the target, and that rename fails with EBUSY against a bind-mounted file, so every save returns a 500. The mount must also be writable — a read-only mount blocks saves for the same reason.

--user runs the container as you, since the image runs as uid 100 and could not otherwise write a directory you own. Docker Desktop on macOS and Windows maps ownership for you, so you can drop that flag there.

The directory holds config.yaml and .nya_state.json, which carries rate-limit windows and key cool-downs across restarts so a config change does not reset your quotas. Edit configuration on the host or through the /config UI; either way NyaProxy restarts itself to apply it. Do not publish the port until server.api_key is set.

CLI Reference

Flag Description
--config, -c Path to the configuration file
--host, -H / --port, -p Bind address and port (defaults: 127.0.0.1 / 8080; environment: SERVER_HOST / SERVER_PORT)
--no-reload Disable the config file-watch supervisor; config changes then require a manual restart
--check-config Validate schema and cross-field configuration, then exit
--remote-url, -r / --remote-api-key, -k / --remote-app-name, -a Pull configuration from a remote config server instead of a local file (disables the local /config UI)
--version Print the version and exit

Configuration

NyaProxy is configured with a single YAML file, validated against a bundled JSON schema. Ready-made examples live in configs/.

Settings under default_settings apply to every API; any API block can override them. For IDE autocomplete and inline validation, keep this modeline as the first line of your config (the shipped examples already include it):

# yaml-language-server: $schema=https://raw.githubusercontent.com/Nya-Foundation/NyaProxy/main/nya/schema.json

A minimal working config:

server:
  api_key:
    - your_admin_proxy_key        # first key = master key (dashboard + config UI)
    - your_application_proxy_key  # additional keys for regular proxy traffic
  logging:
    enabled: true
    level: info
    log_file: app.log
  dashboard:
    enabled: true

default_settings:
  key_variable: keys
  load_balancing_strategy: round_robin
  queue:
    max_size: 200
    max_workers: 10
    expiry_seconds: 300
  rate_limit:
    enabled: true
    endpoint_rate_limit: 1000/h
    key_rate_limit: 60/m
    ip_rate_limit: 5000/d
    user_rate_limit: 5000/d
  retry:
    enabled: true
    attempts: 3
    retry_after_seconds: 1
    retry_status_codes: [429, 500, 502, 503, 504]
  key_blocking:
    enabled: true
    status_codes: [401, 403]
    duration_seconds: 300
  timeouts:
    request_timeout_seconds: 300

apis:
  example_service:
    name: Example Service
    endpoint: https://api.example.com/v1
    aliases:
      - example
    key_variable: keys
    headers:
      Authorization: "Bearer ${{keys}}"
    variables:
      keys:
        - upstream_key_1
        - upstream_key_2

Request Format

Requests are forwarded through /api/<api_name>/<path> — or /api/<alias>/<path> for an alias. Aliases are route segments such as example, not paths such as /example.

With the config above, this proxy request:

POST http://localhost:8080/api/example_service/messages

is forwarded to:

POST https://api.example.com/v1/messages

with Authorization: Bearer <one of your upstream keys> injected, chosen by the load balancer.

Load Balancing

Five strategies are available per API via load_balancing_strategy:

  • round_robin (default) — cycle through keys in order
  • random — pick a key at random
  • least_requests — pick the key that has served the fewest requests
  • fastest_response — pick the key with the lowest average response time
  • weighted — distribute according to key_weights

For weighted, weights align with the order of the key list:

apis:
  example_service:
    load_balancing_strategy: weighted
    key_weights: [3, 1, 1]   # first key gets 3x the traffic of the others
    variables:
      keys: [key_a, key_b, key_c]

Rate Limiting

Four independent limiter scopes:

  • endpoint_rate_limit — total request rate for one upstream API
  • key_rate_limit — request rate for each upstream credential
  • ip_rate_limit — request rate per client IP
  • user_rate_limit — request rate per proxy API key

Formats: 10/s, 60/m, 1000/h, 5000/d, 1/15s (one request per 15 seconds), or "0" for unlimited. Requests over the limit wait in a per-API queue (bounded by queue.max_size) until quota frees up or queue.expiry_seconds passes; clients that exceed the IP/user quota get 429 with a Retry-After header. rate_limit_paths restricts which paths count against the limits (prefix match with a trailing *).

Retries and Failover

When an upstream response matches retry_status_codes (and the method is in retry_request_methods), NyaProxy cools the failing key down for retry_after_seconds, rotates to the next available key, and retries up to attempts times — without blocking other traffic on the same API. If every attempt fails, the client receives 429; upstream connection failures and timeouts surface as 502 and 504 respectively.

Key Quarantine

key_blocking can temporarily remove a credential from selection when the upstream returns any configured HTTP error status. It is disabled by default; a common setup enables it for 401 and 403 so an expired or revoked credential is not selected again for duration_seconds. This policy is independent of retries: add the same status to retry.retry_status_codes only when the current request should also fail over to another credential.

API Examples

Generic Bearer Token API

apis:
  data_vendor:
    name: Data Vendor API
    endpoint: https://api.vendor.example/v2
    key_variable: tokens
    headers:
      Authorization: "Bearer ${{tokens}}"
    variables:
      tokens:
        - vendor_token_1
        - vendor_token_2
    rate_limit:
      enabled: true
      endpoint_rate_limit: 5000/d
      key_rate_limit: 60/m

Custom Header API

apis:
  internal_service:
    name: Internal Service
    endpoint: https://internal.example.com
    key_variable: service_tokens
    headers:
      X-Service-Token: "${{service_tokens}}"
      X-Client-Name: "nyaproxy"
    variables:
      service_tokens:
        - service_token_1
        - service_token_2

OpenAI-Compatible API

apis:
  openai_compatible:
    name: OpenAI-Compatible Provider
    endpoint: https://api.provider.example/v1
    key_variable: keys
    headers:
      Authorization: "Bearer ${{keys}}"
    variables:
      keys:
        - provider_key_1
        - provider_key_2
    allowed_paths:
      enabled: true
      mode: whitelist
      paths:
        - "/chat/*"
        - "/images/*"
    request_body_substitution:
      enabled: true
      rules:
        - name: "Remove unsupported field"
          operation: remove
          path: "frequency_penalty"
          conditions:
            - field: "frequency_penalty"
              operator: "exists"

Streaming responses (SSE and chunked transfer) are forwarded transparently, so OpenAI-style stream: true requests work as-is.

Request Body Substitution

Substitution rules can set or remove JSON fields before forwarding — useful for provider compatibility, default values, and policy enforcement:

request_body_substitution:
  enabled: true
  rules:
    - name: "Cap temperature"
      operation: set
      path: "temperature"
      value: 0.7
      conditions:
        - field: "temperature"
          operator: "gt"
          value: 0.7

See Request Body Substitution for the full rule syntax.

Endpoints

Endpoint Auth Purpose
/api/<api_name>/<path> proxy key Proxy requests to configured upstream APIs
/config master key Edit and validate configuration in the browser
/dashboard master key Metrics, request history, key usage, and queue state; queues can be cleared and metrics reset
/health none Liveness check for load balancers and orchestrators
/info none Configured API list and service status
/metrics none Prometheus exposition endpoint

Operations

  • Logging — configured under server.logging; enabled: false disables both console and file sinks. The log file rotates at 10 MB with the last 5 files retained. debug logs request/response metadata (with secrets redacted).
  • Config reload — a config change triggers a full process restart via the file-watch supervisor. In-flight requests are dropped and in-memory state (queues, rate-limit windows, metrics) resets. Use --no-reload if you'd rather restart explicitly.
  • State — all rate limiting, queueing, and metrics state is in-memory and per-process. Run a single instance per credential pool; running replicas would give each its own independent limits.

Security Notes

  • If server.api_key is not set, authentication is disabled entirely — every endpoint (including the config UI) is open to anyone who can reach the port. The default bind is loopback; always set a key before selecting a public bind with --host or SERVER_HOST.
  • server.trusted_proxies controls which proxy IPs or CIDR networks may supply client-IP forwarding headers. Leave it empty unless NyaProxy is behind a proxy you control.
  • The first key in server.api_key is the master key, required for the dashboard and configuration UI. Additional keys can be handed to applications for proxy traffic only.
  • Do not share upstream provider credentials with clients — keep them in the NyaProxy config or your deployment's secret manager.
  • Restrict server.cors.allow_origins to trusted origins when browsers call the proxy with credentials.
  • Use allowed_paths and allowed_methods to limit what clients can call.

Deployment Guides

Project Status

NyaProxy is in active development. Configuration and behavior may change between releases. Pin a tested version for production deployments and review the changelog before upgrading.

Community

License

NyaProxy is released under the MIT License.

Download files

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

Source Distribution

nya_proxy-0.8.1.tar.gz (162.8 kB view details)

Uploaded Source

Built Distribution

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

nya_proxy-0.8.1-py3-none-any.whl (170.4 kB view details)

Uploaded Python 3

File details

Details for the file nya_proxy-0.8.1.tar.gz.

File metadata

  • Download URL: nya_proxy-0.8.1.tar.gz
  • Upload date:
  • Size: 162.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for nya_proxy-0.8.1.tar.gz
Algorithm Hash digest
SHA256 66ca9c5450914fbbad1bf5976af2c86c095fad24fb0f3dd153c301e2fa6650a8
MD5 3813db643a738b0b66dc9d9c730a7a0e
BLAKE2b-256 7560685fa49849388dbe503acf7861802e6b85187b35bf3c8a7fe71c5d08f64f

See more details on using hashes here.

Provenance

The following attestation bundles were made for nya_proxy-0.8.1.tar.gz:

Publisher: publish.yml on Nya-Foundation/NyaProxy

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

File details

Details for the file nya_proxy-0.8.1-py3-none-any.whl.

File metadata

  • Download URL: nya_proxy-0.8.1-py3-none-any.whl
  • Upload date:
  • Size: 170.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for nya_proxy-0.8.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c8261e950022d1ea84ceae2ddd4dd3ad118fd12fe447c3b32502e229c1342b6d
MD5 5b9adb6088510a5181826e76aa10c9df
BLAKE2b-256 cef82b26c819c08654d0ca434b72ade968d8847804fb00ac90a79e2525ff28d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for nya_proxy-0.8.1-py3-none-any.whl:

Publisher: publish.yml on Nya-Foundation/NyaProxy

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

Release history Release notifications | RSS feed

0.8.2

2 files

This release

0.8.1 This release

2 files

0.8.0

2 files

0.7.2

2 files

0.7.1

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.6

2 files

0.4.5

2 files

0.4.4

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.6

2 files

0.3.5

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

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