RawIntent 5
Build your own API: define endpoints, create API keys, and send requests.
Version 5 replaces the English-language engine and neural compiler completely.
It is a breaking redesign, not a compatible update to RawIntent 4. Pin
rawintent==4.1.0 if you still need the old language engine.
Install
pip install rawintent
For an unpublished local checkout, use python -m pip install ..
Python 3.10 or later is required.
Create a server
Save this as app.py:
from rawintent import API
api = API("My API")
@api.get("/hello")
def hello(name: str = "world"):
return {"message": f"Hello, {name}!"}
@api.post("/add")
def add(a: float, b: float):
return {"result": a + b}
@api.get("/health", public=True)
def health():
return {"status": "ok"}
if __name__ == "__main__":
api.run()
Run python app.py. It listens at http://127.0.0.1:8000.
Open http://127.0.0.1:8000/docs to try endpoints in your browser.
You can also generate the starter and launch it with:
rawintent init app.py
rawintent serve app:api --reload
python -m rawintent works anywhere the console command is unavailable.
init will not overwrite an existing file.
Create a key and send requests
Run this in another terminal from the same working directory as your server:
rawintent keys create --name my-client
Copy the returned ri_... token. It is displayed only at creation and cannot be
recovered from the database. Put it in an environment variable or a secret store.
In PowerShell you can capture the key directly:
$env:RAWINTENT_API_KEY = python -m rawintent keys create --name my-client
python examples/client.py
In your client script:
import os
from rawintent import Client
with Client("http://127.0.0.1:8000", api_key=os.environ["RAWINTENT_API_KEY"]) as client:
print(client.get("/hello", params={"name": "Vincent"}))
print(client.post("/add", json={"a": 2, "b": 3}))
Output:
{'message': 'Hello, Vincent!'}
{'result': 5.0}
Any HTTP client can call your API. Send the key in the X-API-Key header.
The interactive docs have an Authorize button for the same key.
Keys belong to the server/database that issued them; they are not PyPI tokens
or credentials for a hosted RawIntent service.
Endpoint rules
@api.get,@api.post,@api.put,@api.patch, and@api.deleteregister routes.- Endpoints require a valid key unless
public=Trueis explicit. - GET and DELETE scalar arguments come from query parameters.
- POST, PUT, and PATCH arguments become fields of a JSON object.
{item_id}in a route is a path parameter and takes precedence over the body.- Python type annotations validate inputs. Missing or invalid input returns HTTP 422.
- Both regular
defandasync defhandlers work. - Dictionary and list results become JSON. Return
Responsefor other formats. @api.route("/status", methods=["GET", "HEAD"])supports other HTTP methods.- Register body-based and query-based methods separately.
@api.put("/items/{item_id}")
def update_item(item_id: int, title: str, count: int = 1):
return {"id": item_id, "title": title, "count": count}
Call with client.put("/items/42", json={"title": "Notebook", "count": 3}).
For a raw JSON body or explicit query arguments, use exported FastAPI helpers:
from rawintent import Body, Query
@api.post("/echo")
def echo(data: dict = Body(...), verbose: bool = Query(False)):
return {"data": data, "verbose": verbose}
Body(...) uses the entire JSON document. Ordinary parameters instead use named
fields, so def echo(data: dict) expects {"data": {...}}.
BaseModel, Field, Depends, Request, Response, and HTTPException are
also exported. See FastAPI parameter documentation
for explicit parameter declarations and nested Pydantic models.
Key management
The default SQLite registry is .rawintent/keys.sqlite3, relative to the process
working directory. Use an absolute path for servers launched from different directories:
api = API("My API", key_store="C:/my-api/keys.sqlite3")
Use the same file with CLI commands:
rawintent keys create --store C:/my-api/keys.sqlite3 --name reader --scope items:read --expires-in 86400
rawintent keys list --store C:/my-api/keys.sqlite3
rawintent keys revoke KEY_ID --store C:/my-api/keys.sqlite3
keys list shows IDs, names, prefixes, scopes, expiration, and active status;
it never prints secret tokens. Revocation takes effect on the next authentication
check, including across server processes sharing the same SQLite file.
Create keys programmatically with api.create_key("client-name"), or use
KeyStore(path).create(...). Create them during provisioning, not each time
an application imports or a development server reloads.
@api.get("/items", scopes=["items:read"])
def list_items():
return []
A key created with scopes=["items:read"] can access that endpoint. Missing
required scopes return 403. Keys with scopes=None (the default) have all scopes;
scopes=[] allows ordinary protected endpoints but no named scopes. Scope names
are exact strings, with no wildcard expansion. Expired or revoked keys return 401.
request.state.api_key contains authenticated KeyInfo inside a protected handler.
Async clients and errors
import asyncio
import os
from rawintent import AsyncClient, APIError
async def main():
async with AsyncClient("http://127.0.0.1:8000", os.environ["RAWINTENT_API_KEY"]) as client:
try:
print(await client.post("/add", json={"a": 2, "b": 3}))
except APIError as error:
print(error.status_code, error.detail)
asyncio.run(main())
Clients parse JSON responses, return text for non-JSON responses, and return None
for empty responses. HTTP errors and redirects raise APIError. Network errors
and timeouts retain their HTTPX exception types. The default timeout is 30 seconds;
set timeout=10 when constructing a client to change it. Writes are not retried.
Client requests accept paths on their configured server, not arbitrary external
URLs. Redirects are not followed. A base URL ending in /v1 retains that prefix
for calls such as client.get("/items").
Hosting
RawIntent builds on FastAPI,
Uvicorn, and HTTPX.
api is an ASGI application; run rawintent serve app:api --host 0.0.0.0 --port 8000
or uvicorn app:api on your host. Use a TLS reverse proxy for HTTPS outside local
development. Disable interactive docs with API(docs=False) if desired.
Docs and the OpenAPI schema are public when enabled, but protected endpoint calls
still require a key. api.app exposes the underlying FastAPI app for advanced
middleware and lifespan configuration. Routes added directly to api.app use
FastAPI rules and do not automatically get RawIntent key authentication.
The SQLite registry must live on persistent storage. Keep it and your tokens out of source control. The library does not provide hosting, billing, user accounts, rate limiting, or a public key-signup portal. Key creation is a local administrative operation; there is no unauthenticated web endpoint that issues credentials.
Development
python -m pip install -e ".[dev]"
python -m pytest -q
python -m build
python -m twine check dist/*
Metadata
Release files for rawintent 5.0.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 | |
|---|---|---|---|
| rawintent-5.0.0.tar.gz | 19.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rawintent-5.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.0 kB
Release files / rawintent-5.0.0.tar.gz
| Download URL | rawintent-5.0.0.tar.gz |
|---|---|
| Size | 19.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
978e947154e3d38f2942983ef900c454aad3e0e3ff2a46d2666274beb43eae94
|
|
BLAKE2b-256 checksum How to use checksums |
cc9b5b148d71ce6324608d8aeea59e3fa10ccf9abaad64c887153b995164a557
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.15
|
Release files / rawintent-5.0.0-py3-none-any.whl
| Download URL | rawintent-5.0.0-py3-none-any.whl |
|---|---|
| Size | 13.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
73195e4790547d380c26d43a9d0fd1d1958348d73322629a375f7298260f4df3
|
|
BLAKE2b-256 checksum How to use checksums |
d657d5ca3dcdf20b23eba76428f05fc52683b22531c437cddab4e9d7d3c480f2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.15
|