Skip to main content

localapi

Turn any Python function into a local HTTP API with zero boilerplate.

from localapi import LocalAPI

app = LocalAPI()

@app.post
def add(a: int, b: int) -> int:
    return a + b

app.run()
curl -X POST localhost:8000/add \
  -H "Content-Type: application/json" \
  -d '{"a": 10, "b": 20}'
# → {"result": 30}

Interactive docs are at http://127.0.0.1:8000/docs.

Install

pip install -e .            # from a checkout
pip install -e ".[test]"    # with test dependencies

What you get from the signature

Derived from Becomes
Function name add Route /add
@app.get GET, arguments from the query string
@app.post / @app.put / @app.patch / @app.delete That method, arguments from a JSON body
Parameters Request fields; defaults make them optional
Type hints Validation (unannotated parameters accept any JSON value)
Return hint Response schema in OpenAPI
Docstring Endpoint description in OpenAPI

Usage

from localapi import LocalAPI

app = LocalAPI(title="My Tools", version="1.0")   # your API's version, shown in /docs

@app.post                              # POST /greet
def greet(name: str, excited: bool = False) -> str:
    """Say hello."""
    return f"Hello {name}" + ("!" if excited else "")

@app.get                               # GET /status
def status() -> dict:
    return {"status": "ok"}

@app.post(path="/math/add", name="addition")
def add(a: int, b: int) -> int:
    return a + b

@app.delete(path="/files")             # DELETE /files (a path can be reused across methods)
def remove_file(name: str) -> bool:
    ...

app.run()                              # http://127.0.0.1:8000

Decorators return the original function, so it stays callable and testable as plain Python. async def functions are awaited; regular functions run in a threadpool so slow ones don't block the server.

For one-file scripts there's a default instance, where bare @api means @api.post:

from localapi import api

@api
def add(a: int, b: int):
    return a + b

api.run()

Responses

Every response uses the same envelope:

// 200
{"result": 12}

// 422: invalid input
{"error": "validation_error", "detail": [{"field": "a", "message": "Input should be a valid integer"}]}

// 500: the function raised
{"error": "ValueError", "detail": "b must be positive"}

Return values can be primitives, dict/list, Pydantic models, dataclasses, datetime, Path (as a string), bytes (base64), enums, and anything FastAPI's jsonable_encoder understands.

Testing and other ASGI servers

app.asgi is the underlying FastAPI app:

from fastapi.testclient import TestClient

client = TestClient(app.asgi)
assert client.post("/add", json={"a": 1, "b": 2}).json() == {"result": 3}

Security

app.run() binds to 127.0.0.1. Passing another host= (for example 0.0.0.0) exposes your functions to the network and prints a warning. There's no authentication yet, so only do that on a trusted network.

Metadata

Release files for localapi 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for localapi 0.2.1
File Size Uploaded
localapi-0.2.1.tar.gz 17.1 kB Details

Built distribution (wheel)

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

Total release size: 26.2 kB

Release files / localapi-0.2.1.tar.gz

Download URL localapi-0.2.1.tar.gz
Size 17.1 kB
Tags Source
SHA-256 checksum
How to use checksums
8fb7b5a98921f68b09929d3b85353a67d7efca3b878ec001183c893391df493b
BLAKE2b-256 checksum
How to use checksums
ba15a7d7e1de3a84a29aeb9b94c94cb1464396950fff162e743a30388c980ad6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.0

Release files / localapi-0.2.1-py3-none-any.whl

Download URL localapi-0.2.1-py3-none-any.whl
Size 9.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
66c41200bb9792da1d2b9b7378668db5bb8a265c180086ed474b74447f299616
BLAKE2b-256 checksum
How to use checksums
48d5ad441de54667b551070f50970a81ccc98de4e9cef24d56917a3ac6ba77d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.0

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.0

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