Skip to content

Commit f2db647

Browse files
committed
fix: latest videos returns newest 3 (refs #9)
1 parent fdc81ab commit f2db647

13 files changed

Lines changed: 67 additions & 52 deletions

app/main.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,7 @@ async def _problem_response(request: Request, status_code: int, detail: str):
155155
if HttpxConnectError is not None:
156156

157157
@app.exception_handler(HttpxConnectError) # type: ignore[arg-type]
158-
async def httpx_connect_error_handler(
159-
request: Request, exc: Exception
160-
): # noqa: D401
158+
async def httpx_connect_error_handler(request: Request, exc: Exception): # noqa: D401
161159
logger.warning("AstraDB connectivity problem: %s", exc)
162160
# Provide more context for troubleshooting: log the failed request (if
163161
# available) and the full stack trace at DEBUG level.
@@ -176,9 +174,7 @@ async def httpx_connect_error_handler(
176174
if HttpcoreConnectError is not None:
177175

178176
@app.exception_handler(HttpcoreConnectError) # type: ignore[arg-type]
179-
async def httpcore_connect_error_handler(
180-
request: Request, exc: Exception
181-
): # noqa: D401
177+
async def httpcore_connect_error_handler(request: Request, exc: Exception): # noqa: D401
182178
logger.warning("AstraDB connectivity problem: %s", exc)
183179
# httpcore.ConnectError does not expose the original request object, but we
184180
# still output the stack trace to aid debugging.

app/metrics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@
2525
RECOMMENDATION_DURATION_SECONDS = Histogram(
2626
"recommendation_generation_duration_seconds",
2727
"Latency of recommendation engine stub (seconds)",
28-
)
28+
)

app/services/video_service.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@
4444
# AsyncMock / MagicMock for tests – imported early so helper can reference them
4545
from unittest.mock import AsyncMock, MagicMock
4646

47-
from opentelemetry import trace
48-
import time
49-
from app.metrics import ASTRA_DB_QUERY_DURATION_SECONDS
5047

5148
# ---------------------------------------------------------------------------
5249
# Constants & Regex Patterns
@@ -514,12 +511,18 @@ async def list_latest_videos(
514511
page_size: int,
515512
db_table: Optional[AstraDBCollection] = None,
516513
) -> Tuple[List[VideoSummary], int]:
514+
"""Return the newest *three* videos across all days for the home page row."""
515+
516+
# We only need a single row of 3 videos on the UI – cap the page size.
517+
effective_size = min(page_size, 3)
518+
517519
return await list_videos_with_query(
518520
{},
519521
page,
520-
page_size,
522+
effective_size,
523+
sort_options={"added_date": -1},
521524
db_table=db_table,
522-
source_table_name=LATEST_VIDEOS_TABLE_NAME,
525+
source_table_name=VIDEOS_TABLE_NAME,
523526
)
524527

525528

@@ -982,9 +985,7 @@ async def fetch_video_title(youtube_url: str) -> str: # noqa: D401
982985
# ---------------------------------------------------------------------------
983986

984987

985-
async def process_video_submission(
986-
video_id: VideoID, youtube_video_id: str
987-
) -> None: # noqa: D401,E501
988+
async def process_video_submission(video_id: VideoID, youtube_video_id: str) -> None: # noqa: D401,E501
988989
"""Background processing stub that updates status transitions.
989990
990991
In production most metadata is now fetched inline, but this helper can

app/utils/db_instrumentation.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
provides visibility into **all** Data-API mutations without having to wrap
77
each individual call site.
88
"""
9+
910
from __future__ import annotations
1011

1112
import time
@@ -62,4 +63,4 @@ async def _update_wrap(self, *args, **kwargs): # type: ignore
6263
AstraDBCollection.update_one = _update_wrap # type: ignore[attr-defined]
6364

6465
# Mark as patched
65-
AstraDBCollection._kv_instrumented = True # type: ignore[attr-defined]
66+
AstraDBCollection._kv_instrumented = True # type: ignore[attr-defined]

app/utils/observability.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from __future__ import annotations
1010

1111
import logging
12-
import os
1312
import time
1413
from typing import Any
1514

@@ -70,7 +69,7 @@
7069
_LOKI_READY = False
7170
if settings.LOKI_ENABLED and settings.LOKI_ENDPOINT:
7271
try:
73-
import logging_loki # type: ignore
72+
import logging_loki # type: ignore # noqa: F401
7473

7574
_LOKI_READY = True
7675
except ModuleNotFoundError: # pragma: no cover
@@ -282,7 +281,7 @@ def _setup_loki_logging() -> None:
282281

283282
try:
284283
if _LOKI_READY:
285-
import logging_loki # type: ignore
284+
import logging_loki # type: ignore # noqa: F401
286285

287286
tags = {
288287
"service": settings.PROJECT_NAME,

load/semantic_search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ def search(self): # noqa: D401
2525
# Static query keeps the test deterministic; real test could randomise.
2626
self.client.get(
2727
"/api/v1/search/videos", params={"query": "cats", "mode": "semantic"}
28-
)
28+
)

scripts/attach_nvidia_vector_index.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
options it exits silently.
3434
"""
3535

36-
import json
3736
import os
3837
import sys
3938
import logging
@@ -81,6 +80,7 @@
8180
# Helper functions
8281
# --------------------------------------------------------------------------------------
8382

83+
8484
def _post(payload: Dict[str, Any]) -> Dict[str, Any]:
8585
"""Send a JSON payload and return JSON response (or error)."""
8686
resp = requests.post(DATA_API_URL, headers=HEADERS, json=payload, timeout=10)
@@ -97,24 +97,28 @@ def _post(payload: Dict[str, Any]) -> Dict[str, Any]:
9797

9898

9999
def main() -> None: # noqa: D401
100-
log.info("Enabling vectorize on '%s.%s' via NVIDIA model '%s' …", TABLE, COLUMN, MODEL_ID)
101-
_post({
102-
"alterTable": {
103-
"operation": {
104-
"addVectorize": {
105-
"columns": {
106-
COLUMN: {
107-
"provider": "nvidia",
108-
"modelName": MODEL_ID,
100+
log.info(
101+
"Enabling vectorize on '%s.%s' via NVIDIA model '%s' …", TABLE, COLUMN, MODEL_ID
102+
)
103+
_post(
104+
{
105+
"alterTable": {
106+
"operation": {
107+
"addVectorize": {
108+
"columns": {
109+
COLUMN: {
110+
"provider": "nvidia",
111+
"modelName": MODEL_ID,
112+
}
109113
}
110114
}
111115
}
112116
}
113117
}
114-
})
118+
)
115119

116120
log.info("✅ content_features column now configured for $vectorize via NVIDIA.")
117121

118122

119123
if __name__ == "__main__": # pragma: no cover
120-
main()
124+
main()

scripts/enable_vector_flag.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,4 @@ def main() -> None: # noqa: D401 – entry point
9898

9999

100100
if __name__ == "__main__": # pragma: no cover
101-
main()
101+
main()

scripts/run_load_test.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,23 @@ def main() -> None: # noqa: D401 – entry point
3434
)
3535
# Backwards-compat optional flag (not shown in usage)
3636
parser.add_argument("--host", dest="_host_legacy", help=argparse.SUPPRESS)
37-
parser.add_argument("--users", type=int, default=DEFAULT_USERS, help="Number of concurrent users (default: 200)")
38-
parser.add_argument("--spawn-rate", type=int, default=DEFAULT_SPAWN_RATE, help="User hatch rate per second (default: 20)")
39-
parser.add_argument("--duration", default=DEFAULT_DURATION, help="Test duration (Locust time format, default: 5m)")
37+
parser.add_argument(
38+
"--users",
39+
type=int,
40+
default=DEFAULT_USERS,
41+
help="Number of concurrent users (default: 200)",
42+
)
43+
parser.add_argument(
44+
"--spawn-rate",
45+
type=int,
46+
default=DEFAULT_SPAWN_RATE,
47+
help="User hatch rate per second (default: 20)",
48+
)
49+
parser.add_argument(
50+
"--duration",
51+
default=DEFAULT_DURATION,
52+
help="Test duration (Locust time format, default: 5m)",
53+
)
4054
parser.add_argument(
4155
"--locust-file",
4256
default=str(Path("load/semantic_search.py")),
@@ -68,4 +82,4 @@ def main() -> None: # noqa: D401 – entry point
6882

6983

7084
if __name__ == "__main__": # pragma: no cover
71-
main()
85+
main()

tests/conftest.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@ class _DataAPIResponseException(Exception):
4343
exceptions_stub.data_api_exceptions = types.ModuleType(
4444
"astrapy.exceptions.data_api_exceptions"
4545
)
46-
exceptions_stub.data_api_exceptions.DataAPIResponseException = _DataAPIResponseException # type: ignore[attr-defined]
46+
exceptions_stub.data_api_exceptions.DataAPIResponseException = (
47+
_DataAPIResponseException # type: ignore[attr-defined]
48+
)
4749

4850
# Register in sys.modules hierarchy so that "from astrapy.exceptions.data_api_exceptions" works
4951
sys.modules["astrapy.exceptions"] = exceptions_stub
50-
sys.modules[
51-
"astrapy.exceptions.data_api_exceptions"
52-
] = exceptions_stub.data_api_exceptions
52+
sys.modules["astrapy.exceptions.data_api_exceptions"] = (
53+
exceptions_stub.data_api_exceptions
54+
)
5355

5456
# ---------------------------------------------------------------------------
5557
# Patch httpx.AsyncClient to accept `app` kwarg using ASGITransport (for tests)

0 commit comments

Comments
 (0)