Build interfaces · Lesson 03
Generate a REST API for gcd and lcm
The recording turns existing number-theory functions into two REST endpoints. It uses keon/algorithms and checks both arithmetic results and invalid input. This is a different repository from Requests in lesson 2.
By the end of this lesson
- Select only gcd and lcm from an existing Python module.
- Separate generated files from the running service environment.
- Verify real HTTP results and a rejected request.
Watch the lesson
English · 4:14 · Recorded with Apizr 0.4.3.
Chapters in this recording
| Time | Chapter |
|---|---|
| 00:00 | From a Python function to a real HTTP response. |
| 00:18 | A small, explicit function boundary. |
| 00:36 | Pin the source you are going to inspect. |
| 01:04 | Verify that the selected functions are ready. |
| 01:33 | Generate only gcd and lcm. |
| 02:06 | Generating and running are separate steps. |
| 02:28 | Install the generated runtime requirements. |
| 02:56 | Start locally. Call it. Check validation. |
| 03:51 | Existing Python. A selected, callable interface. |
Read the recording transcript and commands
This is the retained English narration, in the original chapter order. Commands keep the recorded version and prerequisites; setup additions in the lesson are labelled separately.
00:00 — From a Python function to a real HTTP response.
Let us turn existing Python functions into a REST API with Apizr. We will use the algorithms repository by Keon, generate only two endpoints, start the application locally, and verify both successful calls and invalid input.
00:18 — A small, explicit function boundary.
Our example calculates the greatest common divisor and least common multiple. Both functions accept two integers. That gives us a clear JSON request contract. We will expose those two functions and keep the other helpers out of the public interface.
00:36 — Pin the source you are going to inspect.
Clone the algorithms repository, then check out the commit used for this recording. A commit identifier keeps the example reproducible as the project evolves. Locate the number theory module. We will use its existing source file without changing the functions or copying them into a new framework.
git clone --depth 1 https://github.com/keon/algorithms.git
cd algorithms
git fetch --depth 1 origin bd1d152f9ec7331c69be662831610b003b10fc7a
git checkout bd1d152f9ec7331c69be662831610b003b10fc7a
git rev-parse --short HEAD
sed -n '17,29p' algorithms/math/gcd.py
01:04 — Verify that the selected functions are ready.
Inspect the number theory module and read the first assessment. The function is ready and can generate an interface. The inputs are integers, while effects remain unknown. Readiness supports generation; it is not permission to execute arbitrary code. We reviewed this small arithmetic module before using direct execution.
apizr inspect algorithms/math/gcd.py > inspection.txt
sed -n '1,23p' inspection.txt
01:33 — Generate only gcd and lcm.
Generate a REST bundle from that file and explicitly select G C D and L C M. Use a new output directory. The generated files include the application, source, input contracts, OpenAPI document and runtime requirements. Listing the OpenAPI paths confirms that only the two selected functions have public routes.
apizr generate rest algorithms/math/gcd.py --select gcd,lcm --output-dir rest
ls rest
python3.14 -c 'import json; print(*json.load(open("rest/openapi.json"))["paths"], sep="\n")'
02:06 — Generating and running are separate steps.
Generation reads the source and writes the bundle. Starting the direct mode server imports that source. The runtime uses the bundle requirements in a separate environment. For this example, the arithmetic code needs no additional third party library. A different project may have its own runtime dependencies.
02:28 — Install the generated runtime requirements.
Create a separate runtime environment with U V, then install the requirements generated by Apizr. These are the server dependencies. Keeping them separate makes it clear which environment builds the bundle and which one runs it. We can now launch Uvicorn from this runtime environment.
uv venv --python python3.14 runtime
uv pip install --python runtime/bin/python -r rest/requirements.txt
02:56 — Start locally. Call it. Check validation.
Start the server on the loopback address, saving its log. The health endpoint confirms it is listening. Now send forty eight and eighteen to the greatest common divisor endpoint. The response is six. Next, eight and twelve produce a least common multiple of twenty four. If we send a string where an integer is required, the interface rejects it with HTTP four twenty two. The arithmetic function is not asked to silently convert that string. Finally, stop the local server.
runtime/bin/uvicorn app:app --app-dir rest --host 127.0.0.1 --port 8814 > server.log 2>&1 &
server_pid=$!
curl -sS http://127.0.0.1:8814/health; echo
curl -sS http://127.0.0.1:8814/capabilities/gcd -H 'Content-Type: application/json' -d '{"a":48,"b":18}'; echo
curl -sS http://127.0.0.1:8814/capabilities/lcm -H 'Content-Type: application/json' -d '{"a":8,"b":12}'; echo
curl -sS -o invalid.json -w 'HTTP %{http_code}\n' http://127.0.0.1:8814/capabilities/gcd -H 'Content-Type: application/json' -d '{"a":"48","b":18}'
cat invalid.json; echo
kill "$server_pid"
tail -n 3 server.log
03:51 — Existing Python. A selected, callable interface.
You have generated and called a real REST interface around existing Python code. The selection controls which functions are public, and the generated input contract checks requests. This is a local demonstration, not a deployment. Next, we will use another repository to make tools callable through MCP.
1. Inspect the recorded arithmetic module
With the video's Apizr 0.4.3 environment, obtain its exact source revision:
git clone --depth 1 https://github.com/keon/algorithms.git
cd algorithms
git fetch --depth 1 origin bd1d152f9ec7331c69be662831610b003b10fc7a
git checkout bd1d152f9ec7331c69be662831610b003b10fc7a
apizr inspect algorithms/math/gcd.py > inspection.txt
Both selected functions accept two integers. Their static input contract is ready, while effects remain unknown. The recording uses direct execution after reviewing this small arithmetic module.
2. Generate only the selected routes
apizr generate rest algorithms/math/gcd.py --select gcd,lcm --output-dir rest
uv venv --python python3.14 runtime
uv pip install --python runtime/bin/python -r rest/requirements.txt
runtime/bin/uvicorn app:app --app-dir rest --host 127.0.0.1 --port 8814
Generation writes source, adapters, OpenAPI and runtime requirements. The final command starts the server and imports the trusted source. Keep that terminal running while calling it from another terminal.
3. Reproduce the three observed requests
curl -sS http://127.0.0.1:8814/capabilities/gcd -H 'Content-Type: application/json' -d '{"a":48,"b":18}'
curl -sS http://127.0.0.1:8814/capabilities/lcm -H 'Content-Type: application/json' -d '{"a":8,"b":12}'
curl -sS -o invalid.json -w 'HTTP %{http_code}\n' http://127.0.0.1:8814/capabilities/gcd -H 'Content-Type: application/json' -d '{"a":"48","b":18}'
The retained terminal shows 6, 24, then HTTP 422 with Value does not match the declared input type. The string "48" is rejected instead of silently becoming an integer. Stop the foreground server with Ctrl+C after practising; the recording starts it in the background and stops its saved process ID.
Practice
Predict the two valid arithmetic results before calling the endpoints. Then send the invalid string input and explain where it is rejected. Check rest/openapi.json: which two functions became routes, and which helpers did not?
Check your reasoning
The greatest common divisor of 48 and 18 is 6; the least common multiple of 8 and 12 is 24. The generated request contract rejects the string with HTTP 422. Selection exposes only gcd and lcm. A successful local call verifies this interface, while a production deployment remains a separate task.