Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions usaspending_api/common/cache.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import hashlib
import json
from typing import Any, Callable

from rest_framework.request import Request
from rest_framework.views import APIView
from rest_framework_extensions.key_constructor import bits
from rest_framework_extensions.key_constructor.constructors import DefaultKeyConstructor

Expand All @@ -12,7 +15,9 @@ class PathKeyBit(bits.QueryParamsKeyBit):
Adds query path as a key bit
"""

def get_source_dict(self, params, view_instance, view_method, request, args, kwargs):
def get_source_dict(
self, params: dict, view_instance: APIView, view_method: Callable, request: Request, args: Any, kwargs: Any
) -> dict[str, str]:
return {"path": request.path}


Expand All @@ -22,14 +27,17 @@ class GetPostQueryParamsKeyBit(bits.QueryParamsKeyBit):
directives in a POST request (i.e., request.data) as well as GET parameters
"""

def get_source_dict(self, params, view_instance, view_method, request, args, kwargs):
def get_source_dict(
self, params: dict, view_instance: APIView, view_method: Callable, request: Request, args: Any, kwargs: Any
) -> dict[str, str]:

if hasattr(view_instance, "cache_key_whitelist"):
whitelist = view_instance.cache_key_whitelist
params = {}
for param in whitelist:
if param in request.query_params:
params[param] = request.query_params[param]
# Currently, the only view with a whitelist attr is RecipientCount
# RecipientCount only reads the request body, not query params.
# Take this into consideration when implementing whitelist attr
if param in request.data:
params[param] = request.data[param]
else:
Expand All @@ -43,14 +51,14 @@ def get_source_dict(self, params, view_instance, view_method, request, args, kwa

class USAspendingKeyConstructor(DefaultKeyConstructor):
"""
Handle cache key construction for API requests. If we never need to create more nuanced keys, see the
Handle cache key construction for API requests. If we ever need to create more nuanced keys, see the
drf-extensions documentation: http://chibisov.github.io/drf-extensions/docs/#default-key-constructor
"""

path_bit = PathKeyBit()
request_params = GetPostQueryParamsKeyBit()

def prepare_key(self, key_dict):
def prepare_key(self, key_dict: dict) -> str:
# Order the key_dict using the order_nested_object function to make sure cache keys are always exactly the same
ordered_key_dict = json.dumps(order_nested_object(key_dict))
key_hex = hashlib.md5(ordered_key_dict.encode("utf-8"), usedforsecurity=False).hexdigest()
Expand Down
Loading