Skip to content

Commit 8dfd433

Browse files
committed
Properly split /api/filters endpoint handlers
1 parent 094c1e0 commit 8dfd433

File tree

4 files changed

+64
-10
lines changed

4 files changed

+64
-10
lines changed

gramps_webapi/api/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from .resources.citation import CitationResource, CitationsResource
1515
from .resources.event import EventResource, EventsResource
1616
from .resources.family import FamiliesResource, FamilyResource
17-
from .resources.filters import FilterResource
17+
from .resources.filters import FilterResource, FiltersResource
1818
from .resources.media import MediaObjectResource, MediaObjectsResource
1919
from .resources.metadata import MetadataResource
2020
from .resources.name_groups import NameGroupsResource
@@ -81,7 +81,7 @@ def register_endpt(resource: Type[Resource], url: str, name: str):
8181
register_endpt(BookmarksResource, "/bookmarks/", "bookmarks")
8282
# Filter
8383
register_endpt(FilterResource, "/filters/<string:namespace>/<string:name>", "filter")
84-
register_endpt(FilterResource, "/filters/<string:namespace>", "filters")
84+
register_endpt(FiltersResource, "/filters/<string:namespace>", "filters")
8585
# Translate
8686
register_endpt(TranslationResource, "/translations/<string:isocode>", "translation")
8787
register_endpt(TranslationsResource, "/translations/", "translations")

gramps_webapi/api/resources/filters.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Gramps filter interface."""
22

33
import json
4-
from typing import Dict, List, Set
4+
from typing import Any, Dict, List, Set
55

66
import gramps.gen.filters as filters
77
from flask import Response, abort
@@ -29,7 +29,7 @@
2929
}
3030

3131

32-
def get_filter_rules(args: Dict[str, str], namespace: str) -> List[Dict]:
32+
def get_filter_rules(args: Dict[str, Any], namespace: str) -> List[Dict]:
3333
"""Return a list of available filter rules for a namespace."""
3434
rule_list = []
3535
for rule_class in _RULES_LOOKUP[namespace]:
@@ -52,7 +52,7 @@ def get_filter_rules(args: Dict[str, str], namespace: str) -> List[Dict]:
5252
return rule_list
5353

5454

55-
def get_custom_filters(args: Dict[str, str], namespace: str) -> List[Dict]:
55+
def get_custom_filters(args: Dict[str, Any], namespace: str) -> List[Dict]:
5656
"""Return a list of custom filters for a namespace."""
5757
filter_list = []
5858
filters.reload_custom_filters()
@@ -164,8 +164,8 @@ class CustomFilterSchema(FilterSchema):
164164
)
165165

166166

167-
class FilterResource(ProtectedResource, GrampsJSONEncoder):
168-
"""Filter resource."""
167+
class FiltersResource(ProtectedResource, GrampsJSONEncoder):
168+
"""Filters resource."""
169169

170170
@use_args(
171171
{
@@ -228,6 +228,23 @@ def put(self, args: Dict, namespace: str) -> Response:
228228
)
229229
return abort(404)
230230

231+
232+
class FilterResource(ProtectedResource, GrampsJSONEncoder):
233+
"""Filter resource."""
234+
235+
def get(self, namespace: str, name: str) -> Response:
236+
"""Get a custom filter."""
237+
try:
238+
namespace = GRAMPS_NAMESPACES[namespace]
239+
except KeyError:
240+
abort(404)
241+
242+
args = {"filters": [name]}
243+
filter_list = get_custom_filters(args, namespace)
244+
if len(filter_list) == 0:
245+
abort(404)
246+
return self.response(200, filter_list[0])
247+
231248
@use_args(
232249
{
233250
"force": fields.Str(validate=validate.Length(equal=0)),

gramps_webapi/data/apispec.yaml

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1909,10 +1909,38 @@ paths:
19091909
description: "Forbidden: Bad credentials, authentication failed."
19101910

19111911
/filters/{namespace}/{name}:
1912+
get:
1913+
tags:
1914+
- filters
1915+
summary: "Get a custom filter for a given namespace or category."
1916+
operationId: getFilter
1917+
security:
1918+
- Bearer: []
1919+
parameters:
1920+
- name: namespace
1921+
in: path
1922+
required: true
1923+
type: string
1924+
description: "The namespace or category for the custom filter."
1925+
- name: name
1926+
in: path
1927+
required: true
1928+
type: string
1929+
description: "The name of a custom filter."
1930+
responses:
1931+
200:
1932+
description: "OK: Successful operation."
1933+
schema:
1934+
$ref: "#/definitions/CustomFilter"
1935+
401:
1936+
description: "Unauthorized: Missing authorization header."
1937+
404:
1938+
description: "Not Found: Namespace or filter not found."
1939+
19121940
delete:
19131941
tags:
19141942
- filters
1915-
summary: "Delete a custom filter."
1943+
summary: "Delete a custom filter in a given namespace or category."
19161944
operationId: deleteFilter
19171945
security:
19181946
- Bearer: []

tests/test_endpoints/runners.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,16 +248,25 @@ def run_test_filters_endpoint_namespace(test, namespace: str, payload: Dict):
248248
# check response if filter already exists
249249
result = test.client.post("/api/filters/" + namespace, json=payload)
250250
test.assertEqual(result.status_code, 422)
251-
# check can fetch the filter
251+
# check can fetch the filter using query parm
252252
result = test.client.get("/api/filters/" + namespace + "?filters=" + filter_name)
253253
test.assertEqual(result.status_code, 200)
254254
test.assertTrue(len(result.json) == 1 and len(result.json["filters"]) == 1)
255255
test.assertEqual(result.json["filters"][0]["name"], filter_name)
256-
# check response if fetching filter that does not exist
256+
# check can fetch the filter using path
257+
result = test.client.get("/api/filters/" + namespace + "/" + filter_name)
258+
test.assertEqual(result.status_code, 200)
259+
test.assertEqual(result.json["name"], filter_name)
260+
# check response if fetching filter using query parm that does not exist
257261
result = test.client.get(
258262
"/api/filters/" + namespace + "?filters=" + filter_name + "Missing"
259263
)
260264
test.assertEqual(result.status_code, 404)
265+
# check response if fetching filter using path that does not exist
266+
result = test.client.get(
267+
"/api/filters/" + namespace + "/" + filter_name + "Missing"
268+
)
269+
test.assertEqual(result.status_code, 404)
261270
# check response applying filter that does not exist
262271
result = test.client.get(
263272
"/api/" + namespace + "/?filter=" + filter_name + "Missing"

0 commit comments

Comments
 (0)