合并 agent-mvp 到 master #1

Merged
jiang merged 93 commits from agent-mvp into master 2026-08-18 17:56:43 +08:00
2 changed files with 71 additions and 21 deletions
Showing only changes of commit 1d88f8efbe - Show all commits
+24 -2
View File
@@ -201,11 +201,25 @@ def _with_header_project_context(endpoint, route_name: str):
def _with_pagination(endpoint): def _with_pagination(endpoint):
signature = inspect.signature(endpoint) signature = inspect.signature(endpoint)
if "limit" in signature.parameters or "offset" in signature.parameters: handler_limit_parameter = "limit" if "limit" in signature.parameters else None
return endpoint handler_offset_parameter = next(
(
parameter_name
for parameter_name in ("offset", "skip")
if parameter_name in signature.parameters
),
None,
)
handler_handles_pagination = bool(
handler_limit_parameter or handler_offset_parameter
)
@wraps(endpoint) @wraps(endpoint)
async def wrapper(*args, **kwargs): async def wrapper(*args, **kwargs):
if handler_handles_pagination:
limit = kwargs.get(handler_limit_parameter, 0)
offset = kwargs.get(handler_offset_parameter, 0)
else:
limit = kwargs.pop("_rest_limit") limit = kwargs.pop("_rest_limit")
offset = kwargs.pop("_rest_offset") offset = kwargs.pop("_rest_offset")
result = endpoint(*args, **kwargs) result = endpoint(*args, **kwargs)
@@ -213,6 +227,13 @@ def _with_pagination(endpoint):
result = await result result = await result
if not isinstance(result, list): if not isinstance(result, list):
return result return result
if handler_handles_pagination:
return Page(
items=result,
total=offset + len(result),
limit=limit or len(result),
offset=offset,
)
return Page( return Page(
items=result[offset : offset + limit], items=result[offset : offset + limit],
total=len(result), total=len(result),
@@ -221,6 +242,7 @@ def _with_pagination(endpoint):
) )
parameters = list(signature.parameters.values()) parameters = list(signature.parameters.values())
if not handler_handles_pagination:
parameters.extend( parameters.extend(
[ [
inspect.Parameter( inspect.Parameter(
+29 -1
View File
@@ -4,7 +4,7 @@ from pathlib import Path
from uuid import uuid4 from uuid import uuid4
import pytest import pytest
from fastapi import FastAPI from fastapi import APIRouter, FastAPI, Query
from fastapi.routing import APIRoute from fastapi.routing import APIRoute
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
@@ -254,3 +254,31 @@ def test_rest_runtime_consumes_injected_project_context(monkeypatch) -> None:
assert response.json()["items"] == [ assert response.json()["items"] == [
{"scheme_name": "burst_case", "scheme_type": "burst_analysis"} {"scheme_name": "burst_case", "scheme_type": "burst_analysis"}
] ]
def test_rest_runtime_wraps_handler_paginated_list() -> None:
source_router = APIRouter()
@source_router.get("/records", response_model=list[int])
async def list_records(
skip: int = Query(0, ge=0),
limit: int = Query(2, ge=1, le=10),
) -> list[int]:
records = [10, 20, 30, 40]
return records[skip : skip + limit]
app = FastAPI(redirect_slashes=False)
app.include_router(build_rest_router(source_router.routes), prefix="/api/v1")
response = TestClient(app, raise_server_exceptions=False).get(
"/api/v1/records",
params={"skip": 1, "limit": 2},
)
assert response.status_code == 200
assert response.json() == {
"items": [20, 30],
"total": 3,
"limit": 2,
"offset": 1,
}