# -*- coding: utf-8 -*-
from distutils.core import setup

packages = \
['falcon_epdb']

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

install_requires = \
['epdb>=0.15.1,<0.16.0']

extras_require = \
{'fernet': ['cryptography>=2.5,<3.0'], 'jwt': ['PyJWT>=1.7,<2.0']}

setup_kwargs = {
    'name': 'falcon-epdb',
    'version': '1.1.2',
    'description': 'Interactive debugging for your Falco apps',
    'long_description': '###########\nfalcon-epdb\n###########\n\n|pypi| |build| |coverage| |src| |docs| |pyversions| |license| |black|\n\nA `Falcon middleware`__ that wraps the excellent `epdb`_ tool and allows one to connect to a running Falcon app and use interactive debugging to step through the code.\n\nBetter documentation can be found at `readthedocs`_.\n\nSource code can be found on GitHub at `jcwilson/falcon-epdb`__.\n\n__ Falcon_middleware_\n\n.. _Falcon_middleware: https://falcon.readthedocs.io/en/stable/api/middleware.html\n\n__ jcwilson_falcon_epdb_\n\n.. _jcwilson_falcon_epdb: https://github.com/jcwilson/falcon-epdb\n\n.. _readthedocs: https://falcon-epdb.readthedocs.io\n\n\n************\nInstallation\n************\nIf you are only planning on debugging in a development environment where access to your service is restricted to you or trusted partners, you may find the `Base64`_ backend sufficient to your purposes. You can just install the library as you would any Python library.\n\n**requirements.txt**\n\n.. code-block:: text\n\n  falcon-epdb\n\n**pip**\n\n.. code-block:: bash\n\n  pip install falcon-epdb\n\n**poetry**\n\n.. code-block:: bash\n\n  poetry add falcon-epdb\n\nHowever, if you need a little more security, you can use one of the other authenticated backends (`Fernet`_, `JWT`_). Choose the one that best fits your use case and install it as a Python `extra`_.\n\n**requirements.txt**\n\n.. code-block:: text\n\n  falcon-epdb[fernet]\n\n**pip**\n\n.. code-block:: bash\n\n  pip install falcon-epdb[fernet, jwt]\n\n**poetry**\n\n.. code-block:: bash\n\n  poetry add falcon-epdb[jwt]\n\n.. _extra: https://www.python.org/dev/peps/pep-0508/#extras\n\n\n*****\nUsage\n*****\n\nThis library adds a middleware to your Falcon API stack, and as such will run for all requests, save those excluded by ``exempt_methods`` provided to the ``EPDBServer`` constructor. If it detects a well-formed (and possibly authenticated) ``X-EPDB`` header on the request it will start the `epdb`_ server on the configured port and block until it establishes a connection from an `epdb`_ client, at which point processing continues but under the control of the remote debugging session.\n\nSubsequent requests with an acceptable header will reuse the client connection and automatically drop into the remote debugging session again.\n\nConfiguring the middleware\n==========================\nThe ``EPDBServe<falcon_epdb.EPDBServe>`` middleware accepts a handful of parameters. The most important are the ``backend`` and ``serve_options`` parameters. The ``backend`` determines how a request is examined for the "secret knock" to start the remote debugging server. The included implementations assume a well-formed ``X-EPDB`` header, but nothing precludes you from sub-classing ``EPDBBackend<falcon_epdb.EPDBBackend>`` and implementing your own.\n\nThe ``serve_options`` are options that are passed through to the ``epdb.serve()`` call. See `Backends`_ for details on how to add this middleware to your API.\n\nConstructing the ``X-EPDB`` header\n==================================\n\nThe content of the header is as follows:\n\n.. code-block:: json\n\n  {\n    "epdb": {}\n  }\n\nDepending on the backend in use, one should encode this content into the appropriate header-safe value. Then append this value to the name of the backend.\n\n.. code-block:: text\n\n  X-EPDB: Base64 eyJlcGRiIjoge319\n\nConnecting the client\n=====================\nExample code for connecting to the waiting port:\n\n.. code-block:: python\n\n  import epdb\n\n  edpb.connect(host=<host>, port=9000)\n\n\n.. _epdb: https://pypi.org/project/epdb/\n\nBackends\n========\n\nBase64\n------\n**Server side configuration**\n\n.. code-block:: python\n\n  epdb_middleware = EPDBServe(\n      backend=Base64Backend(),\n      serve_options={\'port\': 9000})\n  api = falcon.API(middleware=[epdb_middleware])\n\n**Crafting an appropriate header**\n\n.. code-block:: python\n\n  import base64\n  import json\n\n  header_content = base64.b64encode(json.dumps({\'epdb\': {}}).encode()).decode()\n  header_value = \'Base64 {}\'.format(header_content)\n\nFernet\n------\n**Server side configuration**\n\n.. code-block:: python\n\n  fernet_key = Fernet.generate_key()  # The shared key\n  epdb_middleware = EPDBServe(\n      backend=FernetBackend(key=fernet_key),\n      serve_options={\'port\': 9000})\n  api = falcon.API(middleware=[epdb_middleware])\n\n**Crafting an appropriate header**\n\n.. code-block:: python\n\n  import json\n  from cryptography.fernet import Fernet\n\n  f = Fernet(<fernet_key>)  # Key configured on the server\n  header_content = f.encrypt(json.dumps({\'epdb\': {}}).encode()).decode()\n  header_value = \'Fernet {}\'.format(header_content)\n\nJWT\n------\n**Server side configuration**\n\n.. code-block:: python\n\n  jwt_key = uuid.uuid4().hex  # The shared key\n  epdb_middleware = EPDBServe(\n      backend=JWTBackend(key=jwt_key),\n      serve_options={\'port\': 9000})\n  api = falcon.API(middleware=[epdb_middleware])\n\n**Crafting an appropriate header**\n\n.. code-block:: python\n\n  import jwt\n\n  header_content = jwt.encode({\'epdb\': {}}, <jwt_key>, algorithm=\'HS256\').decode()\n  header_value = \'JWT {}\'.format(header_content)\n\n\n***************\nTroubleshooting\n***************\nYou must be sure to allow access to the configured port on your host. Be sure to check your security groups and firewall rules.\n\nConfigure your web app to only run one worker process. If you have multiple workers, only the first one will be able to serve on the configured port. If this is not possible you will have to take steps to ensure that all requests that wish to use the remote debugging port are routed to the same worker. This will depend heavily on your HTTP stack and is beyond the scope of this documentation.\n\nBe sure to up your request timeout limit to something on the order of minutes so that the HTTP server doesn\'t close your request connection or kill your worker process while you\'re debugging.\n\nYou may need to provide the ``HTTP-`` prefix on your ``X-EPDB`` header for it to be handled correctly. So instead of sending ``X-EPDB``, you would send ``HTTP-X-EPDB``.\n\n.. |pypi| image:: https://img.shields.io/pypi/v/falcon-epdb.svg\n    :target: https://pypi.org/project/falcon-epdb/\n    :alt: Build version\n\n.. |build| image:: https://travis-ci.org/jcwilson/falcon-epdb.svg?branch=master\n  :target: https://travis-ci.org/jcwilson/falcon-epdb\n  :alt: Build status\n\n.. |coverage| image:: https://coveralls.io/repos/github/jcwilson/falcon-epdb/badge.svg\n  :target: https://coveralls.io/github/jcwilson/falcon-epdb\n  :alt: Coverage status\n\n.. |src| image:: https://img.shields.io/badge/src-github-blue.svg\n  :target: https://github.com/jcwilson/falcon-epdb\n  :alt: Source code\n\n.. |docs| image:: https://readthedocs.org/projects/falcon-epdb/badge/?version=latest\n  :target: https://falcon-epdb.readthedocs.io/en/latest\n  :alt: Documentation status\n\n.. |pyversions| image:: https://img.shields.io/pypi/pyversions/falcon-epdb.svg\n    :target: https://pypi.org/project/falcon-epdb/\n    :alt: Supported Python versions\n\n.. |license| image:: https://img.shields.io/pypi/l/falcon-epdb.svg\n    :target: https://opensource.org/licenses/BSD-3-Clause\n    :alt: Build version\n\n.. |black| image:: https://img.shields.io/badge/code%20format-black-black.svg\n  :target: https://pypi.org/project/black/\n  :alt: Black code formatter\n',
    'author': 'Josh Wilson',
    'author_email': 'josh.wilson@fivestars.com',
    'url': 'https://github.com/jcwilson/falcon-epdb',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'extras_require': extras_require,
    'python_requires': '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
}


setup(**setup_kwargs)
