# Path: axes/conf.py

# 
# Path: axes/models.py
# class AccessBase(models.Model):
#     user_agent = models.CharField(_("User Agent"), max_length=255, db_index=True)
# 
#     ip_address = models.GenericIPAddressField(_("IP Address"), null=True, db_index=True)
# 
#     username = models.CharField(_("Username"), max_length=255, null=True, db_index=True)
# 
#     http_accept = models.CharField(_("HTTP Accept"), max_length=1025)
# 
#     path_info = models.CharField(_("Path"), max_length=255)
# 
#     attempt_time = models.DateTimeField(_("Attempt Time"), auto_now_add=True)
# 
#     class Meta:
#         app_label = "axes"
#         abstract = True
#         ordering = ["-attempt_time"]


from datetime import timedelta
from hashlib import md5
from logging import getLogger
from string import Template
from typing import Callable, Optional, Type, Union
from urllib.parse import urlencode
from django.core.cache import caches, BaseCache
from django.http import HttpRequest, HttpResponse, JsonResponse, QueryDict
from django.shortcuts import render, redirect
from django.utils.module_loading import import_string
from axes.conf import settings
from axes.models import AccessBase
import ipware.ip

        if settings.AXES_USE_USER_AGENT:
            # 4. The HTTP User-Agent can be used to track e.g. one browser
            filter_query.append({"user_agent": user_agent})

    return filter_query


def make_cache_key_list(filter_kwargs_list):
    cache_keys = []
    for filter_kwargs in filter_kwargs_list:
        cache_key_components = "".join(
            value for value in filter_kwargs.values() if value
        )
        cache_key_digest = md5(cache_key_components.encode()).hexdigest()
        cache_keys.append(f"axes-{cache_key_digest}")
    return cache_keys


def get_client_cache_key(
    request_or_attempt: Union[HttpRequest, AccessBase], credentials: dict = None
) -> str:
    """
    Build cache key name from request or AccessAttempt object.

    :param request_or_attempt: HttpRequest or AccessAttempt object
    :param credentials: credentials containing user information
    :return cache_key: Hash key that is usable for Django cache backends
    """


# Path: axes/conf.py

# 
# Path: axes/models.py
# class AccessBase(models.Model):
#     user_agent = models.CharField(_("User Agent"), max_length=255, db_index=True)
# 
#     ip_address = models.GenericIPAddressField(_("IP Address"), null=True, db_index=True)
# 
#     username = models.CharField(_("Username"), max_length=255, null=True, db_index=True)
# 
#     http_accept = models.CharField(_("HTTP Accept"), max_length=1025)
# 
#     path_info = models.CharField(_("Path"), max_length=255)
# 
#     attempt_time = models.DateTimeField(_("Attempt Time"), auto_now_add=True)
# 
#     class Meta:
#         app_label = "axes"
#         abstract = True
#         ordering = ["-attempt_time"]


# Path: axes/helpers.py
from datetime import timedelta
from hashlib import md5
from logging import getLogger
from string import Template
from typing import Callable, Optional, Type, Union
from urllib.parse import urlencode
from django.core.cache import caches, BaseCache
from django.http import HttpRequest, HttpResponse, JsonResponse, QueryDict
from django.shortcuts import render, redirect
from django.utils.module_loading import import_string
from axes.conf import settings
from axes.models import AccessBase
import ipware.ip


        if settings.AXES_USE_USER_AGENT:
            # 4. The HTTP User-Agent can be used to track e.g. one browser
            filter_query.append({"user_agent": user_agent})

    return filter_query


def make_cache_key_list(filter_kwargs_list):
    cache_keys = []
    for filter_kwargs in filter_kwargs_list:
        cache_key_components = "".join(
            value for value in filter_kwargs.values() if value
        )
        cache_key_digest = md5(cache_key_components.encode()).hexdigest()
        cache_keys.append(f"axes-{cache_key_digest}")
    return cache_keys


def get_client_cache_key(
    request_or_attempt: Union[HttpRequest, AccessBase], credentials: dict = None
) -> str:
    """
    Build cache key name from request or AccessAttempt object.

    :param request_or_attempt: HttpRequest or AccessAttempt object
    :param credentials: credentials containing user information
    :return cache_key: Hash key that is usable for Django cache backends
    """


    if isinstance(request_or_attempt, AccessBase):