Skip to content

Commit

Permalink
Merge branch 'master' into mypy-enable-no-implicit-optional
Browse files Browse the repository at this point in the history
  • Loading branch information
northernSage authored Oct 7, 2023
2 parents af3cf92 + f2e7608 commit 7fc3a44
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 44 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Unreleased
----------

- fix type signature in ``flask_caching.utils.make_template_fragment_key``. :pr:`430`
- Added docs and example for make_cache_key


Version 2.0.2
-------------
Expand All @@ -15,6 +17,7 @@ Released 2023-01-12
- migrate ``flask_caching.backends.RedisCluster`` dependency from redis-py-cluster to redis-py
- bug fix: make the ``make_cache_key`` attributed of decorated view functions writeable. :pr:`431`, issue `#97`


Version 2.0.1
-------------

Expand Down
36 changes: 32 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,33 @@ returned::

cached_comments = get_all_comments()

Make Custom `Cache Key`
-----------------------

Sometimes you want to define your cache key for each route. Using the same ``@cached``
decorator you are able to specify how this key is generated. This might be useful when
the key for cache is should not be just the default key_prefix, but has to be derived
from other parameters in a request. An example usecase would be for caching POST routes.
Where the cache key should be derived from the data in that request, rather than just the
route/view itself.

``make_cache_key`` can be used to specify such a function. The function should return a
string which should act like the key to the required value that is being cached::

def make_key():
"""A function which is called to derive the key for a computed value.
The key in this case is the concat value of all the json request
parameters. Other strategy could to use any hashing function.
:returns: unique string for which the value should be cached.
"""
user_data = request.get_json()
return ",".join([f"{key}={value}" for key, value in user_data.items()])

@app.route("/hello", methods=["POST"])
@cache.cached(timeout=60, make_cache_key=make_key)
def some_func():
....


Memoization
-----------
Expand Down Expand Up @@ -372,9 +399,9 @@ The following configuration values exist for Flask-Caching:
the cache class instantiation.
``CACHE_OPTIONS`` Optional dictionary to pass during the
cache class instantiation.
``CACHE_DEFAULT_TIMEOUT`` The default timeout that is used if no
``CACHE_DEFAULT_TIMEOUT`` The timeout that is used if no other
timeout is specified. Unit of time is
seconds.
seconds. Defaults to ``300``.
``CACHE_IGNORE_ERRORS`` If set to any errors that occurred during the
deletion process will be ignored. However, if
it is set to ``False`` it will stop on the
Expand All @@ -384,11 +411,12 @@ The following configuration values exist for Flask-Caching:
``CACHE_THRESHOLD`` The maximum number of items the cache
will store before it starts deleting
some. Used only for SimpleCache and
FileSystemCache
FileSystemCache. Defaults to ``500``.
``CACHE_KEY_PREFIX`` A prefix that is added before all keys.
This makes it possible to use the same
memcached server for different apps.
Used only for RedisCache and MemcachedCache
Used only for RedisCache and MemcachedCache.
Defaults to ``flask_cache_``.
``CACHE_SOURCE_CHECK`` The default condition applied to function
decorators which controls if the source code of
the function should be included when forming the
Expand Down
34 changes: 16 additions & 18 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,21 @@
#
alabaster==0.7.12
# via sphinx
asgiref==3.6.0
asgiref==3.7.2
# via -r tests.in
async-timeout==4.0.2
# via redis
babel==2.10.3
# via sphinx
build==0.8.0
# via pip-tools
cachelib==0.10.2
# via -r tests.in
cachetools==5.3.0
cachetools==5.3.1
# via tox
certifi==2022.12.7
certifi==2023.7.22
# via requests
cfgv==3.3.1
# via pre-commit
chardet==5.1.0
chardet==5.2.0
# via tox
charset-normalizer==2.1.0
# via requests
Expand All @@ -32,13 +30,13 @@ click==8.1.3
# pip-tools
colorama==0.4.6
# via tox
distlib==0.3.6
distlib==0.3.7
# via virtualenv
docutils==0.18.1
# via
# sphinx
# sphinx-tabs
filelock==3.10.7
filelock==3.12.3
# via
# tox
# virtualenv
Expand All @@ -64,7 +62,7 @@ markupsafe==2.1.1
# werkzeug
nodeenv==1.7.0
# via pre-commit
packaging==23.0
packaging==23.1
# via
# build
# pallets-sphinx-themes
Expand All @@ -76,13 +74,13 @@ pallets-sphinx-themes==2.0.3
# via -r docs.in
pep517==0.13.0
# via build
pip-tools==6.12.2
pip-tools==7.3.0
# via -r dev.in
platformdirs==3.2.0
platformdirs==3.10.0
# via
# tox
# virtualenv
pluggy==1.0.0
pluggy==1.3.0
# via
# pytest
# tox
Expand All @@ -92,13 +90,13 @@ psutil==5.9.1
# via pytest-xprocess
py==1.11.0
# via pytest-xprocess
pygments==2.12.0
pygments==2.15.0
# via
# sphinx
# sphinx-tabs
pylibmc==1.6.3
# via -r tests.in
pyproject-api==1.5.1
pyproject-api==1.6.1
# via tox
pytest==7.3.1
# via
Expand All @@ -113,9 +111,9 @@ pytz==2022.1
# via babel
pyyaml==6.0
# via pre-commit
redis==4.5.4
redis==5.0.0
# via -r tests.in
requests==2.28.1
requests==2.31.0
# via sphinx
snowballstemmer==2.2.0
# via sphinx
Expand Down Expand Up @@ -144,11 +142,11 @@ sphinxcontrib-qthelp==1.0.3
# via sphinx
sphinxcontrib-serializinghtml==1.1.5
# via sphinx
tox==4.4.8
tox==4.11.0
# via -r dev.in
urllib3==1.26.11
# via requests
virtualenv==20.21.0
virtualenv==20.24.4
# via
# pre-commit
# tox
Expand Down
6 changes: 3 additions & 3 deletions requirements/docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ alabaster==0.7.12
# via sphinx
babel==2.10.3
# via sphinx
certifi==2022.12.7
certifi==2023.7.22
# via requests
charset-normalizer==2.1.0
# via requests
Expand All @@ -30,15 +30,15 @@ packaging==21.3
# sphinx
pallets-sphinx-themes==2.0.3
# via -r docs.in
pygments==2.12.0
pygments==2.15.0
# via
# sphinx
# sphinx-tabs
pyparsing==3.0.9
# via packaging
pytz==2022.1
# via babel
requests==2.28.1
requests==2.31.0
# via sphinx
snowballstemmer==2.2.0
# via sphinx
Expand Down
6 changes: 2 additions & 4 deletions requirements/tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
#
# pip-compile tests.in
#
asgiref==3.6.0
asgiref==3.7.2
# via -r tests.in
async-timeout==4.0.2
# via redis
cachelib==0.10.2
# via -r tests.in
click==8.1.3
Expand Down Expand Up @@ -45,7 +43,7 @@ pytest-asyncio==0.21.0
# via -r tests.in
pytest-xprocess==0.22.2
# via -r tests.in
redis==4.5.4
redis==5.0.0
# via -r tests.in
werkzeug==2.2.3
# via flask
4 changes: 2 additions & 2 deletions requirements/typing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#
cffi==1.15.1
# via cryptography
cryptography==39.0.0
cryptography==41.0.4
# via
# types-pyopenssl
# types-redis
Expand All @@ -18,7 +18,7 @@ pycparser==2.21
# via cffi
types-pyopenssl==23.0.0.2
# via types-redis
types-redis==4.5.4.1
types-redis==4.6.0.5
# via -r typing.in
typing-extensions==4.3.0
# via mypy
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
# Metadata goes in setup.cfg. These are here for GitHub's dependency graph.
setup(
name="Flask-Caching",
install_requires=["cachelib >= 0.9.0, < 0.10.0", "Flask < 3"],
install_requires=["cachelib >= 0.9.0, < 0.10.0", "Flask"],
)
19 changes: 7 additions & 12 deletions src/flask_caching/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,13 @@
import uuid
import warnings
from collections import OrderedDict
from typing import Any
from typing import Callable
from typing import Optional
from typing import Tuple
from typing import Union
from typing import Any, Dict, List, Callable, Optional, Tuple, Union

from flask import current_app
from flask import Flask
from flask import request
from flask import Response
from flask import url_for
from markupsafe import Markup
from werkzeug.utils import import_string

from flask_caching.backends.base import BaseCache
Expand Down Expand Up @@ -185,7 +180,7 @@ def cache(self) -> SimpleCache:
app = current_app or self.app
return app.extensions["cache"][self]

def get(self, *args, **kwargs) -> Optional[Union[str, Markup]]:
def get(self, *args, **kwargs) -> Any:
"""Proxy function for internal cache object."""
return self.cache.get(*args, **kwargs)

Expand All @@ -205,7 +200,7 @@ def delete(self, *args, **kwargs) -> bool:
"""Proxy function for internal cache object."""
return self.cache.delete(*args, **kwargs)

def delete_many(self, *args, **kwargs) -> bool:
def delete_many(self, *args, **kwargs) -> List[str]:
"""Proxy function for internal cache object."""
return self.cache.delete_many(*args, **kwargs)

Expand All @@ -217,15 +212,15 @@ def get_many(self, *args, **kwargs):
"""Proxy function for internal cache object."""
return self.cache.get_many(*args, **kwargs)

def set_many(self, *args, **kwargs):
def set_many(self, *args, **kwargs) -> List[Any]:
"""Proxy function for internal cache object."""
return self.cache.set_many(*args, **kwargs)

def get_dict(self, *args, **kwargs):
def get_dict(self, *args, **kwargs) -> Dict[str, Any]:
"""Proxy function for internal cache object."""
return self.cache.get_dict(*args, **kwargs)

def unlink(self, *args, **kwargs) -> bool:
def unlink(self, *args, **kwargs) -> List[str]:
"""Proxy function for internal cache object
only support Redis
"""
Expand Down Expand Up @@ -474,7 +469,7 @@ def _make_cache_key_query_string():

return cache_key

def _make_cache_key(args, kwargs, use_request):
def _make_cache_key(args, kwargs, use_request) -> str:
if query_string:
return _make_cache_key_query_string()
else:
Expand Down

0 comments on commit 7fc3a44

Please sign in to comment.