Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ New experiments should follow the [experiment README guideline](docs/experiment-
| [Web framework basics / Express Hello World](web-framework-basics/hello-world/node-express/) | Migrated snapshot | Demonstrate the minimum Express route and server lifecycle. |
| [Application scaffolding / Express Generator](application-scaffolding/express-generator/node-express/) | Migrated snapshot | Record the conventional routers, views, middleware, and error boundaries generated for Express. |
| [REST API / TODO service with Express and Sequelize](rest-api/todo-service/node-express-sequelize/) | Migrated snapshot | Separate routing, controllers, and PostgreSQL persistence in a small task service. |
| [REST API / DNF history with FastAPI](rest-api/system-history/python-fastapi/) | Migrated snapshot | Parse local DNF transaction history through an asynchronous HTTP endpoint. |
3 changes: 3 additions & 0 deletions rest-api/system-history/python-fastapi/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.venv
__pycache__
*.pyc
3 changes: 3 additions & 0 deletions rest-api/system-history/python-fastapi/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.venv/
__pycache__/
*.py[cod]
12 changes: 12 additions & 0 deletions rest-api/system-history/python-fastapi/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM python:3.11-slim

WORKDIR /srv

COPY requirements.txt .
RUN pip install --no-cache-dir --requirement requirements.txt

COPY main.py history.txt ./

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
67 changes: 67 additions & 0 deletions rest-api/system-history/python-fastapi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# DNF History API with FastAPI

## Concept

This migrated snapshot exposes a local DNF transaction history through an asynchronous FastAPI endpoint.

## Hypothesis or problem

A small HTTP boundary can turn line-oriented system history into typed JSON without blocking the event loop while reading the source file.

## Architecture

| Boundary | Role |
| --- | --- |
| `main.py` | Reads `history.txt`, validates each transaction with Pydantic, and serves `GET /`. |
| `history.txt` | Provides a safe fixture with the three fields consumed by the parser. |
| `Dockerfile` | Runs the historical dependency set on Python 3.11 without the source repository's end-of-life Fedora image. |

## Quick path

Prerequisites: Python 3.11 or Podman.

```sh
python -m venv .venv
.venv/bin/python -m pip install --requirement requirements.txt
.venv/bin/python -m uvicorn main:app
curl http://127.0.0.1:8000/
```

The same request is available in `requests.http`.

## Container

```sh
podman build --tag forge-fastapi-dnf .
podman run --rm --publish 8000:8000 forge-fastapi-dnf
```

## Configuration

The application reads `history.txt` from its working directory. Replace the committed fixture with output shaped like `dnf history`, keeping the `ID | Command line | Date` columns first. Do not commit machine-specific package history.

## Expected behavior

`GET /` returns one JSON object per valid fixture line with numeric `id`, `command`, and `date` fields. Missing or malformed input fails the request rather than silently dropping records.

## Tradeoffs

The parser intentionally consumes only the first three pipe-delimited columns and reads the complete file for every request. The pinned FastAPI generation is preserved from the source period for snapshot fidelity and is not a production dependency baseline.

## Status

Migrated snapshot from `fronzec/fastapi-projects/hello-world` at source commit `7a35799`.

## Verification

Verified on 2026-07-18 with Python 3.11.15:

- `uv pip install --python <temporary-venv>/bin/python --requirement requirements.txt` installed the pinned dependency set.
- `uv pip check --python <temporary-venv>/bin/python` reported that all installed packages are compatible.
- Compiling and importing `main.py` passed.
- A local Uvicorn server returned both typed fixture transactions from `GET /`.
- The container build was skipped because Podman 5.8.2 could not connect to its stopped local machine.

## Agent boundaries

Inherit the root `AGENTS.md`. Keep system-specific history out of Git and preserve the bounded parsing experiment rather than expanding it into a package-management service.
2 changes: 2 additions & 0 deletions rest-api/system-history/python-fastapi/history.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1 | install fastapi | 2026-07-18 10:00
2 | upgrade python | 2026-07-18 11:30
32 changes: 32 additions & 0 deletions rest-api/system-history/python-fastapi/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import aiofiles
from fastapi import FastAPI
from pydantic import BaseModel


app = FastAPI()


class DnfTransaction(BaseModel):
id: int
command: str
date: str


async def read_history():
transactions = []
async with aiofiles.open("history.txt") as history:
async for line in history:
transaction_id, command, date, *_ = line.split("|")
transactions.append(
DnfTransaction(
id=transaction_id.strip(),
command=command.strip(),
date=date.strip(),
)
)
return transactions


@app.get("/")
async def read_root():
return await read_history()
2 changes: 2 additions & 0 deletions rest-api/system-history/python-fastapi/requests.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GET http://127.0.0.1:8000/
Accept: application/json
10 changes: 10 additions & 0 deletions rest-api/system-history/python-fastapi/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
aiofiles==22.1.0
anyio==3.6.2
click==8.1.3
fastapi==0.85.1
h11==0.14.0
idna==3.4
pydantic==1.10.2
starlette==0.20.4
typing-extensions==4.4.0
uvicorn==0.18.3
Loading