diff --git a/folksonomy/api.py b/folksonomy/api.py index 50b3eeb..7079d91 100644 --- a/folksonomy/api.py +++ b/folksonomy/api.py @@ -605,30 +605,38 @@ async def product_tag_delete(response: Response, @app.get("/keys", response_model=List[KeyStats]) -async def keys_list(response: Response, - owner='', - user: User = Depends(get_current_user)): +async def keys_list( + response: Response, + q: Optional[str] = '', + owner: str = '', + user: User = Depends(get_current_user) +): """ - Get the list of keys with statistics + Get the list of keys with statistics, with an optional search filter. The keys list can be restricted to private tags from some owner """ check_owner_user(user, owner, allow_anonymous=True) - cur, timing = await db.db_exec( - """ - SELECT json_agg(j.j)::json FROM( + + search_filter = f"AND k ILIKE %s" if q else "" + query = f""" + SELECT json_agg(j)::json FROM ( SELECT json_build_object( - 'k',k, - 'count',count(*), - 'values',count(distinct(v)) - ) as j + 'k', k, + 'count', COUNT(*), + 'values', COUNT(distinct v) + ) AS j FROM folksonomy - WHERE owner=%s - GROUP BY k - ORDER BY count(*) DESC) as j; - """, - (owner,) - ) + WHERE owner = %s + {search_filter} + GROUP BY k + ORDER BY count(*) DESC + ) AS j; + """ + + query_params = [owner] + ([f"%{q}%"] if q else []) + + cur, timing = await db.db_exec(query, tuple(query_params)) out = await cur.fetchone() return JSONResponse( diff --git a/tests/test_main.py b/tests/test_main.py index f8e5628..716618e 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -410,6 +410,22 @@ def test_keys_list(with_sample): {'k': 'size', 'count': 2, 'values': 2} ] + response = client.get("/keys?q=col") + assert response.status_code == 200 + assert response.json() == [ + {'k': 'color', 'count': 3, 'values': 2} + ] + + response = client.get("/keys?q=siz") + assert response.status_code == 200 + assert response.json() == [ + {'k': 'size', 'count': 2, 'values': 2} + ] + + response = client.get("/keys?q=xyz") + assert response.status_code == 200 + assert response.json() == [] + def test_get_unique_values(with_sample): with TestClient(app) as client: