From 6f4e7f1853dbf6c61e36aa272490e595e34a42e9 Mon Sep 17 00:00:00 2001 From: Colin Maudry Date: Wed, 13 May 2026 14:10:20 +0200 Subject: [PATCH] API: endpoint /schema (#78) Co-Authored-By: Claude Sonnet 4.6 --- src/api/routes.py | 11 +++++++++++ tests/api/conftest.py | 24 ++++++++++++++++++++++++ tests/api/test_endpoints_schema.py | 19 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 tests/api/test_endpoints_schema.py diff --git a/src/api/routes.py b/src/api/routes.py index 759ff1b..a4728b3 100644 --- a/src/api/routes.py +++ b/src/api/routes.py @@ -1,5 +1,8 @@ from flask_smorest import Blueprint +from src.api.auth import require_token +from src.db import schema as duckdb_schema + bp = Blueprint( "api_v1", "api_v1", @@ -12,3 +15,11 @@ bp = Blueprint( def health(): """Sonde de santé, sans authentification.""" return {"status": "ok"} + + +@bp.route("/schema") +@require_token +def schema(): + """Liste des colonnes disponibles dans le dataset DECP.""" + cols = [{"name": name, "type": str(dtype)} for name, dtype in duckdb_schema.items()] + return {"columns": cols} diff --git a/tests/api/conftest.py b/tests/api/conftest.py index 7baca3f..67dc109 100644 --- a/tests/api/conftest.py +++ b/tests/api/conftest.py @@ -10,3 +10,27 @@ def temp_db(tmp_path, monkeypatch): tokens_db.init_schema(db_path) return db_path + + +@pytest.fixture +def api_client(monkeypatch, tmp_path): + """Client Flask test avec USERS_DB_PATH éphémère et blueprint API monté.""" + db_path = tmp_path / "users.test.sqlite" + monkeypatch.setenv("USERS_DB_PATH", str(db_path)) + from flask import Flask + + from src.api import init_api, tokens_db + + tokens_db.init_schema(db_path) + server = Flask(__name__) + init_api(server) + return server.test_client(), db_path + + +@pytest.fixture +def valid_token_header(api_client): + from src.api import tokens_db + + _, db_path = api_client + token, _ = tokens_db.create_token(db_path, "test-token") + return {"Authorization": f"Bearer {token}"} diff --git a/tests/api/test_endpoints_schema.py b/tests/api/test_endpoints_schema.py new file mode 100644 index 0000000..3d8438e --- /dev/null +++ b/tests/api/test_endpoints_schema.py @@ -0,0 +1,19 @@ +def test_schema_without_token_returns_401(api_client): + client, _ = api_client + resp = client.get("/api/v1/schema") + assert resp.status_code == 401 + + +def test_schema_returns_columns(api_client, valid_token_header): + client, _ = api_client + resp = client.get("/api/v1/schema", headers=valid_token_header) + assert resp.status_code == 200 + data = resp.get_json() + assert "columns" in data + assert isinstance(data["columns"], list) + assert len(data["columns"]) > 0 + first = data["columns"][0] + assert set(first.keys()) >= {"name", "type"} + # uid doit être présent dans le schéma DECP de test + names = [c["name"] for c in data["columns"]] + assert "uid" in names