Skip to content

Commit b05458f

Browse files
committed
feat: add API metadata endpoint
1 parent b5ad4a8 commit b05458f

3 files changed

Lines changed: 58 additions & 1 deletion

File tree

app/main.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
AllowedProgrammingLanguages,
1616
AllowedSpokenLanguages,
1717
)
18-
from app.schemas import Developer, HealthStatus, Repository
18+
from app.schemas import Developer, HealthStatus, Metadata, Repository
1919
from app.scraping import (
2020
UpstreamRequestError,
2121
get_request,
@@ -25,6 +25,8 @@
2525
)
2626

2727
app = fastapi.FastAPI()
28+
APP_NAME = "Github Trending API"
29+
APP_VERSION = "1.0.2"
2830
CACHE_TTL_SECONDS = 300
2931
CacheKey = tuple[str, tuple[tuple[str, str], ...]]
3032
_trending_html_cache: dict[CacheKey, tuple[float, str]] = {}
@@ -107,6 +109,25 @@ def health() -> HealthStatus:
107109
return HealthStatus(status="ok")
108110

109111

112+
@app.get("/metadata", response_model=Metadata)
113+
def metadata(request: fastapi.Request) -> Metadata:
114+
"""Return API metadata for clients."""
115+
base_url = str(request.base_url).rstrip("/")
116+
return Metadata(
117+
name=APP_NAME,
118+
version=APP_VERSION,
119+
docs=f"{base_url}/docs",
120+
redoc=f"{base_url}/redoc",
121+
health=f"{base_url}/health",
122+
repositories=f"{base_url}/repositories",
123+
developers=f"{base_url}/developers",
124+
cacheTtlSeconds=CACHE_TTL_SECONDS,
125+
supportedDateRanges=[date_range.value for date_range in AllowedDateRanges],
126+
supportedProgrammingLanguagesCount=len(AllowedProgrammingLanguages),
127+
supportedSpokenLanguagesCount=len(AllowedSpokenLanguages),
128+
)
129+
130+
110131
@app.get("/repositories", response_model=list[Repository])
111132
async def trending_repositories(
112133
since: AllowedDateRanges | None = None,

app/schemas.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,22 @@ class HealthStatus(BaseModel):
88
status: str
99

1010

11+
class Metadata(BaseModel):
12+
"""API metadata response data."""
13+
14+
name: str
15+
version: str
16+
docs: str
17+
redoc: str
18+
health: str
19+
repositories: str
20+
developers: str
21+
cacheTtlSeconds: int
22+
supportedDateRanges: list[str]
23+
supportedProgrammingLanguagesCount: int
24+
supportedSpokenLanguagesCount: int
25+
26+
1127
class Contributor(BaseModel):
1228
"""Repository contributor data."""
1329

tests/main_test.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,26 @@ def test_health_route():
4343
assert response.json() == {"status": "ok"}
4444

4545

46+
def test_metadata_route():
47+
"""Tests if the metadata route returns API discovery data."""
48+
response = client.get("/metadata")
49+
50+
assert response.status_code == 200
51+
assert response.json() == {
52+
"name": "Github Trending API",
53+
"version": "1.0.2",
54+
"docs": "http://testserver/docs",
55+
"redoc": "http://testserver/redoc",
56+
"health": "http://testserver/health",
57+
"repositories": "http://testserver/repositories",
58+
"developers": "http://testserver/developers",
59+
"cacheTtlSeconds": 300,
60+
"supportedDateRanges": ["daily", "weekly", "monthly"],
61+
"supportedProgrammingLanguagesCount": len(main.AllowedProgrammingLanguages),
62+
"supportedSpokenLanguagesCount": len(main.AllowedSpokenLanguages),
63+
}
64+
65+
4666
def test_repositories_route_uses_query_parameters(monkeypatch):
4767
"""Tests the repository endpoint request payload and response parsing."""
4868
calls = []

0 commit comments

Comments
 (0)