Skip to main content
harspec

Turn any website's network traffic into an OpenAPI spec and typed API clients. One command, zero dependencies.

tests PyPI Python License: MIT

Install · Documentation · What you get · How it works · Write a generator · Contributing

Python 3.9+ · No dependencies · Works offline · Secrets redacted automatically


See it in action

Terminal demo of harspec capture.har

You record traffic in your browser, save it as a .har file, and run harspec. You get documentation and ready-to-use client code for an API that never had any.

capture.har goes through harspec and becomes openapi.yaml, TypeScript and Python clients, curl examples, a Postman collection and an auth summary

Get started

  1. Install it (Python 3.9 or newer):
    pip install harspec
    
  2. Record traffic. Open the site, press F12, go to the Network tab, use the app normally (log in, search, save something), then right click in the list and choose Save all as HAR with content.
  3. Run it:
    harspec capture.har
    
  4. Open harspec-out/. Import openapi.yaml into Swagger UI, Postman or Insomnia, or copy client.ts / client.py into your project.

No HAR file handy? Try the bundled sample: harspec examples/sample.har.

What you get

File What it is
openapi.yaml OpenAPI 3.0.3: paths, path and query parameters (required or optional), request and response schemas per status code, examples, security schemes
client.ts Typed fetch client with an interface for every request and response
client.py requests-based client with a method per endpoint
examples.sh One runnable curl command per endpoint
postman_collection.json Postman v2.1 collection grouped by resource
AUTH.md Auth summary: schemes in use, how to obtain a token, CSRF headers, cookies

Using the generated client:

from client import Client

api = Client(token="YOUR_TOKEN")
pets = api.get_pets(params={"limit": 10})
pet = api.get_pet(42)
import { Client } from "./client";

const api = new Client({ token: "YOUR_TOKEN" });
const pets = await api.getPets({ limit: 10 }); // fully typed

How it works

Stage What happens
1. Parse and filter Reads the HAR, drops html, js, css, images, fonts and CORS preflights, keeps API calls
2. Redact Removes secrets immediately, before anything else sees the data
3. Group endpoints Turns /users/42/posts/7 into /users/{user_id}/posts/{post_id}
4. Infer schemas Merges every sample of a request or response into one schema
5. Detect auth Finds Bearer, Basic, API-key and session-cookie auth, login endpoints and CSRF headers
6. Generate Builds the OpenAPI spec, then every output format is produced from that spec

What the inference does with your samples:

Seen in the capture Result in the spec
Field present in every sample required
Field missing in some samples optional
null in some samples nullable: true
integer in one sample, decimal in another number
string in one sample, number in another oneOf
UUID, date-time, email, URL strings format: uuid / date-time / email / uri
Numeric, UUID, hash or date path segments path parameter
Same path, different status codes one response entry per status

Privacy and redaction

Redaction runs while the HAR is parsed, so a secret can never reach a generator, the spec or an example.

Where What is redacted
Headers Authorization (scheme kept, value removed), Cookie and Set-Cookie (names kept, values removed), API-key and CSRF headers
JSON, form and query values Any field named like password, token, secret, api_key, session, csrf, card, otp
Anywhere in a string JWTs

harspec makes no network requests. Everything runs on your machine. A test checks that none of the secrets from the sample HAR appear in any output file. Business data inside example values is not redacted, so skim the output before publishing it.

Command line

harspec capture.har [options]
Option Meaning
-o, --out DIR Output directory (default harspec-out)
-f, --formats LIST Comma list: typescript,python,curl,postman (default all)
--host HOST Use one host from a multi-host capture (default: the busiest)
--title TEXT Title for the OpenAPI document
--json Write openapi.json instead of openapi.yaml
--no-cluster Disable detection of mixed IDs such as sku123
--include-static Keep html, js, css and images
--list-generators Show available generators, including plugins

Write a generator

A generator is a function from the OpenAPI dictionary to {filename: content}:

from harspec.generators import register

@register("routes", "List of METHOD /path lines")
def routes(spec):
    lines = [f"{m.upper()} {p}" for p, item in spec["paths"].items() for m in item]
    return {"routes.txt": "\n".join(lines)}

Built-in generators in harspec/generators/ are about 60 lines each. Ship yours as a separate package through the harspec.generators entry-point group and harspec loads it automatically.

Wanted generators (good first pull requests): Go, Rust, Kotlin, Swift, Dart, Java, C#, PHP and Ruby clients, Bruno, Insomnia, k6 load tests, Playwright API tests, WireMock or MSW mock servers, Zod and Pydantic models, Markdown API docs.

Compatibility

Tested Result
Python 3.12 on Linux 16 unit tests pass
Generated client.ts Compiles with tsc --strict
Generated client.py Compiles; uses requests at runtime
openapi.yaml Parses with PyYAML and round-trips
Python 3.9, 3.11, 3.13, Windows, macOS Run by CI on every push (3.9, 3.11, 3.13); not yet verified by hand

HAR files from Chrome, Edge, Firefox and Safari DevTools all follow the same format. Some tools omit response bodies; then you only get paths and parameters.

Limitations

  • The spec describes what you captured. Unseen endpoints, fields and error shapes are not in it. More traffic gives a better spec.
  • "Required" means "present in every sample", which is a guess.
  • GraphQL calls appear as one POST /graphql operation; per-query modelling is on the roadmap.
  • WebSocket traffic is ignored.
  • The result is a draft. Review it before building on it.

Roadmap

  • GraphQL operation extraction
  • harspec diff old.har new.har to detect API changes
  • Mock server from the generated spec
  • Pagination and rate-limit header detection
  • Merge several HAR files into one spec
  • More generators (see the wanted list above)

Development

git clone https://github.com/AYUSH-PANDEY023/harspec.git
cd harspec
python -m unittest discover -s tests -v     # run the tests
python examples/make_sample_har.py          # rebuild the sample capture
python -m harspec examples/sample.har       # run from source

There are no dependencies to install. Optional: tsc to type-check generated TypeScript, PyYAML to run the YAML round-trip test.

Contributing

Contributions are welcome, from typo fixes to new generators. Read CONTRIBUTING.md first. If harspec produces a wrong spec for a real capture, please open an issue with a redacted snippet of the traffic, what you expected, and what you got.

Use harspec only on traffic you are allowed to capture and APIs you are allowed to call. Check the terms of service of the service you are analysing. harspec is not affiliated with any other project that uses a similar name.

License

MIT. Free to use, modify and distribute.

Thank you

Thank you for trying harspec. If it saved you an afternoon, a star helps other developers find it.

Metadata

Release files for harspec 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 harspec 0.1.0
File Size Uploaded Provenance
harspec-0.1.0.tar.gz 26.8 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 52.9 kB

Release files / harspec-0.1.0.tar.gz

Download URL harspec-0.1.0.tar.gz
Size 26.8 kB
Tags Source
SHA-256 checksum
How to use checksums
e3fb1483a7eeb2f82fb9e7a8493373dc9cb04e79bb86113ddf747cab8e00f147
BLAKE2b-256 checksum
How to use checksums
177ae147e3b79a24c1afd47716f46157d52804f6be28cc7ec2e1e448d43f57b0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

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

Download URL harspec-0.1.0-py3-none-any.whl
Size 26.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a1bd57ca8904dd836ee6b47598f020ebc61365b3c76e8f1dd7bfb236b4264bcf
BLAKE2b-256 checksum
How to use checksums
439414deb6e318ccd7434083b75d2c80086b54163848c7c090f2cff008c6fbde
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Security for harspec 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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No 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