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

packages = \
['axualclient']

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

install_requires = \
['confluent-kafka[avro]>=1.7.0,<2.0.0']

setup_kwargs = {
    'name': 'axual-client-python',
    'version': '1.1.0',
    'description': 'Axual client for Python',
    'long_description': "Axual Python Client\n-------------------\n\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Pipeline Status](https://gitlab.com/axual-public/axual-client-python/badges/master/pipeline.svg)](https://gitlab.com/axual-public/axual-client-python/commits/master) \n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=axual-public-axual-client-python&metric=alert_status&token=803308122363db3988c6a86bfedcb42d5b4a6791)](https://sonarcloud.io/dashboard?id=axual-public-axual-client-python)\n[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=axual-public-axual-client-python&metric=sqale_rating&token=803308122363db3988c6a86bfedcb42d5b4a6791)](https://sonarcloud.io/dashboard?id=axual-public-axual-client-python)\n\nPython client library that enables interaction with the Axual platform.\n\n![Python Client Overview](http://www.plantuml.com/plantuml/png/VP0zQyCm48Rdw5TSJI6J6-hP14AxT0jqB1s4T8v5zA7ALca8_Uzrpht4zf39kkTz_HpSW_7APerGAnkoDhupXxRV76Lpb5iXrc8DAaI36eotnYEqc12Q51pqBKAqqlVPsGqqmMfCJyCVeadI8HJx57HMc436M83i838uYvKABWQFleTYzvEb1MNDC5rxuoX-MVOIV9VTHAO8t9TnxofZ6xKebjG_YvdarNGgV6CwmMx_HZLz8RFEkshHIKXuC5sVJjJYGQo-CcQ4eduS3qafFP_lP9KGAre4vKThj4R_MMudKdxDOhQENoWPLV-eWlBMkfpWTbseXuGMBY5lMd3MS4niSc1oBI4z5uhg3m00)\n\n## Prerequisites\n\nPython 3 is required, Python 3.6 or greater is recommended.\n\n## Installation\n\n```bash\npip install axual-client-python\n```\n\n## Testing\nTests are located in the `tests/` directory.\nTo run all of them:\n```bash\npython -m unittest discover tests\n```\n\n## Usage\n### Producer\n\n```python\nimport json\nfrom axualclient.producer import Producer\n\nconf = {\n    # Axual configuration\n    'application_id': application_id,\n    'endpoint': endpoint,\n    'tenant': tenant,\n    'environment': environment,\n    # SSL configuration\n    'ssl.certificate.location': producer_app_cert,\n    'ssl.key.location': producer_app_key,\n    'ssl.ca.location': root_cert,\n}\nproducer = Producer(conf)\nproducer.produce(value=json.dumps(dict(a=1, b='banana')))\nproducer.flush()  # Flushes producer before ending (triggering callbacks for delivery reports)\n```\nSee [SSL Configuration](#ssl-configuration) for more info on the certificates required.\n\n### Consumer\n\n```python\nfrom axualclient.consumer import Consumer\n\nconf = {\n    # Axual configuration\n    'application_id': application_id,\n    'endpoint': endpoint,\n    'tenant': tenant,\n    'environment': environment,\n    # SSL configuration\n    'ssl.certificate.location': producer_app_cert,\n    'ssl.key.location': producer_app_key,\n    'ssl.ca.location': root_cert,\n    # Consumer configuration\n    'auto.offset.reset': 'earliest',\n    'on_commit': on_commit_callback,\n}\nconsumer = Consumer(conf)\n\ntry:\n    # Subscribe to topic(s) as they appear on Self Service\n    consumer.subscribe(['your-topic'])\n    while True:\n        msg = consumer.poll(1.0)\n\n        # msg is None if no new message\n        if msg is None:\n            continue\n\n        if msg.error():\n            # Error handling\n            raise KafkaException(msg.error())\n        else:\n            # Do some processing on the message\n            print(\n                f'Received message on topic {msg.topic()} partition {msg.partition()} '\n                f'offset {msg.offset()} key {msg.key()} value {msg.value()}'\n            )\n            # Commit message offset to the topic\n            consumer.commit()\nfinally:\n    if consumer is not None:\n        # Cleanly unregister from cluster by closing consumer\n        consumer.commit()\n        consumer.close()\n```\n\n### Producer (AVRO)\nProducing AVRO messages works if you have the AVRO schema available that was uploaded to self-service. \nThose schemas need to be provided to the serializer via the `schema_str` as Avro [Schema Declaration](https://avro.apache.org/docs/current/spec.html#schemas>).\n```python\nfrom axualclient.avro import AvroSerializer\nfrom axualclient.serializing_producer import SerializingProducer\n\nkey_serializer = AvroSerializer(schema_str=Application.SCHEMA, to_dict=application_to_dict)\nvalue_serializer = AvroSerializer(schema_str=ApplicationLogEvent.SCHEMA, to_dict=application_log_event_to_dict)\n\nconf = {\n    # Axual configuration\n    'application_id': application_id,\n    'endpoint': endpoint,\n    'tenant': tenant,\n    'environment': environment,\n    # SSL configuration\n    'ssl.certificate.location': producer_app_cert,\n    'ssl.key.location': producer_app_key,\n    'ssl.ca.location': root_cert,\n    # Producer configuration\n    'key.serializer': key_serializer,\n    'value.serializer': value_serializer,\n    'acks': 'all',\n}\nproducer = SerializingProducer(conf)\n\nproducer.produce(topic=topic, value=value, key=key)\nproducer.flush() # Flushes producer before ending (triggering callbacks for delivery reports)\n```\n\n### Consumer (AVRO)\nConsumer `AvroDeserializers` need to be instantiated and passed as configuration to the Axual `DeserializingConsumer` like so:\n```python\nfrom axualclient.avro import AvroDeserializer\nfrom axualclient.deserializing_consumer import DeserializingConsumer\n\n# Initialize Deserializers:\nkey_deserializer = AvroDeserializer(\n    # Optional parameters\n    schema_str=Application.SCHEMA,\n    from_dict=dict_to_application\n)\nvalue_deserializer = AvroDeserializer(\n    # Optional parameters\n    schema_str=ApplicationLogEvent.SCHEMA,\n    from_dict=dict_to_application_log_event,\n)\n\nconfiguration = {\n    # Axual configuration\n    'application_id': application_id,\n    'endpoint': endpoint,\n    'tenant': tenant,\n    'environment': environment,\n    # SSL configuration\n    'ssl.certificate.location': producer_app_cert,\n    'ssl.key.location': producer_app_key,\n    'ssl.ca.location': root_cert,\n    # Consumer configuration\n    'key.deserializer': key_deserializer,\n    'value.deserializer': value_deserializer,\n    'auto.offset.reset': 'earliest',\n    'on_commit': on_commit_callback,\n    'error_cb': on_error_callback,\n    'logger': logger\n}\n\nconsumer = DeserializingConsumer(configuration)\n\ntry:\n    consumer.subscribe([topic])\n    while True:\n        msg = consumer.poll()\n\n        if msg is None:\n            continue\n\n        if msg.error():\n            print(f'Error returned by poll: {msg.error()}')\n        else:\n            print(\n                f'Received message on topic {msg.topic()} partition {msg.partition()} '\n                f'offset {msg.offset()} key: {str(msg.key())} value: {str(msg.value())}'\n            )\n            consumer.commit()\nexcept KeyboardInterrupt:\n    print('Caught KeyboardInterrupt, stopping.')\nfinally:\n    if consumer is not None:\n        print('Committing final offsets and leaving group.')\n        consumer.commit()\n        consumer.close()\n```\n\n\n## SSL Configuration\nThe client configuration requires a correct SSL configuration in order to communicate securely with brokers, the discovery API, and the schema registry.  \nEach application (as defined in self-service) requires an application certificate (`ssl.certificate.location`) and corresponding private key (`ssl.key.location`). \nThe application certificate must match the one uploaded in self-service for that application.  \nThe file with root certificates needs to be created properly: the brokers might be using a root certificate authority different \nfrom the authority that signed the certificates for the discovery API and schema registry.\nThe base64-encoded unencrypted versions of these certificates can be pasted into one file (`ssl.ca.location`).\nThis file would then look like the following example:\n```\n-----BEGIN CERTIFICATE-----\nMIIQdaGDAksKadksSDKNsdka5sjy8elAMsm3d .....\n ...  more base64-encoded content here ...\n..... LKlmsf02mz2EWYnds=\n-----END CERTIFICATE-----\n\n-----BEGIN CERTIFICATE-----\nMIIPmsd92nNWlasHWdwMOe92nwoa2QNinnNaZ .....\n ...  more base64-encoded content here ...\n..... ldFAf02SArubBW7wVFW2i1=\n-----END CERTIFICATE-----\n```\n\n## Examples\n\nSimple use cases using the client code can be found in the \n[Axual Python Client Examples](https://gitlab.com/axual-public/axual-client-python-examples).\n\n\n## Known Limitations\n\n- We have encountered issues when using `root_ca`s consisting of more than 1 intermediate certificates.\nThe issue originates with the underlying SSL C library implementation and results in the following exception \nwhen authenticating:\n\n```\n[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: path length constraint exceeded (_ssl.c:1123)\n```\n- Transaction support is not there. An [issue](https://gitlab.com/axual-public/axual-client-python/-/issues/17) is already created and transactions will be supported in future releases.\n- PEM as string format is not supported. An [issue](https://gitlab.com/axual-public/axual-client-python/-/issues/19) is already created and will be added in future releases.\n\n## Contributing\n\nAxual is interested in building the community; we would welcome any thoughts or \n[patches](https://gitlab.com/axual-public/axual-client-python/-/issues).\nYou can reach us [here](https://axual.com/contact/).\n\nSee [contributing](https://gitlab.com/axual-public/axual-client-python/blob/master/CONTRIBUTING.md).\n\n### Building locally\nThis project uses [poetry](https://python-poetry.org/docs/) for dependency management and building.\nInstall the tool as per the instructions on the linked page, and build the library using:\n\n    poetry build\n\n#### For maintainers: building a release\nThe version of the library being built will be the version specified in `pyproject.toml` whenever you \npush to a branch. \n<br>\nWhen tagging and building a release however, please be aware that the CI pipeline will ignore the version in `pyproject.toml` and \nbuild a release based on what is specified in the tag; \nfor example tagging `1.0.0-alpha4` will produce `axual_client_python-1.0.0a4-py3-none-any.whl`.\n<p>\nThis has two consequences:\n\n- You have to follow the normal [semver](https://semver.org/) rules when choosing a tag\n- After releasing, it falls on the developer to manually update the version in `pyproject.toml` in preparation for the next version.\n\n\n## License\n\nAxual Python Client is licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt).",
    'author': 'Axual',
    'author_email': 'opensource@axual.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': None,
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.6,<4.0',
}


setup(**setup_kwargs)
