A clean REST API that scrapes the latest Tunisian vehicle registration plate numbers from automobile.tn and exposes them through a structured FastAPI service with Swagger (OpenAPI).
- FastAPI REST endpoints
- Swagger UI (
/docs) + ReDoc (/redoc) - Structured output (prefix, series, number, full)
- No caching (every request scrapes upstream)
- Good error handling for upstream/parsing failures
CarPlates/
├─ main.py
├─ requirements.txt
└─ README.md
Windows (PowerShell):
python -m venv venv
.\venv\Scripts\Activate.ps1Linux/macOS:
python -m venv venv
source venv/bin/activatepip install -r requirements.txtpython -m uvicorn main:app --reload --host 0.0.0.0 --port 5000Server will be available at:
- API Base:
http://localhost:5000 - Swagger UI:
http://localhost:5000/docs - ReDoc:
http://localhost:5000/redoc - OpenAPI JSON:
http://localhost:5000/openapi.json
GET /api/v1/plates
Example:
curl http://localhost:5000/api/v1/platesResponse example:
{
"updated_at": "2025-12-21T15:21:45.011316+00:00",
"source": "automobile.tn",
"data": {
"TUN": {
"label": "Immatriculation Normale",
"prefix": "TU",
"series": 257,
"number": 6878,
"full": "TU 257/6878"
},
"MC": {
"label": "Motocyclette",
"prefix": "MOTO",
"series": null,
"number": 123655,
"full": "MOTO 123655"
}
}
}GET /api/v1/plates/{plate_type}
Allowed values:
TUN,RS,IT,TRAC,MC,REM,AA,ES
Example:
curl http://localhost:5000/api/v1/plates/TUNResponse example:
{
"type": "TUN",
"plate": {
"label": "Immatriculation Normale",
"prefix": "TU",
"series": 257,
"number": 6878,
"full": "TU 257/6878"
},
"updated_at": "2025-12-21T15:21:45.011316+00:00",
"source": "automobile.tn"
}Returns 400:
{
"detail": "Invalid plate type. Allowed: TUN, RS, IT, TRAC, MC, REM, AA, ES"
}Returns 502:
{
"detail": "Upstream source unavailable"
}Returns 500:
{
"detail": "Unexpected page structure"
}This API scrapes HTML from automobile.tn. If the site changes CSS classes or layout, parsing can break. If that happens:
- Update the selectors/classes in
main.py(C1,C2) - Or switch to a more stable parsing strategy (ex: locate items by surrounding text)
For educational use. Respect the upstream site's terms of service and robots rules.