1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
# Hot functions API
A small HTTP service that registers typed Python functions and calls them with
JSON. It derives input and output schemas from type annotations; there is no
separate schema registration step or UI.
## Run locally
Python 3.10 or newer is needed for `int | str` annotations in the examples.
The `curl` examples use Bash's `$'...'` quoting for multiline source.
```sh
python -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
python server.py
```
The service listens on port 8000. Functions live in memory and disappear when
the server stops.
## Register and call a function
Send a complete, synchronous function definition. The function name must match
the URL, and every parameter and the return value must have a type annotation.
```sh
curl -X PATCH http://localhost:8000/double \
--data-binary $'def double(x: int) -> int:\n return x * 2'
```
With one parameter, POST either a bare JSON value or a named argument:
```sh
curl -X POST http://localhost:8000/double \
-H 'Content-Type: application/json' -d '4'
# 8
curl -X POST http://localhost:8000/double \
-H 'Content-Type: application/json' -d '{"x":4}'
# 8
```
The response is the function's JSON result, without a `result` wrapper. Input
and output are validated against the annotations in Pydantic's strict mode.
### Multiple arguments and union types
```sh
curl -X PATCH http://localhost:8000/label \
--data-binary $'def label(x: int | str, prefix: str = "item") -> str:\n return f"{prefix}:{x}"'
curl -X POST http://localhost:8000/label \
-H 'Content-Type: application/json' -d '{"x":4,"prefix":"order"}'
# "order:4"
curl -X POST http://localhost:8000/label \
-H 'Content-Type: application/json' -d '{"x":"abc"}'
# "item:abc"
```
For multiple parameters, POST a JSON object with parameter names as keys.
Defaults may be omitted. Unrecognized keys are rejected.
A single parameter may accept any JSON value its annotation permits: an object,
array, string, number, boolean, or `null`. For example, a function annotated
`x: dict[str, int]` can receive `{"count":2}` directly or as
`{"x":{"count":2}}`. If an object also looks like valid named arguments, the
named-argument form takes precedence. Structured types can use Pydantic models
defined in the uploaded source.
## Discover functions and schemas
```sh
curl http://localhost:8000/double
curl http://localhost:8000/
```
`GET /double` returns an object containing `name`, `source`, and `schema`.
`GET /` returns `{"functions": [...]}` with the same objects for all registered
functions. For `double`, the input schema describes both accepted POST forms:
```json
{
"name": "double",
"source": "def double(x: int) -> int:\n return x * 2",
"schema": {
"input": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"anyOf": [
{
"type": "object",
"properties": {"x": {"title": "X", "type": "integer"}},
"required": ["x"],
"additionalProperties": false
},
{"type": "integer"}
]
},
"output": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "integer"
}
}
}
```
The input and output schemas are JSON Schema Draft 2020-12 documents. Replacing
a function with `PATCH` also regenerates its schemas.
## API responses
| Request | Result |
| --- | --- |
| `PATCH /name` | `200` on registration; `400` for an invalid definition |
| `POST /name` | `200` with the JSON result; `400` for invalid input; `404` if undefined; `500` if execution or output validation fails |
| `GET /name` | `200` with the function description; `404` if undefined |
| `GET /` | `200` with all defined functions |
Run the tests with `python -m unittest -v test_server`.
## Trust boundary
Uploaded definitions execute as Python in the server process, including at
registration time. The server has no authentication, isolation, request-size
limit, or execution timeout and binds to `0.0.0.0`. Only run it where every
caller is fully trusted; it is not safe to expose to untrusted clients.
|