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

packages = \
['flask_shortcut']

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

install_requires = \
['click>=7.1,<8.0',
 'flask>=1.1,<2.0',
 'importlib-metadata>=1.6,<2.0',
 'xmltodict>=0.12,<0.13']

setup_kwargs = {
    'name': 'flask-shortcut',
    'version': '0.4.1',
    'description': 'Extension that provides an easy way to add dev-only shortcuts to your routes.',
    'long_description': '|Logo|\n\n|CI_CD| |Docs| |pyPI| |py_versions| |License| |Style|\n\n\n.. header-end\n\n\nProject Description\n-------------------\n\nThis extension provides an easy and safe way to add dev-only shortcuts to\nroutes in your flask application.\n\nThe main beneficiaries are microservices that need to be tested regularly in\nconjunction with their clients. If you need to assert working communication and\nbasic integration in a sufficiently complex ecosystem, clients that can not\nfreely chose how their requests are formed gain a lot from being able to\nreceive predictable responses. By skipping over the details of how the\nmicroservice is implemented, which bugs and minor changes it experiences over\ntime, testing basic API compatibility gets a lot more manageable.\n\nIn a test-engineering context, it would be considered a "fake".\n\nWhat is a Shortcut?\n-------------------\n\nIn the context of this package, a shortcut is a condition-and-response pair.\nThe response is `anything that a view function can return`_, and the\ncondition depends on one of the three possible mapping contexts.\n\nIn the first context, only the response is passed as the shortcut, and the\ncondition is assumed to always be true, effectively replacing the route to\nalways just return the given response. Showcased with the view ``foo``\nin the usage section.\n\nIn the second context, a dictionary that maps strings to responses is passed\nas the shortcut. The strings need to be deserializeable as json, and the\nfirst one that can be fully matched as a substructure into the request body\nwill see its condition as fulfilled, returning its associated response.\nIf none of them are valid sub-matches, the original view function will run.\nShowcased with the view ``bar`` in the usage section.\n\nIn the third context, either a single function or a list of functions is\npassed as the shortcut. The functions can run any code whatsoever and will\nbe executed one after the other as long as they return ``None``, which means\nthat their condition is not fulfilled. As soon as one of them returns\nsomething different, it is passed on as the response. If all of them return\n``None``, the original view function is executed. Showcased with the view\n``baz`` in the usage section.\n\n\nUsage\n-----\n\nYou can add shortcuts to your view functions either individually with\ndecorators, or in a single swoop once all routes have been defined. Both ways\nare functionally equivalent.\n\nApplying Shortcuts\n==================\n\n**With decorators:**\n\n.. code-block:: python\n\n    from flask import Flask\n    from flask_shortcut import Shortcut\n\n    app = Flask(__name__)\n    short = Shortcut(app)\n\n    @app.route(\'/foo\', methods=[\'GET\'])\n    @short.cut((\'short_foo\', 200))\n    def foo():\n        return \'foo\'\n\n    @app.route(\'/bar\', methods=[\'POST\'])\n    @short.cut({\n        \'{"name": "TestUser"}\': (\'short_bar\', 200),\n        \'{"name": "UserTest"}\': (\'longer_bar\', 200),\n    })\n    def bar():\n        return \'bar\'\n\n    @app.route(\'/baz\', methods=[\'POST\'])\n    @short.cut(lambda: ("json_baz", 200) if "json" in request.mimetype else None)\n    def baz():\n        return \'baz\'\n\n\n**With a wire call**\n\n.. code-block:: python\n\n    from flask import Flask\n    from flask_shortcut import Shortcut\n\n    app = Flask(__name__)\n\n    @app.route(\'/foo\', methods=[\'GET\'])\n    def foo():\n        return \'foo\'\n\n    @app.route(\'/bar\', methods=[\'POST\'])\n    def bar():\n        return \'bar\'\n\n    @app.route(\'/baz\', methods=[\'POST\'])\n    def baz():\n        return \'baz\'\n\n    Shortcut(app).wire(\n        {\n             \'/foo\': (\'short_foo\', 200),\n             \'/bar\': {\n                 \'{"name": "TestUser"}\': (\'short_bar\', 200),\n                 \'{"name": "UserTest"}\': (\'longer_bar\', 200),\n             }\n             \'/baz\': lambda: ("json_baz", 200) if "json" in request.mimetype else None\n        }\n    )\n\n\nWhat it looks like\n==================\n\nTo showcase how the shortcuts are supposed to work, here is the result\nof a couple of requests sent against the server from the example above\nif it were run with ``FLASK_ENV=test flask run``:\n\n.. code-block:: python\n\n  >>> from request import get, post\n  >>> get(\'http://127.0.0.1:5000/foo\').text\n  \'short_foo\'  # the only response this route will give\n  >>> post(\'http://127.0.0.1:5000/bar\', json={"name": "me"}).text\n  \'bar\'  # no shortcut match -> the original logic was executed\n  >>> post(\'http://127.0.0.1:5000/bar\', json={"name": "TestUser"}).text\n  \'short_bar\'  # shortcut match\n  >>> post(\'http://127.0.0.1:5000/bar\', json={"name": "UserTest", "job": None}).text\n  \'longer_bar\'  # shortcut only needs to be contained for a match\n  >>> post(\'http://127.0.0.1:5000/baz\').text\n  \'baz\'  # no shortcut match -> the function returned None\n  >>> post(\'http://127.0.0.1:5000/baz\', json={"name": "me"}).text\n  \'json_baz\'  # shortcut matched -> the function returned a valid response\n\nOne focus of this package is that a production deployment would remain\nas ignorant as possible about the existence of shortcuts. While the\nshortcut object is still created, it only delegates the view functions\nand no shortcut code has any chance of being executed, or showing up in\nstack traces.\n\n\nConfiguration\n-------------\n\nShortcuts will only be applied when ``FLASK_ENV`` is set to something\ndifferent from its default setting, ``production``. You can extend that list\nthrough the ``SHORTCUT_EXCLUSIONS`` config setting, either by adding it to\nyour app\'s config before creating any Shortcut objects, or preferably by\nsetting up the whole config `with a file`_.\n\nPossible values for it are all environments that you want to block other\nthan ``production`` separated by commas. For example ``staging,master`` will\nblock the envs ``production``, ``staging``, and ``master`` from receiving\nshortcuts.\n\n\n.. |Logo| image:: https://user-images.githubusercontent.com/2063412/79631833-c1b39400-815b-11ea-90da-d9264420ef68.png\n   :alt: Logo\n   :width: 1200\n   :target: https://github.com/a-recknagel/Flask-Shortcut\n\n.. |CI_CD| image:: https://github.com/a-recknagel/Flask-Shortcut/workflows/CI-CD/badge.svg\n   :alt: Main workflow status\n   :target: https://github.com/a-recknagel/Flask-Shortcut/actions\n\n.. |pyPI| image:: https://img.shields.io/pypi/v/flask-shortcut\n   :alt: Current pyPI version\n   :target: https://pypi.org/project/flask-shortcut/\n\n.. |Docs| image:: https://img.shields.io/badge/docs-github--pages-blue\n   :alt: Documentation home\n   :target: https://a-recknagel.github.io/Flask-Shortcut/\n\n.. |License| image:: https://img.shields.io/pypi/l/flask-shortcut\n   :alt: Package license\n   :target: https://pypi.org/project/flask-shortcut/\n\n.. |py_versions| image:: https://img.shields.io/pypi/pyversions/flask-shortcut\n   :alt: Supported on python versions\n   :target: https://pypi.org/project/flask-shortcut/\n\n.. |Style| image:: https://img.shields.io/badge/codestyle-black-black\n   :alt: Any color you want\n   :target: https://black.readthedocs.io/en/stable/\n\n.. _with a file: https://flask.palletsprojects.com/en/1.1.x/config/#configuring-from-files\n\n.. _anything that a view function can return: https://flask.palletsprojects.com/en/1.1.x/quickstart/#about-responses',
    'author': 'Arne',
    'author_email': 'arecknag@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/a-recknagel/Flask-Shortcut',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.6,<4.0',
}


setup(**setup_kwargs)
