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

packages = \
['aio_odoorpc']

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

install_requires = \
['aio-odoorpc-base>=2.0.1,<3.0.0']

setup_kwargs = {
    'name': 'aio-odoorpc',
    'version': '1.3.14',
    'description': 'Fast, simple Odoo RPC client with both a synchronous and an asynchronous client',
    'long_description': "# aio-odoorpc: an async Odoo RPC client\n\nThis package builds upon the lower-level [aio-odoorpc-base](https://github.com/mbello/aio-odoorpc-base) \nadding a AsyncOdooRPC/OdooRPC class as a thin layer that makes for a friendlier interface.\n\nAsyncOdooRPC is asynchronous code, OdooRPC is synchronous.\n\nThis package does not intend to implement all the functionality of other odoo rpc modules\nlike ERPpeek and odoorpc. This is meant to be simpler but equally easy to work with without\ntrying to be too smart. One of the motivations of this package was to have an alternative to odoorpc\nwhich started getting in my way. For instance, just instantiating a new object in odoorpc may result\nin a roundtrip to the remote Odoo server. These unnecessary RPC calls quickly add up and it becomes\ntoo difficult to develop fast software. Also, odoorpc offers no asynchronous interface which\nis a huge lost opportunity for code that spends a lot of time waiting on blocking network calls.\n\n## Why use this instead of aio-odoorpc-base\n\nWith this interface you can instantiate an object once and then make simpler invocations to remote\nmethods like `login, read, search, search_read and search_count`. With aio-odoorpc-base, you get only\nthe lower level `execute_kw` call and must pass a long list of parameters on every invocation.\n\nAlso, aio-odoorpc let's you simulate behavior of odoorpc by instantiating the AsyncOdooRPC class with\na `default_model_name` so then all method calls do not need to pass a `model_name`. In this way, you can\neasily replace the usage of odoorpc with this object (I know because I migrated a lot of code away \nfrom odoorpc). Of course, if you are migrating from odoorpc you should take the opportunity to\nmigrate to async code as well.\n\n## Limitations\n\nRight now there are built-in helper functions only for getting info out (read, search, search_read,\nsearch_count), nothing to help creating new records or updating field values. Those are coming soon.\n\n## Things to know about this module:\n- Asyncio is a python3 thing, so no python2 support;\n\n- Type hints are used everywhere;\n\n- This package uses jsonrpc only (no xmlrpc);\n\n- You need to manage the http client yourself. Code is tested with requests (sync),\n  httpx (sync and async) and aiohttp (async). See 'Usage' for examples;\n\n- I am willing to take patches and to add other contributors to this project. Feel free to get in touch,\n  the github page is the best place to interact with the project and the project's author;\n  \n- The synchronous version of the code is generated automatically from the asynchronous code, so at\n  least for now the effort to maintain both is minimal. Both versions are unit tested.\n\n## Things to know about Odoo's API:\n- The `login()` call is really only a lookup of the uid (an int) of the user given a\n  database, username and password. If you are using this RPC client over and over in your code,\n  maybe even calling from a stateless cloud service, you should consider finding out the user id (uid)\n  of the user and pass the uid instead of the username to the constructor of AsyncOdooRPC. This way, \n  you do not need to call the `login()` method after instantiating the class, saving a RPC call;\n\n- The uid mentioned above is not a session-like id. It is really only the database id of the user\n  and it never expires. There is really no 'login' step required to access the Odoo RPC API if you\n  know the uid from the beginning;\n\n- You will need the url of your Odoo's jsonrpc endpoint. Usually, you will just need to add 'jsonrpc' to\n  your odoo url. Example: Odoo web GUI on 'https://acme.odoo.com', JSONRPC will be on 'https://acme.odoo.com/jsonrpc'. \n  However, you may alternatively use one of the three helper methods offered by aio-odoorpc-base.helpers \n  to build the correct url:\n\n```python\ndef build_odoo_base_url(*, host: str, port: Optional[int] = None, ssl: bool = True, base_url: str = '') -> str:\n    ...\n\ndef build_odoo_jsonrpc_endpoint_url(*, host: str, port: Optional[int] = None, ssl: bool = True,\n                                    base_url: str = '', custom_odoo_jsonrpc_suffix: Optional[str] = None) -> str:\n    ...\n\ndef odoo_base_url2jsonrpc_endpoint(odoo_base_url: str = '', custom_odoo_jsonrpc_suffix: Optional[str] = None) -> str:\n    ...\n```\n   To import them use\n```\nfrom aio_odoorpc_base.helpers import build_odoo_base_url, build_odoo_jsonrpc_endpoint_url, odoo_base_url2jsonrpc_endpoint\n```\n   Examples:\n```python\nbuild_odoo_base_url(host='acme.odoo.com', base_url='testing')\n>>>> https://acme.odoo.com/testing\nbuild_odoo_jsonrpc_endpoint_url(host='acme.odoo.com', base_url='testing')\n>>>> https://acme.odoo.com/testing/jsonrpc\nodoo_base_url2jsonrpc_endpoint('https://acme.odoo.com/testing')\n>>>> https://acme.odoo.com/testing/jsonrpc\n```\n\n# Usage\n\n#### Note: check the tests folder for more examples\n\nI will omit the event_loop logic I assume that if you want an async module you already have\nthat sorted out yourself or through a framework like FastAPI.\nAll examples below could also be called using the synchronous OdooRPC object, but without the\n'await' syntax.\n\n```python\nfrom aio_odoorpc import AsyncOdooRPC\nimport httpx\n\n# If the http_client you are using does not support a 'base_url' parameter like\n# httpx does, you will need to pass the 'url_jsonrpc_endpoint' parameter when\n# instantiating the AsyncOdooRPC object.\nasync with httpx.AsyncClient(base_url='https://acme.odoo.com/jsonrpc') as session:\n    odoo = AsyncOdooRPC(database='acme_db', username_or_uid='demo',\n                        password='demo', http_client=session)\n    await odoo.login()\n\n    try:\n        # A default model name has not been set a instantiation time so we should\n        # pass the model_name on every invocation. Here it should throw an exception.\n        await odoo.read()\n    except RuntimeError:\n        pass\n    else:\n        assert False, 'Expected an exception to be raised'\n    \n    # Now with model_name set it should work. Not passing a list of ids\n    # turns the read call into a search_read call with an empty domain (so it matches all)\n    # A missing 'fields' parameter means 'fetch all fields'.\n    # Hence this call is very expensive, it fetches all fields for all\n    # 'sale.order' records\n    all_orders_all_fields = await odoo.read(model_name='sale.order')\n    \n    # creates a copy of odoo obj setting default_model_name to 'sale.order'\n    sale_order = odoo.new_for_model('sale.order')\n    \n    # now we do not need to pass model_name and it works!\n    all_orders_all_fields2 = await sale_order.read()\n\n    large_orders = sale_order.search_read(domain=[['amount_total', '>', 10000]],\n                                          fields=['partner_id', 'amount_total', 'date_order'])\n```\n\n# Object instantiation\n\n**The AsyncOdooRPC/OdooRPC object takes these parameters:**\n- **database**: string, required. The name of the odoo database\n- **username_or_id**: string or int, required. If you pass username (a string), an invocation of the\n  method 'login()' will be required to fetch the uid (an int). The uid is what is really needed, \n  if you know both username and uid pass the uid and avoid a login() call which costs a roundtrip\n  to the Odoo server;\n- **password**: string, required. The user's password. Unfortunately, Odoo's jsonrpc API requires the\n  password to be sent on every call. There is no session or token mechanism available as an alternative\n  authentication method.\n- **http_client**: an http client, optional. If an http client is not set, you will need to pass the\n  http_client parameter on every method invocation (when available). Some http clients (e.g. httpx) \n  let you create a session setting the appropriate url as in\n  `async with httpx.AsyncClient(base_url='https://acme.odoo.com/jsonrpc as session`\n  if you do that on a supporting client, you do not need to pass url, it is already set on the\n  http_client. Otherwise, you will need to pass `url_jsonrpc_endpoint` to the constructor.\n- **url_jsonrpc_endpoint**: string, optional. The url for your Odoo's server jsonrpc endpoint. You should\n  always pass it unless your http_client already knows to which url it should point to.\n  You may use aio-odoorpc-base helper methods `build_odoo_base_url, build_odoo_jsonrpc_endpoint_url,\n  odoo_base_url2jsonrpc_endpoint` that were described earlier in this README to build this url.\n  In short, the jsonrpc endpoint is your odoo instance's base url with a 'jsonrpc' suffix:\n  https://acme.odoo.com/jsonrpc\n- **default_model_name**: str, optional. This parameter sets the default model_name for all method\n  invocations that take an optional method_name parameter. If you set 'model_name' on a method\n  invocation it will override this default and follow your order. When you have an instance of\n  AsyncOdooRPC/OdooRPC you can create a copy with a different default method_name calling the\n  method new_for_model('sale.order.line'). You can use this style to mimic odoorpc's way where\n  you can call search, read, search_read on a specific model. \n```python\nodoo = AsyncOdooRPC(...)\nsale_order = odoo.new_for_model('sale.order')\nsale_order_line = odoo.new_for_model('sale.order.line')\npartner = sale_order.new_for_model('partner')\n```\n  Just remember that new_for_method is nothing special, it only sets a default model name on a\n  copy of an instance. Making copies of copies is perfectly ok. \n\n# Dependencies\n\nThis package depends on [aio-odoorpc-base](https://github.com/mbello/aio-odoorpc-base) which has no dependency itself.",
    'author': 'mbello',
    'author_email': 'mbello@users.noreply.github.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/mbello/aio-odoorpc',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
