Skip to main content

Start a local mock REST API server from an OpenAPI 3.x spec. Convention: reads ~/.openapi/spec.yaml by default.

Project description

apiup

⚡ Start a local mock REST API server from an OpenAPI 3.x spec — one command.

CI PyPI Python License: CC BY-NC-SA 4.0

Install

pip install apiup

With uv:

uv tool install apiup

With validation support:

pip install 'apiup[validate]'

Convention: ~/.openapi/

apiup follows an XDG-style user convention — place your default spec at:

~/.openapi/spec.json      ← preferred
~/.openapi/spec.yaml      ← fallback

Optional config:

# ~/.openapi/config.yaml
port: 8080
host: 127.0.0.1
mode: mock
spec: ~/.openapi/spec.json

Usage

apiup                          # reads ~/.openapi/spec.json, starts on :8080
apiup --spec ./my-api.yaml     # custom spec path
apiup --port 9000              # custom port
apiup --host 0.0.0.0           # bind all interfaces
apiup --list                   # list routes without starting server
apiup --validate               # validate spec against OpenAPI 3.x schema
apiup --version
apiup --help

Example session

$ apiup --validate
   Validating: /home/roebi/.openapi/spec.json
   OpenAPI   : 3.0.3
   Title     : My API v1.0.0
   ✓ spec valid  (7 route(s))

$ apiup --list
Routes in: /home/roebi/.openapi/spec.json

  GET      /skills        # List all skills
  POST     /skills        # Create a new skill
  GET      /skills/{id}   # Get skill details
  DELETE   /skills/{id}   # Delete a skill

4 route(s) found.

$ apiup
⚡ apiup 0.6.0 — My API v1.0.0
   Spec  : /home/roebi/.openapi/spec.json
   Mode  : mock
   Listen: http://127.0.0.1:8080
   Docs  : http://127.0.0.1:8080/docs
   Spec  : http://127.0.0.1:8080/spec.json
   Routes: 4

$ curl http://localhost:8080/skills
[{"id": "create-agent-skill-en", "name": "Create Agent Skill", "version": "1.0.0"}]

Built-in endpoints

Every apiup instance exposes two additional routes:

Endpoint Description
GET /docs Swagger UI (no extra dependencies)
GET /spec.json Raw OpenAPI spec served directly

Mock behaviour

In mock mode apiup:

  • Registers one route handler per [METHOD] /path in the spec
  • Returns the first example value found in the spec responses
  • Falls back to {"_mock": true, "note": "no example in spec"} if none present
  • Returns 204 No Content with no body for routes that declare it
  • Resolves local $ref pointers in spec components

Add example: fields to your spec responses to get real data back:

/skills:
  get:
    responses:
      "200":
        content:
          application/json:
            example:
              - id: create-agent-skill-en
                name: Create Agent Skill
                version: "1.0.0"

Server modes

Mode Status Description
mock ✓ available returns spec examples
proxy planned forwards requests to a real backend
record planned proxy + saves real responses as spec examples

Validation

pip install 'apiup[validate]'
apiup --validate
apiup --validate --spec ./my-api.yaml

# use in CI — exits 1 if spec is invalid
apiup --validate || exit 1

Requires openapi-spec-validator. If not installed, --validate warns but does not block startup.

Python API

from apiup.spec import load_spec, extract_routes
from apiup.mock import extract_mock_response
from apiup.server import build_mock_app, serve
from apiup.config import load_config

cfg    = load_config(spec="./my-api.yaml", port=9000)
spec   = load_spec(cfg.spec)
routes = extract_routes(spec)
app    = build_mock_app(routes, spec, cfg.spec)
serve(app, host=cfg.host, port=cfg.port)

Development

uv sync --all-extras
uv run pytest
uv run ruff check .
uv run ruff format .

License

CC BY-NC-SA 4.0 — see LICENSE.

Part of the roebi agent-skills ecosystem.

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

apiup-0.7.0.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

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

apiup-0.7.0-py3-none-any.whl (11.8 kB view details)

Uploaded Python 3

File details

Details for the file apiup-0.7.0.tar.gz.

File metadata

  • Download URL: apiup-0.7.0.tar.gz
  • Upload date:
  • Size: 10.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for apiup-0.7.0.tar.gz
Algorithm Hash digest
SHA256 097b758161b2f9940029a292f92701a4e9da8a91b8c26eb1dce22a0831a32c29
MD5 d28896ae614b4789b7c8c732d9d43240
BLAKE2b-256 6e95414cde68d71e29568f8da3a0afa2dc52ac5bde6d4c2d51c235b36a3d5fb6

See more details on using hashes here.

File details

Details for the file apiup-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: apiup-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 11.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for apiup-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6a1697fd8bee5175f74de59b1acd35523e2391654f492b0736b8124078aaf2fc
MD5 6032aeed982ed35330e6d0d40f46f0a6
BLAKE2b-256 ebc930e056d7d172c24f24cc2bcf7f5acc5067b7fae62c97be89bf3297263c06

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