# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['request_profiler', 'request_profiler.migrations']

package_data = \
{'': ['*']}

install_requires = \
['django>=2.2,<4.0']

setup_kwargs = {
    'name': 'django-request-profiler',
    'version': '0.15.1',
    'description': 'A simple Django project profiler for timing HTTP requests.',
    'long_description': '.. image:: https://badge.fury.io/py/django-request-profiler.svg\n    :target: https://badge.fury.io/py/django-request-profiler\n\n.. image:: https://travis-ci.org/yunojuno/django-request-profiler.svg\n    :target: https://travis-ci.org/yunojuno/django-request-profiler\n\nDjango Request Profiler\n=======================\n\n**This package now requires Python3 and Django 1.11 and above. For previous versions please refer to the Python2 branch.**\n\nA very simple request profiler for Django.\n\nIntroduction\n------------\n\n    Premature optimization is the root of all evil.\n\nThere are a lot of very good, and complete, python and django profilers\navailable. They can give you detailed stack traces and function call timings,\noutput all the SQL statements that have been run, the templates that have been\nrendered, and the state of any / all variables along the way. These tools are\ngreat for optimisation of your application, once you have decided that the\ntime is right.\n\n``django-request-profiler`` is not intended to help you optimise, but to help\nyou decide whether you need to optimise in the first place. It is complimentary.\n\nRequirements\n------------\n\n1. Small enough to run in production\n2. Able to configure profiling at runtime\n3. Configurable to target specific URLs or users\n4. Record basic request metadata:\n\n- Duration (request-response)\n- Request path, remote addr, user-agent\n- Response status code, content length\n- View function\n- Django user and session keys (if appropriate)\n- Database query count (if DEBUG=True)\n\nIt doesn\'t need to record all the inner timing information - the goal is to have\na system that can be used to monitor site response times, and to identify\nproblem areas ahead of time.\n\nTechnical details\n-----------------\n\nThe profiler itself runs as Django middleware, and it simply starts a timer when\nit first sees the request, and stops the timer when it is finished with the\nresponse. It should be installed as the first middleware in\n``MIDDLEWARE_CLASSES`` in order to record the maximum duration.\n\nIt hooks into the  ``process_request`` method to start the timer, the\n``process_view`` method to record the view function name, and the\n``process_response`` method to stop the timer, record all the request\ninformation and store the instance.\n\nThe profiler is controlled by adding ``RuleSet`` instances which are used to\nfilter which requests are profiled. There can be many, overlapping,\nRuleSets, but if any match, the request is profiled. The RuleSet model\ndefines two core matching methods:\n\n1. uri_regex - in order to profile a subset of the site, you can supply a regex\nwhich is used match the incoming request path. If the url matches, the request\ncan be profiled.\n\n2. user_filter_type - there are three choices here - profile all users, profile\nonly authenticated users, and profile authenticated users belonging to a given\nGroup - e.g. create a groups called "profiling" and add anyone you want to\nprofile.\n\nThese filter properties are an AND (must pass the uri and user filter), but the\nrules as a group are an OR - so if a request passes all the filters in any rule,\nthen it\'s profiled.\n\nThese filters are pretty blunt, and there are plenty of use cases where you may\nwant more sophisticated control over the profiling. There are two ways to do\nthis. The first is a setting, ``REQUEST_PROFILER_GLOBAL_EXCLUDE_FUNC``, which is\na function that takes a request as the single argument, and must return True or\nFalse. If it returns False, the profile is cancelled, irrespective of any rules.\nThe primary use case for this is to exclude common requests that you are not\ninterested in, e.g. from search engine bots, or from Admin users etc. The\ndefault for this function is to prevent admin user requests from being profiled.\n\nThe second control is via the ``cancel()`` method on the ``ProfilingRecord``,\nwhich is accessible via the ``request_profile_complete`` signal. By hooking\nin to this signal you can add additional processing, and optionally cancel\nthe profiler. A typical use case for this is to log requests that have\nexceeded a set request duration threshold. In a high volume environment you\nmay want to, for instance, only profile a random subset of all requests.\n\n.. code:: python\n\n    from django.dispatch import receiver\n    from request_profiler.signals import request_profile_complete\n\n    @receiver(request_profiler_complete)\n    def on_request_profile_complete(sender, **kwargs):\n        profiler = kwargs.get(\'instance\')\n        if profiler.elapsed > 2:\n            # log long-running requests\n            # NB please don\'t use \'print\' for real - use logging\n            print u"Long-running request warning: %s" % profiler\n        else:\n            # calling cancel means that it won\'t be saved to the db\n            profiler.cancel()\n\n\nInstallation\n------------\n\nThis app has dropped support for Django < 1.7, since v0.11.\n\nFor use as the app in Django project, use pip:\n\n.. code:: shell\n\n    $ pip install django-request-profiler\n    # For hacking on the project, pull from Git:\n    $ git pull git@github.com:yunojuno/django-request-profiler.git\n\nTests\n-----\n\nThe app installer contains a test suite that can be run using the Django\ntest runner:\n\n.. code:: shell\n\n    $ pip install -r requirements.txt\n    $ python manage.py test test_app request_profiler\n\nIf you want to test coverage you\'ll need to add some dependencies:\n\n.. code:: shell\n\n    $ pip install coverage django-coverage\n    $ python manage.py test_coverage test_app request_profiler\n\nThe tests also run using `tox <https://testrun.org/tox/latest/>`_:\n\n.. code:: shell\n\n    $ pip install tox\n    $ tox\n\n**Note: To test with a custom user model, you should override the default User model\nby providing a value for the AUTH_USER_MODEL (in testapp/settings) setting that references a custom model**\n\nThe tests run on `Travis <https://travis-ci.org/yunojuno/django-request-profiler>`_ on commits to master.\n\nUsage\n-----\n\nOnce installed, add the app and middleware to your project\'s settings file.\nIn order to add the database tables, you should run the ``migrate`` command:\n\n.. code:: bash\n\n    $ python manage.py migrate request_profiler\n\nNB the middleware must be the **first** item in ``MIDDLEWARE_CLASSES``.\n\n.. code:: python\n\n    INSTALLED_APPS = (\n        \'django.contrib.admin\',\n        \'django.contrib.auth\',\n        \'django.contrib.contenttypes\',\n        \'django.contrib.sessions\',\n        \'django.contrib.messages\',\n        \'django.contrib.staticfiles\',\n        \'request_profiler\',\n    )\n\n    MIDDLEWARE_CLASSES = [\n        # this package\'s middleware\n        \'request_profiler.middleware.ProfilingMiddleware\',\n        # default django middleware\n        \'django.middleware.common.CommonMiddleware\',\n        \'django.contrib.sessions.middleware.SessionMiddleware\',\n        \'django.contrib.auth.middleware.AuthenticationMiddleware\',\n        \'django.middleware.csrf.CsrfViewMiddleware\',\n        \'django.contrib.messages.middleware.MessageMiddleware\',\n    ]\n\nConfiguration\n-------------\n\nTo configure the app, open the admin site, and add a new request profiler\n\'Rule set\'. The default options will result in all non-admin requests being\nprofiled.\n\nLicence\n-------\n\nMIT (see LICENCE)\n\n',
    'author': 'YunoJuno',
    'author_email': 'code@yunojuno.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/yunojuno/django-request-profiler',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.7,<4.0',
}


setup(**setup_kwargs)
