mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
feat(rpc): add /rpc/v5/{type} openapi-compatible routes
We will be modeling future RPC implementations on an OpenAPI spec. While this commit does not completely cohere to OpenAPI in terms of response data, this is a good start and will allow us to cleanly document these openapi routes in the current and future. This commit brings in the new RPC routes: - GET /rpc/v5/info/{pkgname} - GET /rpc/v5/info?arg[]=pkg1&arg[]=pkg2 - POST /rpc/v5/info with JSON data `{"arg": ["pkg1", "pkg2"]}` - GET /rpc/v5/search?arg=keywords&by=valid-by-value - POST /rpc/v5/search with JSON data `{"by": "valid-by-value", "arg": "keywords"}` Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
parent
bb6e602e13
commit
df0a4a2be2
2 changed files with 199 additions and 0 deletions
|
@ -160,3 +160,107 @@ async def rpc_post(
|
|||
callback: Optional[str] = Form(default=None),
|
||||
):
|
||||
return await rpc_request(request, v, type, by, arg, args, callback)
|
||||
|
||||
|
||||
@router.get("/rpc/v{version}/info/{name}")
|
||||
async def rpc_openapi_info(request: Request, version: int, name: str):
|
||||
return await rpc_request(
|
||||
request,
|
||||
version,
|
||||
"info",
|
||||
defaults.RPC_SEARCH_BY,
|
||||
name,
|
||||
[],
|
||||
)
|
||||
|
||||
|
||||
@router.get("/rpc/v{version}/info")
|
||||
async def rpc_openapi_multiinfo(
|
||||
request: Request,
|
||||
version: int,
|
||||
args: Optional[list[str]] = Query(default=[], alias="arg[]"),
|
||||
):
|
||||
arg = args.pop(0) if args else None
|
||||
return await rpc_request(
|
||||
request,
|
||||
version,
|
||||
"info",
|
||||
defaults.RPC_SEARCH_BY,
|
||||
arg,
|
||||
args,
|
||||
)
|
||||
|
||||
|
||||
@router.post("/rpc/v{version}/info")
|
||||
async def rpc_openapi_multiinfo_post(
|
||||
request: Request,
|
||||
version: int,
|
||||
):
|
||||
data = await request.json()
|
||||
|
||||
args = data.get("arg", [])
|
||||
if not isinstance(args, list):
|
||||
rpc = RPC(version, "info")
|
||||
return JSONResponse(
|
||||
rpc.error("the 'arg' parameter must be of array type"),
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
)
|
||||
|
||||
arg = args.pop(0) if args else None
|
||||
return await rpc_request(
|
||||
request,
|
||||
version,
|
||||
"info",
|
||||
defaults.RPC_SEARCH_BY,
|
||||
arg,
|
||||
args,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/rpc/v{version}/search")
|
||||
async def rpc_openapi_search(
|
||||
request: Request,
|
||||
version: int,
|
||||
by: Optional[str] = Query(default=defaults.RPC_SEARCH_BY),
|
||||
arg: Optional[str] = Query(default=str()),
|
||||
):
|
||||
return await rpc_request(
|
||||
request,
|
||||
version,
|
||||
"search",
|
||||
by,
|
||||
arg,
|
||||
[],
|
||||
)
|
||||
|
||||
|
||||
@router.post("/rpc/v{version}/search")
|
||||
async def rpc_openapi_search_post(
|
||||
request: Request,
|
||||
version: int,
|
||||
):
|
||||
data = await request.json()
|
||||
by = data.get("by", defaults.RPC_SEARCH_BY)
|
||||
if not isinstance(by, str):
|
||||
rpc = RPC(version, "search")
|
||||
return JSONResponse(
|
||||
rpc.error("the 'by' parameter must be of string type"),
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
)
|
||||
|
||||
arg = data.get("arg", str())
|
||||
if not isinstance(arg, str):
|
||||
rpc = RPC(version, "search")
|
||||
return JSONResponse(
|
||||
rpc.error("the 'arg' parameter must be of string type"),
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
)
|
||||
|
||||
return await rpc_request(
|
||||
request,
|
||||
version,
|
||||
"search",
|
||||
by,
|
||||
arg,
|
||||
[],
|
||||
)
|
||||
|
|
|
@ -933,3 +933,98 @@ def test_rpc_too_many_info_results(client: TestClient, packages: list[Package]):
|
|||
with client as request:
|
||||
resp = request.get("/rpc", params=params)
|
||||
assert resp.json().get("error") == "Too many package results."
|
||||
|
||||
|
||||
def test_rpc_openapi_info(client: TestClient, packages: list[Package]):
|
||||
pkgname = packages[0].Name
|
||||
|
||||
with client as request:
|
||||
endp = f"/rpc/v5/info/{pkgname}"
|
||||
resp = request.get(endp)
|
||||
assert resp.status_code == HTTPStatus.OK
|
||||
|
||||
data = resp.json()
|
||||
assert data.get("resultcount") == 1
|
||||
|
||||
|
||||
def test_rpc_openapi_multiinfo(client: TestClient, packages: list[Package]):
|
||||
pkgname = packages[0].Name
|
||||
|
||||
with client as request:
|
||||
endp = "/rpc/v5/info"
|
||||
resp = request.get(endp, params={"arg[]": [pkgname]})
|
||||
assert resp.status_code == HTTPStatus.OK
|
||||
|
||||
data = resp.json()
|
||||
assert data.get("resultcount") == 1
|
||||
|
||||
|
||||
def test_rpc_openapi_multiinfo_post(client: TestClient, packages: list[Package]):
|
||||
pkgname = packages[0].Name
|
||||
|
||||
with client as request:
|
||||
endp = "/rpc/v5/info"
|
||||
resp = request.post(endp, json={"arg": [pkgname]})
|
||||
assert resp.status_code == HTTPStatus.OK
|
||||
|
||||
data = resp.json()
|
||||
assert data.get("resultcount") == 1
|
||||
|
||||
|
||||
def test_rpc_openapi_multiinfo_post_bad_request(
|
||||
client: TestClient, packages: list[Package]
|
||||
):
|
||||
pkgname = packages[0].Name
|
||||
|
||||
with client as request:
|
||||
endp = "/rpc/v5/info"
|
||||
resp = request.post(endp, json={"arg": pkgname})
|
||||
assert resp.status_code == HTTPStatus.BAD_REQUEST
|
||||
|
||||
data = resp.json()
|
||||
expected = "the 'arg' parameter must be of array type"
|
||||
assert data.get("error") == expected
|
||||
|
||||
|
||||
def test_rpc_openapi_search(client: TestClient, packages: list[Package]):
|
||||
pkgname = packages[0].Name
|
||||
|
||||
with client as request:
|
||||
endp = "/rpc/v5/search"
|
||||
resp = request.get(endp, params={"arg": pkgname})
|
||||
assert resp.status_code == HTTPStatus.OK
|
||||
|
||||
data = resp.json()
|
||||
assert data.get("resultcount") == 1
|
||||
|
||||
|
||||
def test_rpc_openapi_search_post(client: TestClient, packages: list[Package]):
|
||||
pkgname = packages[0].Name
|
||||
|
||||
with client as request:
|
||||
endp = "/rpc/v5/search"
|
||||
resp = request.post(endp, json={"arg": pkgname})
|
||||
assert resp.status_code == HTTPStatus.OK
|
||||
|
||||
data = resp.json()
|
||||
assert data.get("resultcount") == 1
|
||||
|
||||
|
||||
def test_rpc_openapi_search_post_bad_request(client: TestClient):
|
||||
# Test by parameter
|
||||
with client as request:
|
||||
endp = "/rpc/v5/search"
|
||||
resp = request.post(endp, json={"by": 1})
|
||||
assert resp.status_code == HTTPStatus.BAD_REQUEST
|
||||
data = resp.json()
|
||||
expected = "the 'by' parameter must be of string type"
|
||||
assert data.get("error") == expected
|
||||
|
||||
# Test arg parameter
|
||||
with client as request:
|
||||
endp = "/rpc/v5/search"
|
||||
resp = request.post(endp, json={"arg": ["a", "list"]})
|
||||
assert resp.status_code == HTTPStatus.BAD_REQUEST
|
||||
data = resp.json()
|
||||
expected = "the 'arg' parameter must be of string type"
|
||||
assert data.get("error") == expected
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue