How to Build a Simple Filter Helper in Python for API Design
Create a reusable data filter service with dataclasses that mimics gRPC request/response patterns for filtering dataset records.
Python code
63 linesfrom dataclasses import dataclass, field
from typing import List, Optional, Dict, Any
@dataclass
class FilterRequest:
"""A simple filter request mirroring a gRPC message structure."""
field_name: str
operator: str # eq, ne, gt, lt, contains
value: Any
page_size: int = 10
page_token: Optional[str] = None
@dataclass
class FilterResponse:
results: List[Dict[str, Any]] = field(default_factory=list)
next_page_token: Optional[str] = None
class DataFilterService:
"""A stateless filter service (like a gRPC service handler)."""
def __init__(self, dataset: List[Dict[str, Any]]):
self.dataset = dataset
def filter(self, request: FilterRequest) -> FilterResponse:
filtered = []
for item in self.dataset:
if field_name not in item:
continue
value = item[field_name]
if request.operator == "eq" and value == request.value:
filtered.append(item)
elif request.operator == "ne" and value != request.value:
filtered.append(item)
elif request.operator == "gt" and value > request.value:
filtered.append(item)
elif request.operator == "lt" and value < request.value:
filtered.append(item)
elif request.operator == "contains" and request.value in value:
filtered.append(item)
if len(filtered) >= request.page_size:
break
return FilterResponse(results=filtered)
if __name__ == "__main__":
sample_data = [
{"name": "Alice", "age": 30, "city": "NYC"},
{"name": "Bob", "age": 25, "city": "LA"},
{"name": "Charlie", "age": 35, "city": "NYC"},
{"name": "Diana", "age": 28, "city": "SF"},
]
service = DataFilterService(sample_data)
req = FilterRequest(field_name="city", operator="eq", value="NYC", page_size=10)
resp = service.filter(req)
print("NYC residents:", [r["name"] for r in resp.results])
req2 = FilterRequest(field_name="age", operator="gt", value=26, page_size=10)
resp2 = service.filter(req2)
print("Over 26:", [r["name"] for r in resp2.results])
Output
NYC residents: ['Alice', 'Charlie']
Over 26: ['Alice', 'Charlie', 'Diana']
How it works
The FilterRequest and FilterResponse dataclasses mirror gRPC message structures, giving a clean contract for API input/output. The DataFilterService.filter method iterates through the dataset, applying the operator logic (eq, ne, gt, lt, contains) against the specified field. page_size limits results to a batch, echoing pagination patterns used in real gRPC or REST APIs. The field_name check skips items missing the key, preventing KeyError. This stateless design allows the service to handle requests independently, like a gRPC handler.
Common mistakes
- Forgetting to check if the field exists in the item before accessing it, causing KeyError
- Assuming all values are comparable (e.g., mixing integers and strings with gt/lt)
- Not handling the 'contains' operator for non-string values, which raises TypeError
- Overlooking pagination when dataset grows beyond page_size and no next_page_token is returned
Variations
- Use a dictionary of operator functions for cleaner dispatch: operators = {'eq': lambda a,b: a == b, ...}
- Add a 'sort_by' field to FilterRequest to order results before pagination
Real-world use cases
- Implementing a gRPC server endpoint that filters records for a mobile app's search feature.
- Building a lightweight API gateway that queries an in-memory dataset for testing before swapping to a database.
- Creating a command-line tool that uses filter logic to parse and select config entries for deployment scripts.
Sponsored
More from API design & gRPC
- Build a Bulk Array POST Mock Server in Python medium
- Build a Mock REST API with PUT and GET in Python medium
- Convert Protobuf to JSON and Dict in Python easy
- Create a Data Helper in Python for gRPC-style APIs easy
- Format data in Python using dataclasses like gRPC messages easy
- Generate an OpenAPI Spec from Mock Routes in Python easy
Keep learning
Related tutorials and quizzes for this topic.