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)
| File | Size | Uploaded | |
|---|---|---|---|
| localapi-0.2.0.tar.gz | 16.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|