1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
|
.. _RFC2616: https://tools.ietf.org/html/rfc2616#section-14.37
.. _ratelimit-conf:
Configuration
=============
Using Flask Config
------------------
The following :doc:`Flask Configuration <flask:config>` values are honored by
:class:`~flask_limiter.Limiter`. If the corresponding configuration value is also present
as an argument to the :class:`~flask_limiter.Limiter` constructor, the constructor argument will
take priority.
.. list-table::
* - .. data:: RATELIMIT_ENABLED
Constructor argument: :paramref:`~flask_limiter.Limiter.enabled`
- Overall kill switch for rate limits. Defaults to ``True``
* - .. data:: RATELIMIT_KEY_FUNC
Constructor argument: :paramref:`~flask_limiter.Limiter.key_func`
- A callable that returns the domain to rate limit (e.g. username, ip address etc)
* - .. data:: RATELIMIT_KEY_PREFIX
Constructor argument: :paramref:`~flask_limiter.Limiter.key_prefix`
- Prefix that is prepended to each stored rate limit key and app context
global name. This can be useful when using a shared storage for multiple
applications or rate limit domains. For multi-instance use cases, explicitly
pass ``key_prefix`` keyword argument to :class:`~flask_limiter.Limiter` constructor instead.
* - .. data:: RATELIMIT_APPLICATION
Constructor argument: :paramref:`~flask_limiter.Limiter.application_limits`
- A comma (or some other delimiter) separated string that will be used to
apply limits to the application as a whole (i.e. shared by all routes).
* - .. data:: RATELIMIT_APPLICATION_PER_METHOD
Constructor argument: :paramref:`~flask_limiter.Limiter.application_limits_per_method`
- Whether application limits are applied per method, per route or as a combination
of all method per route.
* - .. data:: RATELIMIT_APPLICATION_EXEMPT_WHEN
Constructor argument: :paramref:`~flask_limiter.Limiter.application_limits_exempt_when`
- A function that should return a truthy value if the application rate limit(s)
should be skipped for the current request. This callback is called from the
:doc:`flask request context <flask:reqcontext>` :meth:`~flask.Flask.before_request` hook.
* - .. data:: RATELIMIT_APPLICATION_DEDUCT_WHEN
Constructor argument: :paramref:`~flask_limiter.Limiter.application_limits_deduct_when`
- A function that should return a truthy value if a deduction should be made
from the application rate limit(s) for the current request. This callback is called
from the :doc:`flask request context <flask:reqcontext>` :meth:`~flask.Flask.after_request` hook.
* - .. data:: RATELIMIT_APPLICATION_COST
Constructor argument: :paramref:`~flask_limiter.Limiter.application_limits_cost`
- The cost of a hit to the application wide shared limit as an integer or a function
that takes no parameters and returns the cost as an integer (Default: 1)
* - .. data:: RATELIMIT_DEFAULT
Constructor argument: :paramref:`~flask_limiter.Limiter.default_limits`
- A comma (or some other delimiter) separated string that will be used to
apply a default limit on all routes that are otherwise not decorated with
an explicit rate limit. If not provided, the default limits can be
passed to the :class:`~flask_limiter.Limiter` constructor as well (the values passed to the
constructor take precedence over those in the config).
:ref:`ratelimit-string` for details.
* - .. data:: RATELIMIT_DEFAULTS_PER_METHOD
Constructor argument: :paramref:`~flask_limiter.Limiter.default_limits_per_method`
- Whether default limits are applied per method, per route or as a combination
of all method per route.
* - .. data:: RATELIMIT_DEFAULTS_COST
Constructor argument: :paramref:`~flask_limiter.Limiter.default_limits_cost`
- The cost of a hit to the default limits as an integer or a function
that takes no parameters and returns the cost as an integer (Default: 1)
* - .. data:: RATELIMIT_DEFAULTS_EXEMPT_WHEN
Constructor argument: :paramref:`~flask_limiter.Limiter.default_limits_exempt_when`
- A function that should return a truthy value if the default rate limit(s)
should be skipped for the current request. This callback is called from the
:doc:`flask request context <flask:reqcontext>` :meth:`~flask.Flask.before_request` hook.
* - .. data:: RATELIMIT_DEFAULTS_DEDUCT_WHEN
Constructor argument: :paramref:`~flask_limiter.Limiter.default_limits_deduct_when`
- A function that should return a truthy value if a deduction should be made
from the default rate limit(s) for the current request. This callback is called
from the :doc:`flask request context <flask:reqcontext>` :meth:`~flask.Flask.after_request` hook.
* - .. data:: RATELIMIT_STORAGE_URI
Constructor argument: :paramref:`~flask_limiter.Limiter.storage_uri`
- A storage location conforming to the scheme in :ref:`limits:storage:storage scheme`.
A basic in-memory storage can be used by specifying ``memory://`` but it
should be used with caution in any production setup since:
#. Each application process will have it's own storage
#. The state of the rate limits will not persist beyond the process' life-time.
Other supported backends include:
- Memcached: ``memcached://host:port``
- MongoDB: ``mongodb://host:port``
- Redis: ``redis://host:port``
For specific examples and requirements of supported backends please
refer to :ref:`limits:storage:storage scheme` and the :doc:`limits <limits:storage>` library.
* - .. data:: RATELIMIT_STORAGE_OPTIONS
Constructor argument: :paramref:`~flask_limiter.Limiter.storage_options`
- A dictionary to set extra options to be passed to the storage implementation
upon initialization.
* - .. data:: RATELIMIT_REQUEST_IDENTIFIER
Constructor argument: :paramref:`~flask_limiter.Limiter.request_identifier`
- A callable that returns the unique identity of the current request. Defaults to :attr:`flask.Request.endpoint`
* - .. data:: RATELIMIT_STRATEGY
Constructor argument: :paramref:`~flask_limiter.Limiter.strategy`
- The rate limiting strategy to use. :ref:`ratelimit-strategy`
for details.
* - .. data:: RATELIMIT_HEADERS_ENABLED
Constructor argument: :paramref:`~flask_limiter.Limiter.headers_enabled`
- Enables returning :ref:`ratelimit-headers`. Defaults to ``False``
* - .. data:: RATELIMIT_HEADER_LIMIT
Constructor argument: :paramref:`~flask_limiter.Limiter.header_name_mapping`
- Header for the current rate limit. Defaults to ``X-RateLimit-Limit``
* - .. data:: RATELIMIT_HEADER_RESET
Constructor argument: :paramref:`~flask_limiter.Limiter.header_name_mapping`
- Header for the reset time of the current rate limit. Defaults to ``X-RateLimit-Reset``
* - .. data:: RATELIMIT_HEADER_REMAINING
Constructor argument: :paramref:`~flask_limiter.Limiter.header_name_mapping`
- Header for the number of requests remaining in the current rate limit. Defaults to ``X-RateLimit-Remaining``
* - .. data:: RATELIMIT_HEADER_RETRY_AFTER
Constructor argument: :paramref:`~flask_limiter.Limiter.header_name_mapping`
- Header for when the client should retry the request. Defaults to ``Retry-After``
* - .. data:: RATELIMIT_HEADER_RETRY_AFTER_VALUE
Constructor argument: :paramref:`~flask_limiter.Limiter.retry_after`
- Allows configuration of how the value of the ``Retry-After`` header is rendered.
One of ``http-date`` or ``delta-seconds``. (`RFC2616`_).
* - .. data:: RATELIMIT_SWALLOW_ERRORS
Constructor argument: :paramref:`~flask_limiter.Limiter.swallow_errors`
- Whether to allow failures while attempting to perform a rate limit
such as errors with downstream storage. Setting this value to ``True``
will effectively disable rate limiting for requests where an error has
occurred.
* - .. data:: RATELIMIT_IN_MEMORY_FALLBACK_ENABLED
Constructor argument: :paramref:`~flask_limiter.Limiter.in_memory_fallback_enabled`
- ``True``/``False``. If enabled an in memory rate limiter will be used
as a fallback when the configured storage is down. Note that, when used in
combination with ``RATELIMIT_IN_MEMORY_FALLBACK`` the original rate limits
will not be inherited and the values provided in
* - .. data:: RATELIMIT_IN_MEMORY_FALLBACK
Constructor argument: :paramref:`~flask_limiter.Limiter.in_memory_fallback`
- A comma (or some other delimiter) separated string
that will be used when the configured storage is down.
* - .. data:: RATELIMIT_FAIL_ON_FIRST_BREACH
Constructor argument: :paramref:`~flask_limiter.Limiter.fail_on_first_breach`
- Whether to stop processing remaining limits after the first breach.
Default to ``True``
* - .. data:: RATELIMIT_ON_BREACH_CALLBACK
Constructor argument: :paramref:`~flask_limiter.Limiter.on_breach`
- A function that will be called when any limit in this
extension is breached.
* - .. data:: RATELIMIT_META
Constructor argument: :paramref:`~flask_limiter.Limiter.meta_limits`
- A comma (or some other delimiter) separated string that will be used to
control the upper limit of a requesting client hitting any configured rate limit.
Once a meta limit is exceeded all subsequent requests will raise a
:class:`~flask_limiter.RateLimitExceeded` for the duration of the meta limit window.
* - .. data:: RATELIMIT_ON_META_BREACH_CALLBACK
Constructor argument: :paramref:`~flask_limiter.Limiter.on_meta_breach`
- A function that will be called when a meta limit in this
extension is breached.
.. _ratelimit-string:
Rate limit string notation
--------------------------
Rate limits are specified as strings following the format::
[count] [per|/] [n (optional)] [second|minute|hour|day|month|year][s]
You can combine multiple rate limits by separating them with a delimiter of your
choice.
Examples
^^^^^^^^
* ``10 per hour``
* ``10 per 2 hours``
* ``10/hour``
* ``5/2 seconds;10/hour;100/day;2000 per year``
* ``100/day, 500/7 days``
.. warning:: If rate limit strings that are provided to the :meth:`~flask_limiter.Limiter.limit`
decorator are malformed and can't be parsed the decorated route will fall back
to the default rate limit(s) and an ``ERROR`` log message will be emitted. Refer
to :ref:`logging` for more details on capturing this information. Malformed
default rate limit strings will however raise an exception as they are evaluated
early enough to not cause disruption to a running application.
.. _ratelimit-headers:
Rate-limiting Headers
---------------------
If the configuration is enabled, information about the rate limit with respect to the
route being requested will be added to the response headers. Since multiple rate limits
can be active for a given route - the rate limit with the lowest time granularity will be
used in the scenario when the request does not breach any rate limits.
.. tabularcolumns:: |p{8cm}|p{8.5cm}|
============================== ================================================
``X-RateLimit-Limit`` The total number of requests allowed for the
active window
``X-RateLimit-Remaining`` The number of requests remaining in the active
window.
``X-RateLimit-Reset`` UTC seconds since epoch when the window will be
reset.
``Retry-After`` Seconds to retry after or the http date when the
Rate Limit will be reset. The way the value is presented
depends on the configuration value set in :data:`RATELIMIT_HEADER_RETRY_AFTER_VALUE`
and defaults to `delta-seconds`.
============================== ================================================
The header names can be customised if required by either using the flask configuration (
:attr:`RATELIMIT_HEADER_LIMIT`,
:attr:`RATELIMIT_HEADER_RESET`,
:attr:`RATELIMIT_HEADER_RETRY_AFTER`,
:attr:`RATELIMIT_HEADER_REMAINING`
)
values or by providing the :paramref:`~flask_limiter.Limiter.header_name_mapping` argument
to the extension constructor as follows::
from flask_limiter import Limiter, HEADERS
limiter = Limiter(header_name_mapping={
HEADERS.LIMIT : "X-My-Limit",
HEADERS.RESET : "X-My-Reset",
HEADERS.REMAINING: "X-My-Remaining"
}
)
|