{ "info": { "author": "Dave Shawley", "author_email": "daveshawley@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Libraries" ], "description": "klempner\n========\nConstructs URLs that targeting other services.\n\n|Version| |Python| |Source| |Coverage| |Quality| |Docs| |CI|\n\nThis library makes building URLs for inter-service communication safer\nand easier to build.\n\nURL building\n------------\n\n.. code-block:: python\n\n url = klempner.url.build_url('account', 'path', 'with spaces',\n query='arg', multi=['arg', 'support'])\n print(url)\n # http://account/path/with%20spaces?query=arg&multi=arg&multi=support\n\n``build_url`` takes care of formatting the path and query parameters correctly\nin addition to discovering the service name. In this example, the service name\nis used as-is (see *Unconfigured usage* below). The real power in ``build_url``\nis its ability to discover the scheme, host name, and port number based on the\noperating environment.\n\n``build_url`` uses the ``http`` scheme by default. If the port is determined\nby the discovery mechanism, then the scheme is set using a simple global\nmapping from port number to scheme.\n\nDiscovery examples\n------------------\n\nUnconfigured usage\n~~~~~~~~~~~~~~~~~~\n\n.. code-block:: python\n\n url = klempner.url.build_url('account')\n print(url) # http://account/\n\nThis isn't very useful but if you do not configure the discovery mechanism,\nthen ``build_url`` assumes that the requested service is accessible directly\nby name.\n\nConsul service discovery\n~~~~~~~~~~~~~~~~~~~~~~~~\nThe basic form of using consul is not *discovery* at all. It is simply\nURL construction that follows the naming convention that Consul's DNS\ninterface exposes.\n\n.. code-block:: python\n\n os.environ['KLEMPNER_DISCOVERY'] = 'consul'\n os.environ['CONSUL_DATACENTER'] = 'production'\n url = klempner.url.build_url('account')\n print(url) # http://account.service.production.consul/\n\nIf you append ``+agent`` to the discovery method, then ``build_url`` will\nconnect to a Consul agent and retrieve the port number for services. If the\nport has a registered service associated with it, then the service name will\nbe used as the scheme.\n\nAssuming that the *account* service is registered in consul with a service port\nof 8000:\n\n.. code-block:: python\n\n os.environ['KLEMPNER_DISCOVERY'] = 'consul+agent'\n url = klempner.url.build_url('account')\n print(url) # http://account.service.production.consul:8000/\n\nNow let's look at what happens for a RabbitMQ connection:\n\n.. code-block:: python\n\n url = klempner.url.build_url('rabbit')\n print(url) # amqp://rabbit.service.production.consul:5432/\n\nThe scheme is derived by looking up the port in the\n``klempner.config.URL_SCHEME_MAP`` and using the result if the lookup\nsucceeds.\n\nThe library will connect to the agent specified by the ``CONSUL_HTTP_ADDR``\nenvironment variable. If the environment variable is not specified, then the\nagent listening on the localhost will be used.\n\nKubernetes service discovery\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code-block:: python\n\n os.environ['KLEMPNER_DISCOVERY'] = 'kubernetes'\n url = klempner.url.build_url('account')\n print(url) # http://account.default.svc.cluster.local/\n\n.. code-block:: python\n\n os.environ['KLEMPNER_DISCOVERY'] = 'kubernetes'\n os.environ['KUBERNETES_NAMESPACE'] = 'my-team'\n url = klempner.url.build_url('account')\n print(url) # http://account.my-team.svc.cluster.local/\n\nDocker-compose service discovery\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code-block:: python\n\n os.environ['KLEMPNER_DISCOVERY'] = 'docker-compose'\n os.environ['COMPOSE_PROJECT_NAME'] = 'foo'\n url = klempner.url.build_url('account')\n print(url) # http://127.0.0.1:32867/\n\nThis discovery mechanism discovers IP and port numbers for services using\nthe Docker API. ``build_url`` retrieves the list of services from the docker\nhost, filters the list using the \"com.docker.compose.project\" label, and\nselects the service using the \"com.docker.compose.service\" label.\n\nEnvironment variable discovery\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nThis form of discovery uses environment variables with the service name encoded\ninto them:\n\n.. code-block:: python\n\n os.environ['KLEMPNER_DISCOVERY'] = 'environment'\n os.environ['ACCOUNT_HOST'] = '10.2.12.23'\n os.environ['ACCOUNT_PORT'] = '11223'\n url = klempner.url.build_url('account')\n print(url) # http://10.2.12.23:11223/\n\nFor a service named ``adder``, the following environment variables are used\nif they are set.\n\n+------------------+-------------------------------+-------------+\n| Name | URL component | Default |\n+------------------+-------------------------------+-------------+\n| ``ADDER_HOST`` | host portion of the authority | *none* |\n+------------------+-------------------------------+-------------+\n| ``ADDER_PORT`` | port portion of the authority | *omitted* |\n+------------------+-------------------------------+-------------+\n| ``ADDER_SCHEME`` | scheme | *see below* |\n+------------------+-------------------------------+-------------+\n\nThe URL scheme defaults to looking up the port number in the\n``klempner.config.URL_SCHEME_MAP`` dictionary. If the port number is not\nin the dictionary, then ``http`` is used as a default.\n\n.. code-block:: python\n\n os.environ['KLEMPNER_DISCOVERY'] = 'environment'\n os.environ['ACCOUNT_HOST'] = '10.2.12.23'\n os.environ['ACCOUNT_PORT'] = '443'\n url = klempner.url.build_url('account')\n print(url) # https://10.2.12.23:443/\n\nWant to contribute?\n-------------------\n*Thank you.* See `docs/contributing.rst`_ or\nhttps://klempner.readthedocs.io/en/latest/contributing.html for what you need\nto do.\n\n.. _docs/contributing.rst: https://github.com/dave-shawley/klempner/blob\n /master/docs/contributing.rst\n\n.. |CI| image:: https://img.shields.io/circleci/project/github/dave-shawley/klempner/master.svg\n :target: https://circleci.com/gh/dave-shawley/klempner\n.. |Coverage| image:: https://img.shields.io/coveralls/github/dave-shawley/klempner.svg\n :target: https://coveralls.io/github/dave-shawley/klempner\n.. |Docs| image:: https://img.shields.io/readthedocs/klempner.svg\n :target: https://klempner.readthedocs.io/\n.. |Python| image:: https://img.shields.io/pypi/pyversions/klempner.svg\n :target: https://pypi.org/project/klempner\n.. |Quality| image:: https://sonarcloud.io/api/project_badges/measure?project=dave-shawley_klempner&metric=alert_status\n :target: https://sonarcloud.io/dashboard?id=dave-shawley_klempner\n.. |Source| image:: https://img.shields.io/github/stars/dave-shawley/klempner.svg?logo=github\n :target: https://github.com/dave-shawley/klempner\n.. |Version| image:: https://img.shields.io/pypi/v/klempner.svg\n :target: https://pypi.org/project/klempner", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://klempner.readthedocs.io/", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "klempner", "package_url": "https://pypi.org/project/klempner/", "platform": "", "project_url": "https://pypi.org/project/klempner/", "project_urls": { "Builds": "https://circleci.com/gh/dave-shawley/klempner", "Documentation": "https://klempner.readthedocs.io/", "Download": "https://pypi.org/project/klempner/", "Homepage": "https://klempner.readthedocs.io/", "Quality Reports": "https://sonarcloud.io/dashboard?id=dave-shawley_klempner", "Source Code": "https://github.com/dave-shawley/klempner" }, "release_url": "https://pypi.org/project/klempner/0.0.3/", "requires_dist": null, "requires_python": "", "summary": "Construct service request URLs", "version": "0.0.3" }, "last_serial": 5316448, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "0f689d4715235dd26aa7ce33f6835fec", "sha256": "93d477c4757e40ded61ef14b3164789e00c1bd0460c606db987125771a59e614" }, "downloads": -1, "filename": "klempner-0.0.1.tar.gz", "has_sig": false, "md5_digest": "0f689d4715235dd26aa7ce33f6835fec", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8675, "upload_time": "2019-05-05T13:50:29", "url": "https://files.pythonhosted.org/packages/dd/11/665c3dc6a143525decdd2e48f3812bb2b07f02efca762d6641174cf9407d/klempner-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "4babece3bc419cb43deba06b737d77c4", "sha256": "788a074ec43bad83743b82cb360ceca99e0a00710157538ead140313fa0b011b" }, "downloads": -1, "filename": "klempner-0.0.2.tar.gz", "has_sig": false, "md5_digest": "4babece3bc419cb43deba06b737d77c4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11821, "upload_time": "2019-05-19T12:05:48", "url": "https://files.pythonhosted.org/packages/26/e8/81daa9356a6dfc3cbc1e533a03af338d3bb7bd47a2f03ba3573ef495aa73/klempner-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "4d84dce55d2bc0634717bedb210d4063", "sha256": "452d54c2db2d5633647295631f989f21e7bcf0618a0e64a650d1651dc6446858" }, "downloads": -1, "filename": "klempner-0.0.3.tar.gz", "has_sig": false, "md5_digest": "4d84dce55d2bc0634717bedb210d4063", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13663, "upload_time": "2019-05-25T13:25:59", "url": "https://files.pythonhosted.org/packages/f1/69/347175582a7b7237f3786b25c496c990571a24e38e086806a9e783f0706d/klempner-0.0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4d84dce55d2bc0634717bedb210d4063", "sha256": "452d54c2db2d5633647295631f989f21e7bcf0618a0e64a650d1651dc6446858" }, "downloads": -1, "filename": "klempner-0.0.3.tar.gz", "has_sig": false, "md5_digest": "4d84dce55d2bc0634717bedb210d4063", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13663, "upload_time": "2019-05-25T13:25:59", "url": "https://files.pythonhosted.org/packages/f1/69/347175582a7b7237f3786b25c496c990571a24e38e086806a9e783f0706d/klempner-0.0.3.tar.gz" } ] }