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

packages = \
['fastapi_jsonrpc']

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

install_requires = \
['aiojobs>0.2.2', 'fastapi>0.55']

setup_kwargs = {
    'name': 'fastapi-jsonrpc',
    'version': '2.1.3',
    'description': 'JSON-RPC server based on fastapi',
    'long_description': '|tests|\n\n.. |tests| image:: https://github.com/smagafurov/fastapi-jsonrpc/actions/workflows/tests.yml/badge.svg\n   :target: https://github.com/smagafurov/fastapi-jsonrpc/actions/workflows/tests.yml\n\n\nDescription\n===========\n\nJSON-RPC server based on fastapi:\n\n    https://fastapi.tiangolo.com\n\nMotivation\n^^^^^^^^^^\n\nAutogenerated **OpenAPI** and **Swagger** (thanks to fastapi) for JSON-RPC!!!\n\nInstallation\n============\n\n.. code-block:: bash\n\n    pip install fastapi-jsonrpc\n\nDocumentation\n=============\n\nRead FastAPI documentation and see usage examples bellow\n\nSimple usage example\n====================\n\n.. code-block:: bash\n\n    pip install uvicorn\n\nexample1.py\n\n.. code-block:: python\n\n    import fastapi_jsonrpc as jsonrpc\n    from pydantic import BaseModel\n    from fastapi import Body\n\n\n    app = jsonrpc.API()\n\n    api_v1 = jsonrpc.Entrypoint(\'/api/v1/jsonrpc\')\n\n\n    class MyError(jsonrpc.BaseError):\n        CODE = 5000\n        MESSAGE = \'My error\'\n\n        class DataModel(BaseModel):\n            details: str\n\n\n    @api_v1.method(errors=[MyError])\n    def echo(\n        data: str = Body(..., example=\'123\'),\n    ) -> str:\n        if data == \'error\':\n            raise MyError(data={\'details\': \'error\'})\n        else:\n            return data\n\n\n    app.bind_entrypoint(api_v1)\n\n\n    if __name__ == \'__main__\':\n        import uvicorn\n        uvicorn.run(\'example1:app\', port=5000, debug=True, access_log=False)\n\nGo to:\n\n    http://127.0.0.1:5000/docs\n\nFastAPI dependencies usage example\n==================================\n\n.. code-block:: bash\n\n    pip install uvicorn\n\nexample2.py\n\n.. code-block:: python\n\n    import logging\n    from contextlib import asynccontextmanager\n\n    from pydantic import BaseModel, Field\n    import fastapi_jsonrpc as jsonrpc\n    from fastapi import Body, Header, Depends\n\n\n    logger = logging.getLogger(__name__)\n\n\n    # database models\n\n    class User:\n        def __init__(self, name):\n            self.name = name\n\n        def __eq__(self, other):\n            if not isinstance(other, User):\n                return False\n            return self.name == other.name\n\n\n    class Account:\n        def __init__(self, account_id, owner, amount, currency):\n            self.account_id = account_id\n            self.owner = owner\n            self.amount = amount\n            self.currency = currency\n\n        def owned_by(self, user: User):\n            return self.owner == user\n\n\n    # fake database\n\n    users = {\n        \'1\': User(\'user1\'),\n        \'2\': User(\'user2\'),\n    }\n\n    accounts = {\n        \'1.1\': Account(\'1.1\', users[\'1\'], 100, \'USD\'),\n        \'1.2\': Account(\'1.2\', users[\'1\'], 200, \'EUR\'),\n        \'2.1\': Account(\'2.1\', users[\'2\'], 300, \'USD\'),\n    }\n\n\n    def get_user_by_token(auth_token) -> User:\n        return users[auth_token]\n\n\n    def get_account_by_id(account_id) -> Account:\n        return accounts[account_id]\n\n\n    # schemas\n\n    class Balance(BaseModel):\n        """Account balance"""\n        amount: int = Field(..., example=100)\n        currency: str = Field(..., example=\'USD\')\n\n\n    # errors\n\n    class AuthError(jsonrpc.BaseError):\n        CODE = 7000\n        MESSAGE = \'Auth error\'\n\n\n    class AccountNotFound(jsonrpc.BaseError):\n        CODE = 6000\n        MESSAGE = \'Account not found\'\n\n\n    class NotEnoughMoney(jsonrpc.BaseError):\n        CODE = 6001\n        MESSAGE = \'Not enough money\'\n\n        class DataModel(BaseModel):\n            balance: Balance\n\n\n    # dependencies\n\n    def get_auth_user(\n        # this will become the header-parameter of json-rpc method that uses this dependency\n        auth_token: str = Header(\n            None,\n            alias=\'user-auth-token\',\n        ),\n    ) -> User:\n        if not auth_token:\n            raise AuthError\n\n        try:\n            return get_user_by_token(auth_token)\n        except KeyError:\n            raise AuthError\n\n\n    def get_account(\n        # this will become the parameter of the json-rpc method that uses this dependency\n        account_id: str = Body(..., example=\'1.1\'),\n        user: User = Depends(get_auth_user),\n    ) -> Account:\n        try:\n            account = get_account_by_id(account_id)\n        except KeyError:\n            raise AccountNotFound\n\n        if not account.owned_by(user):\n            raise AccountNotFound\n\n        return account\n\n\n    # JSON-RPC middlewares\n\n    @asynccontextmanager\n    async def logging_middleware(ctx: jsonrpc.JsonRpcContext):\n        logger.info(\'Request: %r\', ctx.raw_request)\n        try:\n            yield\n        finally:\n            logger.info(\'Response: %r\', ctx.raw_response)\n\n\n    # JSON-RPC entrypoint\n\n    common_errors = [AccountNotFound, AuthError]\n    common_errors.extend(jsonrpc.Entrypoint.default_errors)\n\n    api_v1 = jsonrpc.Entrypoint(\n        # Swagger shows for entrypoint common parameters gathered by dependencies and common_dependencies:\n        #    - json-rpc-parameter \'account_id\'\n        #    - header parameter \'user-auth-token\'\n        \'/api/v1/jsonrpc\',\n        errors=common_errors,\n        middlewares=[logging_middleware],\n        # this dependencies called once for whole json-rpc batch request\n        dependencies=[Depends(get_auth_user)],\n        # this dependencies called separately for every json-rpc request in batch request\n        common_dependencies=[Depends(get_account)],\n    )\n\n\n    # JSON-RPC methods of this entrypoint\n\n    # this json-rpc method has one json-rpc-parameter \'account_id\' and one header parameter \'user-auth-token\'\n    @api_v1.method()\n    def get_balance(\n        account: Account = Depends(get_account),\n    ) -> Balance:\n        return Balance(\n            amount=account.amount,\n            currency=account.currency,\n        )\n\n\n    # this json-rpc method has two json-rpc-parameters \'account_id\', \'amount\' and one header parameter \'user-auth-token\'\n    @api_v1.method(errors=[NotEnoughMoney])\n    def withdraw(\n        account: Account = Depends(get_account),\n        amount: int = Body(..., gt=0, example=10),\n    ) -> Balance:\n        if account.amount - amount < 0:\n            raise NotEnoughMoney(data={\'balance\': get_balance(account)})\n        account.amount -= amount\n        return get_balance(account)\n\n\n    # JSON-RPC API\n\n    app = jsonrpc.API()\n    app.bind_entrypoint(api_v1)\n\n\n    if __name__ == \'__main__\':\n        import uvicorn\n        uvicorn.run(\'example2:app\', port=5000, debug=True, access_log=False)\n\nGo to:\n\n    http://127.0.0.1:5000/docs\n\n.. image:: ./images/fastapi-jsonrpc.png\n\nDevelopment\n===========\n\n* Install poetry\n\n    https://github.com/sdispater/poetry#installation\n\n* Install dependencies\n\n    .. code-block:: bash\n\n        poetry update\n\n* Regenerate README.rst\n\n    .. code-block:: bash\n\n        rst_include include -q README.src.rst README.rst\n\n* Change dependencies\n\n    Edit ``pyproject.toml``\n\n    .. code-block:: bash\n\n        poetry update\n        dephell deps convert\n\n* Bump version\n\n    .. code-block:: bash\n\n        poetry version patch\n        dephell deps convert\n\n* Publish to pypi\n\n    .. code-block:: bash\n\n        poetry publish --build\n\n',
    'author': 'Sergey Magafurov',
    'author_email': 'magafurov@tochka.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/smagafurov/fastapi-jsonrpc',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.6.2,<4.0.0',
}


setup(**setup_kwargs)
