A CLI tool to generate .http files and Kulala-compatible environment files from OpenAPI specs.
- Generate HTTP request collections (.http) from OpenAPI 3.x specs
- Generate http-client.env.json and http-client.private.env.json skeletons from security schemes
- Inspect specs: summary, paths, and request/response samples
- Batch process directories of spec files
Generated .http files and environment files work with:
- âś… Kulala (Neovim): Full support including environment files and BASE_URL management
- âś… PyCharm/IntelliJ IDEA: Full support with JetBrains HTTP Client
- âś… httpyac (VS Code): Full support - use the httpyac extension for complete environment file support
⚠️ VS Code REST Client: Limited support - environment variables need manual setup in.vscode/settings.json
Note: BASE_URL is now managed per-environment in the http-client.env.json files instead of shared blocks in the HTTP files.
Requires Python 3.13+
# From the project root (pick one)
pip install -e .
# or using uv
uv pip install -e .This will install the httpfilegen command.
If you're using NixOS with Home Manager, you can use the provided flake:
# In your home.nix
{
imports = [
# Import the httpfilegen Home Manager module
inputs.httpfilegen.homeManagerModules.httpfilegen
];
programs.httpfilegen = {
enable = true;
# Configure default CLI options (optional)
defaults = {
mode = "default"; # or "kulala", "pycharm", "vscode"
filemode = "single";
baseUrl = "https://api.example.com";
envName = "dev";
includeExamples = true;
includeSchema = false;
};
};
}Then enter the development shell:
cd /path/to/httpfilegen
nix developOr install the package system-wide:
nix build
nix profile install ./resultThe Home Manager module creates a config file at ~/.config/httpfilegen/config.toml with your configured defaults (see Configuration section above).
httpfilegen --helphttpfilegen supports configuration files for setting default CLI options. The config file is located at ~/.config/httpfilegen/config.toml.
Create or edit ~/.config/httpfilegen/config.toml:
# Editor mode for optimized behavior
# Options: default, kulala, pycharm, vscode
mode = "default"
# Default file generation mode
# Options: single, multi
filemode = "single"
# Default base URL for generated files
base_url = "https://api.example.com"
# Default environment name
env_name = "dev"
# Default include options
include_examples = false
include_schema = false- CLI arguments always take precedence over config file defaults
- Only non-provided CLI options will use config defaults
- Config file is optional - httpfilegen works without it
- Invalid config files are ignored with a warning
With the above config, this command:
httpfilegen generate spec.yamlIs equivalent to:
httpfilegen generate spec.yaml --mode default --filemode single --base-url https://api.example.com --env-name devBut you can still override any option:
httpfilegen generate spec.yaml --filemode multi --include-exampleshttpfilegen generate path/to/openapi.yaml \
--out path/to/output.http \
--env-name dev \
--overwrite- By default, an output file is created next to the spec with the same basename and .http extension.
- Add
--no-envto skip environment files.
Options of interest:
--filemode, -f: Generation mode.SINGLE(default) writes one .http file.MULTIwrites one .http per API path and mirrors the path structure as directories.--base-url: Optional base URL to include in environment files. This creates an additional environment alongside any servers defined in the spec.--include-examples/--no-include-examples: Include commented response examples next to each request.--include-schema/--no-include-schema: Include commented request body examples (based on provided examples or schema fallback) next to each request.--dry-run: Preview output without writing any files. Shows what would be generated.
Examples:
Single file with an explicit base URL:
httpfilegen generate path/to/openapi.yaml \
--out api.http \
--base-url https://api.example.comMulti-file output (one per path) under a directory derived from the output name:
httpfilegen generate path/to/openapi.yaml \
--out api.http \
--filemode MULTI
# Creates ./api/<path-segments>/index.httpMulti-file with explicit base URL and env files under the same directory tree:
httpfilegen generate path/to/openapi.yaml \
--out api.http \
--filemode MULTI \
--base-url https://api.example.com \
--include-schema \
--include-examples \
--envhttpfilegen env path/to/openapi.yaml \
--env-name dev \
--out-dir ./Environment files:
http-client.env.json(public)http-client.private.env.json(secrets and variables)
Basic info:
httpfilegen info path/to/openapi.yamlList paths (optionally filter by method):
httpfilegen paths path/to/openapi.yaml --method get --method postShow request/response samples for a specific path:
httpfilegen sample path/to/openapi.yaml \
"/users/{id}" \
--method get \
--content-type application/json \
--status 200Validate an OpenAPI spec without generating any files:
httpfilegen validate path/to/openapi.yamlFor CI/CD pipelines, use JSON output:
httpfilegen validate path/to/openapi.yaml --jsonReturns exit code 0 on success, 1 on failure.
Preview what would be generated without writing any files:
httpfilegen generate path/to/openapi.yaml --dry-runThis shows the first 100 lines of the generated .http file and lists any env files that would be created.
httpfilegen batch path/to/specs \
--pattern "*.json,*.yaml,*.yml" \
--filemode MULTI \
--base-url https://api.example.com \
--env-name dev \
--overwriteThis scans the directory for matching specs and generates .http (+ env files) for each.
You can also import and use the generator in Python code:
# filepath: examples/programmatic.py
from pathlib import Path
from http_file_generator import HtttpFileGenerator
from http_file_generator.models import HttpSettings, Filemode
spec = Path("path/to/openapi.yaml")
out = Path("path/to/output.http")
# Single file with optional base URL and response examples
from pydantic_core import Url
settings = HttpSettings(filemode=Filemode.SINGLE, baseURL=Url("https://api.example.com"), include_examples=True, include_schema=True)
http_file_generator = HtttpFileGenerator(spec, settings=settings)
http_file_generator.to_http_file(out)
# Multi-file output under a directory mirroring API paths
# http_file_generator = HtttpFileGenerator(spec, settings=HttpSettings(filemode=Filemode.MULTI))
# http_file_generator.to_http_file(Path("api.http")) # creates ./api/<segments>/index.http
# Optional env files
public_env = out.parent / "http-client.env.json"
private_env = out.parent / "http-client.private.env.json"
http_file_generator.to_env_files(public_env, private_env, env_name="dev")- Generated env files follow the schemas used by Kulala. Private env contains only secrets and extra variables; public env contains non-sensitive auth config.
- OpenAPI parsing relies on prance and openapi-pydantic; external $refs are resolved automatically.
- When using
--base-urlorHttpSettings.baseURL, the URL creates an additional environment in the generated env files. If the spec also defines servers, each server creates its own environment. - In
MULTImode, env files (if enabled) default to being written next to the generated tree unless--env-diris specified.
# JetBrains HTTP Client file
# https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html
# Supports: {{variable}}, # @name, pre/post scripts, http-client.env.json
@BASE_URL=https://api.example.com
### Get all users
# @name getUsers
GET {{BASE_URL}}/users
Accept: application/json
### Create a user
# @name createUser
< {% request.variables.set('timestamp', Date.now()); %}
POST {{BASE_URL}}/users
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com"
}
> {% client.assert(response.status === 201); %}
### Get user by ID
# @name getUserById
GET {{BASE_URL}}/users/{{userId}}
Accept: application/json
Authorization: Bearer {{auth_token}}{
"dev": {
"BASE_URL": "https://api.example.com",
"userId": "123"
},
"staging": {
"BASE_URL": "https://staging.api.example.com",
"userId": "456"
}
}{
"dev": {
"auth_token": "",
"api_key": ""
},
"staging": {
"auth_token": "",
"api_key": ""
}
}Symptoms: Error message showing both JSON and YAML parse failures.
Cause: The OpenAPI spec file contains syntax errors.
Solution:
- Validate your spec with an online tool like Swagger Editor
- Check for common YAML issues: incorrect indentation, missing colons, unquoted special characters
- For JSON, ensure proper comma placement and balanced braces
Symptoms: Error mentioning missing required fields or invalid OpenAPI structure.
Cause: The spec is valid YAML/JSON but doesn't conform to OpenAPI 3.x schema.
Solution:
- Ensure
openapi: "3.0.0"(or 3.1.x) is present at the root - Verify required fields:
info.title,info.version,paths - Check that all
$refreferences point to valid definitions
Symptoms: The specified spec file cannot be found.
Solution:
- Check the file path is correct (use absolute paths if unsure)
- Verify file extension matches (
.yaml,.yml, or.json) - For URLs, ensure the spec is publicly accessible
Symptoms: Error fetching spec from URL (401, 403, 404, etc.)
Solution:
- 401/403: The spec requires authentication; download it locally first
- 404: Verify the URL is correct and the spec exists
- Timeout: Check network connectivity; try downloading manually
Symptoms: Generated .http file uses {{variable}} but env files don't define them.
Solution:
- Security scheme variables (API keys, tokens) go in
http-client.private.env.json - Use
--base-urlto set a custom BASE_URL - Path parameters like
{{userId}}must be manually added to env files
Q: Why are my pre/post request scripts not appearing?
A: Scripts are extracted from OpenAPI x-pre-request-script and x-post-request-script extensions on operations. Add these to your spec:
paths:
/users:
get:
x-pre-request-script: "console.log('before');"
x-post-request-script: "client.assert(response.status === 200);"Q: How do I switch between environments?
A: In your editor:
- Kulala/PyCharm: Select environment from the dropdown or run menu
- httpyac: Use
# @env devdirective or VS Code command palette - VS Code REST Client: Define environments in
.vscode/settings.json
Q: Why use --mode flag?
A: The --mode flag adds editor-specific header comments for better IDE integration:
--mode pycharm: JetBrains documentation link--mode kulala: Kulala.nvim documentation link--mode httpyac: httpyac documentation link--mode default: No header (maximum compatibility)
The actual request syntax is identical across all modes.
- Install dev dependencies:
uv pip install -e ".[test]" - Run tests:
uv run pytest - Run with coverage:
uv run pytest --cov=src --cov-report=term-missing - Lint:
uv run ruff check src/ tests/ - Format:
uv run ruff format src/ tests/ - Code lives under
src/using a src-layout.
MIT