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")

@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.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 localapi 0.2.0
File Size Uploaded
localapi-0.2.0.tar.gz 16.9 kB Details

Built distribution (wheel)

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

Total release size: 26.0 kB

Release files / localapi-0.2.0.tar.gz

Download URL localapi-0.2.0.tar.gz
Size 16.9 kB
Tags Source
SHA-256 checksum
How to use checksums
e3d565ca979475e6f8813999bb0a139ec0804c04047cf3858e8ddbd496d910d5
BLAKE2b-256 checksum
How to use checksums
a524ae899c22b1f04aa9b5417c2f94bf0fe4507d7c5347427f5da8a353f16300
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.0-py3-none-any.whl

Download URL localapi-0.2.0-py3-none-any.whl
Size 9.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3d8de1b41a3748940e4064e2ae6d3789a76c3113350f4db4b8ee997fe23b0ca9
BLAKE2b-256 checksum
How to use checksums
d7a01b8149e2d959bbc3435ac612e8e4962320b4817aaff071991927204b9a3d
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

0.2.1

2 release files

This release

0.2.0 This release

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