{"id":40645013,"url":"https://github.com/keijack/python-eureka-client","last_synced_at":"2026-01-21T08:16:12.096Z","repository":{"id":45302754,"uuid":"150200809","full_name":"keijack/python-eureka-client","owner":"keijack","description":"A eureka client written in python. Support registering your python component to Eureka Server, as well as calling remote services by pulling the the Eureka registry. ","archived":false,"fork":false,"pushed_at":"2025-10-23T03:22:11.000Z","size":207,"stargazers_count":194,"open_issues_count":11,"forks_count":49,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-11-23T12:14:24.158Z","etag":null,"topics":["eureka","microservice","python","spring-cloud","spring-cloud-eureka"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/keijack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-09-25T03:11:54.000Z","updated_at":"2025-11-21T08:49:15.000Z","dependencies_parsed_at":"2024-01-16T11:31:14.962Z","dependency_job_id":"5547bc44-d3f0-4582-b651-f2a367643940","html_url":"https://github.com/keijack/python-eureka-client","commit_stats":{"total_commits":161,"total_committers":7,"mean_commits":23.0,"dds":"0.17391304347826086","last_synced_commit":"dd89189e4973966630c6bf12200e8dd774c1dfea"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/keijack/python-eureka-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keijack%2Fpython-eureka-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keijack%2Fpython-eureka-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keijack%2Fpython-eureka-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keijack%2Fpython-eureka-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keijack","download_url":"https://codeload.github.com/keijack/python-eureka-client/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keijack%2Fpython-eureka-client/sbom","scorecard":{"id":553789,"data":{"date":"2025-08-11","repo":{"name":"github.com/keijack/python-eureka-client","commit":"b1ce2dbc909a80c65d5968659ee8a99bf3585ceb"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.9,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 1/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'","Warn: branch protection not enabled for branch '0.8.x'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-3rq5-2g8h-59hc"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T11:45:37.865Z","repository_id":45302754,"created_at":"2025-08-20T11:45:37.865Z","updated_at":"2025-08-20T11:45:37.865Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28630000,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T04:47:28.174Z","status":"ssl_error","status_checked_at":"2026-01-21T04:47:22.943Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eureka","microservice","python","spring-cloud","spring-cloud-eureka"],"created_at":"2026-01-21T08:16:12.036Z","updated_at":"2026-01-21T08:16:12.089Z","avatar_url":"https://github.com/keijack.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# python-eureka-client\n\n[![PyPI version](https://badge.fury.io/py/py-eureka-client.png)](https://badge.fury.io/py/py-eureka-client)\n\n## Discription\n\nThis is an eureka client written in python, you can easily intergrate your python components with spring cloud.\n\n## Support Python Version\n\nPython 3.7+\n\n*From `0.9.0`, python 2 is no longer supported, if you are using python 2, please use  version `0.8.12`.*\n\n## Why choose\n\n* Register your python components to eureka server.\n* Support failover.\n* Support DNS discovery. \n* Send heartbeat to eureka server.\n* Pull registry from eureka server.\n* Easy to use interface to use other REST service.\n* HA when calling other REST service.\n* Both trandictional and async def interfaces are provided.\n* The http client lib is replacable.\n\n## How to use\n\n### Install\n\n```Shell\npip install py_eureka_client\n```\n\n### Getting Start\n\nThis is the easiest way to use this component.\n\n```python\nimport py_eureka_client.eureka_client as eureka_client\n\nyour_rest_server_port = 9090\n# The flowing code will register your server to eureka server and also start to send heartbeat every 30 seconds\neureka_client.init(eureka_server=\"http://your-eureka-server-peer1,http://your-eureka-server-peer2\",\n                   app_name=\"your_app_name\",\n                   instance_port=your_rest_server_port)\n```\n\nThen, in your business code, use\n\n```python\nimport py_eureka_client.eureka_client as eureka_client\n\nres = eureka_client.do_service(\"OTHER-SERVICE-NAME\", \"/service/context/path\")\nprint(\"result of other service\" + res)\n\n```\n\nYou can also use the `EurekaClient` class. \n\n```python\nfrom py_eureka_client.eureka_client import EurekaClient\nclient = EurekaClient(eureka_server=\"http://my_eureka_server_peer_1/eureka/v2,http://my_eureka_server_peer_2/eureka/v2\", app_name=\"python_module_1\", instance_port=9090)\nawait client.start()\nres = await client.do_service(\"OTHER-SERVICE-NAME\", \"/service/context/path\")\nprint(\"result of other service\" + res)\n# when server is shutted down:\nawait client.stop()\n```\n\nIn fact, the `init` function is a facade of the EurekaClient, it holds a client object behind, you can get that by catching its return value or use `eureka_client.get_client()` to get it. The `init` function will automatically start the client, while using raw `EurekaClient`, you must call the `start()` and `stop()` method explicitly. \n\n\nFrom `0.11.0`, all the methods in `EurekaClient` are defined `async`, and there are also async facade for `init`, `do_servise`, `stop` functions names `init_async`, `do_service_async`, `sto_async`.\n\n### Registering to Eureka Server\n\nThe most common method to will be like:\n\n```Python\nimport py_eureka_client.eureka_client as eureka_client\n\nyour_rest_server_port = 9090\neureka_client.init(eureka_server=\"http://your-eureka-server-peer1,http://your-eureka-server-peer2\",\n                                app_name=\"python_module_1\",\n                                instance_port=your_rest_server_port)\n```\n\nBut if you have deploy your eureka server in several zones, you should specify the `eureka_availability_zones` parameter.\n\n```python\nimport py_eureka_client.eureka_client as eureka_client\neureka_client.init(eureka_availability_zones={\n                \"us-east-1c\": \"http://ec2-552-627-568-165.compute-1.amazonaws.com:7001/eureka/v2/,http://ec2-368-101-182-134.compute-1.amazonaws.com:7001/eureka/v2/\",\n                \"us-east-1d\": \"http://ec2-552-627-568-170.compute-1.amazonaws.com:7001/eureka/v2/\",\n                \"us-east-1e\": \"http://ec2-500-179-285-592.compute-1.amazonaws.com:7001/eureka/v2/\"}, \n                zone=\"us-east-1c\",\n                app_name=\"python_module_1\", \n                instance_port=9090,\n                data_center_name=\"Amazon\")\n```\n\nIf you are looking for flexibility, you should configure Eureka service URLs using DNS.\n\nFor instance, following is a DNS TXT record created in the DNS server that lists the set of available DNS names for a zone.\n\n```\ntxt.us-east-1.mydomaintest.netflix.net=\"us-east-1c.mydomaintest.netflix.net\" \"us-east-1d.mydomaintest.netflix.net\" \"us-east-1e.mydomaintest.netflix.net\"\n```\n\nThen, you can define TXT records recursively for each zone similar to the following (if more than one hostname per zone, space delimit)\n\n```\ntxt.us-east-1c.mydomaintest.netflix.net=\"ec2-552-627-568-165.compute-1.amazonaws.com\" \"ec2-368-101-182-134.compute-1.amazonaws.com\"\ntxt.us-east-1d.mydomaintest.netflix.net=\"ec2-552-627-568-170.compute-1.amazonaws.com\"\ntxt.us-east-1e.mydomaintest.netflix.net=\"ec2-500-179-285-592.compute-1.amazonaws.com\"\n```\n\nAnd then you can create the client like: \n\n```python\nimport py_eureka_client.eureka_client as eureka_client\neureka_client.init(eureka_domain=\"mydomaintest.netflix.net\",\n                region=\"us-east-1\",\n                zone=\"us-east-1c\",\n                app_name=\"python_module_1\", \n                instance_port=9090,\n                data_center_name=\"Amazon\")\n```\n\nYou can specify the protocol, basic authentication and context path of your eureka server separatly rather than setting it at the URL. \n\n```python\nimport py_eureka_client.eureka_client as eureka_client\neureka_client.init(eureka_domain=\"mydomaintest.netflix.net\",\n                region=\"us-east-1\",\n                zone=\"us-east-1c\",\n                eureka_protocol=\"https\",\n                eureka_basic_auth_user=\"keijack\",\n                eureka_basic_auth_password=\"kjauthpass\",\n                eureka_context=\"/eureka/v2\",\n                app_name=\"python_module_1\", \n                instance_port=9090,\n```\n\nor\n\n```python\nimport py_eureka_client.eureka_client as eureka_client\neureka_client.init(eureka_server=\"your-eureka-server-peer1,your-eureka-server-peer2\",\n                eureka_protocol=\"https\",\n                eureka_basic_auth_user=\"keijack\",\n                eureka_basic_auth_password=\"kjauthpass\",\n                eureka_context=\"/eureka/v2\",\n                app_name=\"python_module_1\", \n                instance_port=9090)\n```\n\n*About the instance `IP` and `hostname`*:\n\nIf you are using a `Amazon` data center, `py-eureka-client` will try to use `local-ipv4` and `local-hostname` get from Amazon metadata service. In other cases, `py-eureka-client` will use the first non-loopback ip address and hostname from your net interface. \n\nYou can also specify both these tow field or just one of them explicitly:\n\n```python\neureka_client.init(eureka_server=\"your-eureka-server-peer1,your-eureka-server-peer2\",\n                eureka_protocol=\"https\",\n                eureka_basic_auth_user=\"keijack\",\n                eureka_basic_auth_password=\"kjauthpass\",\n                eureka_context=\"/eureka/v2\",\n                app_name=\"python_module_1\", \n                instance_ip=\"192.168.10.168\",\n                instance_host=\"my-py-component.mydomian.com\",\n                instance_port=9090)\n```\n\nIn some case you might have more than one interfaces attached, for example, you are running your application in a docker-container. In this case you can specify a network via `instance_ip_network` to be used to get the container's ip and host. You can use:\n\n```python\neureka_client.init(eureka_server=\"your-eureka-server-peer1,your-eureka-server-peer2\",\n                eureka_protocol=\"https\",\n                eureka_basic_auth_user=\"keijack\",\n                eureka_basic_auth_password=\"kjauthpass\",\n                eureka_context=\"/eureka/v2\",\n                app_name=\"python_module_1\", \n                instance_ip_network=\"192.168.10.0/24\",\n                instance_port=9090)\n```\n\nIf you want to get the ip only and sepecify the host by yourself, try:\n\n```python\nimport py_eureka_client.netint_utils as netint_utils\n\n# you can get the ip only\nip = netint_utils.get_first_non_loopback_ip(\"192.168.10.0/24\")\nhost = \"my-py-component.mydomian.com\"\n\neureka_client.init(eureka_server=\"your-eureka-server-peer1,your-eureka-server-peer2\",\n                eureka_protocol=\"https\",\n                eureka_basic_auth_user=\"keijack\",\n                eureka_basic_auth_password=\"kjauthpass\",\n                eureka_context=\"/eureka/v2\",\n                app_name=\"python_module_1\", \n                instance_ip=ip,\n                instance_host=host,\n                instance_port=9090)\n```\n\n### Error Callback\n\nYou can specify a callback function when initializing the eureka client, when errors occur in `register`, `discover` or `status update` phase, the callback function will be called to inform you. The callback function will be called only when all the eureka server url are all tried and fails. \n\nThe callback function should accept 2 arguments. which are the error type and the exception itself. please check:\n\n```python\ndef on_err(err_type: str, err: Exception):\n    if err_type in (eureka_client.ERROR_REGISTER, eureka_client.ERROR_DISCOVER):\n        eureka_client.stop()\n    else:\n        print(f\"{err_type}::{err}\")\n\nyour_rest_server_port = 9090\neureka_client.init(eureka_server=\"http://your-eureka-server-peer1,http://your-eureka-server-peer2\",\n                                app_name=\"python_module_1\",\n                                instance_port=your_rest_server_port,\n                                on_error=on_err)\n\n```\n\n### Call Remote Service\n\nAfter `init` the eureka client, this is the most simplist way to do service:\n\n```python\nimport py_eureka_client.eureka_client as eureka_client\n\ntry:\n    res = eureka_client.do_service(\"OTHER-SERVICE-NAME\", \"/service/context/path\")\n    print(\"result of other service\" + res)\nexcept urllib.request.HTTPError as e:\n    # If all nodes are down, a `HTTPError` will raise.\n    print(e)\n```\n\n`do_service` function also recieve a `return_type` keyword parameter, which when `json` was passed, the result will be a `dict` type object whereas `response_object` is pass, the original HTTPResponse object will be return. Please read the relative document for more information.\n\nYou can also use its `async` version:\n\n```python\nimport py_eureka_client.eureka_client as eureka_client\n\nres = await eureka_client.do_service_async(\"OTHER-SERVICE-NAME\", \"/service/context/path\")\n```\n\n*do_service method will automatically try other nodes when one node return a HTTP error, until one success or all nodes being tried.*\n\nIf you want to handle all the services' calling, you can use `walk_nodes` function:\n\n```python\nimport py_eureka_client.eureka_client as eureka_client\n\n# you can define this function with `async def`\ndef walk_using_your_own_urllib(url):\n    print(url)\n    \"\"\"\n    # Connect to url and read result, then return it.\n    # The result you return here will be returned to the `eureka_client.walk_nodes` function\n    # If you want find this node is down, you can raise a `urllib.request.HTTPError`(urllib2.HTTPError in python2)\n    # Then the `eureka_client.walk_nodes` will try to find another node to do the service.\n    \"\"\"\n\n# result is the result that you return in walk_using_your_own_urllib function\ntry:\n    res = eureka_client.walk_nodes(\"OTHER-SERVICE-NAME\", \"/service/context/path\", walker=walk_using_your_own_urllib)\n    print(res)\nexcept urllib.request.HTTPError as e:\n    # If all nodes are down, a `HTTPError` will raise.\n    print(e)\n```\n\nA `async` version is also provied:\n\n```python\nimport py_eureka_client.eureka_client as eureka_client\n\ndef walk_using_your_own_urllib(url):\n    print(url)\n    \"\"\"\n    # Connect to url and read result, then return it.\n    # The result you return here will be returned to the `eureka_client.walk_nodes` function\n    # If provided node is down, you can raise a `urllib.request.HTTPError`(urllib2.HTTPError in python2)\n    # Then the `eureka_client.walk_nodes` will try to find another node to do the service.\n    \"\"\"\n\nres = await eureka_client.walk_nodes_async(\"OTHER-SERVICE-NAME\", \"/service/context/path\",\n                          walker=walk_using_your_own_urllib)\n```\n\n### High Available Strategies\n\nThere are several HA strategies when using discovery client. They are:\n\n* HA_STRATEGY_RANDOM, default strategy, find an node randamly.\n* HA_STRATEGY_STICK, use one node until it goes down.\n* HA_STRATEGY_OTHER, always use a different node from the last time.\n\nIn your `init` function, you can specify one of the above strategies:\n\n```python\nimport py_eureka_client.eureka_client as eureka_client\n# General init method\neureka_client.init(eureka_server=\"http://your-eureka-server-peer1,http://your-eureka-server-peer2\",\n                   app_name=\"your_app_name\",\n                   instance_port=your_rest_server_port,\n                   ha_strategy=eureka_client.HA_STRATEGY_STICK)\n```\n\nIf the build-in stratergies do not satify you, you can load all the registry by following code:\n\n```python\nimport py_eureka_client.eureka_client as eureka_client\n\nclient = eureka_client.get_client()\napp = client.applications.get_application(\"OTHER-SERVICE-NAME\")\nup_instances = app.up_instances\nup_instances_same_zone = app.up_instances_in_zone(client.zone)\nup_instances_other_zone = app.up_instances_not_in_zone(client.zone)\ninst = up_instances[0]\n\n# ... construct your url and do the service call\n\n```\n\n### Use Other Http Client\n\nYou can use other http client to connect to eureka server and other service rather than the build-in urlopen method. It should be useful if you use https connections via self-signed cetificates. \n\nFrom `0.11.0`, the methods of the `http_client.HttpClient` are defined `async`, you can now use some async http libs like `aiohttp`\n\nTo do this, you should:\n\n1. (Optional) At most scenario, you should also write a class that inherited from `py_eureka_client.http_client.HttpResponse`, for the reason of the `py_eureka_client.http_client.HttpResponse` class wraps the `http.client.HTTPResponse` which may not return by the third http libs. \n2. Write a class inherited the `HttpClient` class in `py_eureka_client.http_client`.\n3. Rewrite the `urlopen` method in your class. this method must return an subclass of `py_eureka_client.http_client.HttpResponse`, which is a wrapper class that hold to properties called `raw_response` and `body_text`. \n4. Set you own HttpClient object into `py_eureka_client.http_client` by `py_eureka_client.set_http_client`\n\n```python\nimport py_eureka_client.http_client as http_client\n\n# 1. A class inherited `py_eureka_client.http_client.HttpResonse`\n\nclass MyHttpResponse(http_client.HttpResponse):\n\n    def __init__(self, raw_response):\n        \"\"\"\n        \" This raw response will return when you pass `response_object` in the `do_service` function.\n        \"\"\"\n        self.raw_response = raw_response\n    \n    @property\n    def body_text(self):\n        txt = \"\"\n        \"\"\"\n        \" Read the body text from `self.raw_response`\n        \"\"\"\n        return txt\n\n# 2. A class inherited `py_eureka_client.http_client.HttpClient`.\nclass MyHttpClient(http_client.HttpClient):\n\n    # 3. Rewrite the `urlopen` method in your class.\n    # If you want to raise an exception, please make sure that the exception is an `http_client.HTTPError` or `http_client.URLError`.     \n    async def urlopen(self, request: Union[str, http_client.HttpRequest] = None,\n                      data: bytes = None, timeout: float = None) -\u003e http_client.HttpResponse:\n        res = await your_own_http_client_lib.do_the_visit(request, data, timeout)\n        return MyHttpResponse(res)\n        # You can parse your response object here, and set the body_text to http_client.HttpResponse, then you may ignore the http_client.HttpResponse inheritance.\n        # body_txt = parse_res_body(res)\n        # http_res = http_client.HttpResponse()\n        # http_res.raw_response = res\n        # http_res.body_text = body_text\n        # return http_res\n            \n\n# 4. Set your class to `py_eureka_client.http_client`. \nhttp_client.set_http_client(MyHttpClient())\n```\n\n### Logger\n\nThe default logger is try to write logs to the screen, you can specify the logger handler to write it to a file.\n\n```python\nimport py_eureka_client.logger as logger\nimport logging\n\n_formatter = logging.Formatter(fmt='[%(asctime)s]-[%(name)s]-%(levelname)-4s: %(message)s')\n_handler = logging.TimedRotatingFileHandler(\"/var/log/py-eureka-client.log\", when=\"midnight\", backupCount=7)\n_handler.setFormatter(_formatter)\n_handler.setLevel(\"INFO\")\n\nlogger.set_handler(_handler)\n```\n\nIf you want to add a handler rather than replace the inner one, you can use:\n\n```python\nlogger.add_handler(_handler)\n```\n\nIf you want to change the logger level:\n\n```python\nlogger.set_level(\"DEBUG\")\n```\n\nThis logger will first save all the log record to a global queue, and then output them in a background thread, so it is very suitable for getting several logger with a same handler, especialy the `TimedRotatingFileHandler` which may slice the log files not quite well in a mutiple thread environment. \n\n### Costom Logger\n\nIf you want to use your own logger, you can do this:\n\n```python\nimport py_eureka_client.logger as logger\n\nlogger.set_custom_logger(your_logger)\n```\n\n## Amazon Data Center Support\n\nThis component should support deploying in Amazone EC2, it should automatically load metadata from Amazon metadata service. All the metadata keys come from `com.netflix.appinfo.AmazonInfo` in Netflix's java client. BUT for the reason that I have no amazon environment to test, it may not work. If errors occurs, please submit an issue and provide some detail logs, I will try to fix it as far as I can. If it works, a reply in this [issue](https://github.com/keijack/python-eureka-client/issues/33) is wellcomed.\n\n## More Infomation\n\nYou can find more information in the project comments.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeijack%2Fpython-eureka-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeijack%2Fpython-eureka-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeijack%2Fpython-eureka-client/lists"}