{"id":17974702,"url":"https://github.com/meeb/whoisit","last_synced_at":"2026-01-12T13:18:17.312Z","repository":{"id":42531183,"uuid":"375105443","full_name":"meeb/whoisit","owner":"meeb","description":"A Python library to RDAP WHOIS-like services for internet resources such as ASNs, IPs, CIDRs and domains","archived":false,"fork":false,"pushed_at":"2026-01-10T05:21:48.000Z","size":444,"stargazers_count":117,"open_issues_count":0,"forks_count":24,"subscribers_count":8,"default_branch":"main","last_synced_at":"2026-01-11T01:35:26.453Z","etag":null,"topics":["python","rdap","whois"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meeb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":["meeb"]}},"created_at":"2021-06-08T18:20:10.000Z","updated_at":"2026-01-10T05:20:52.000Z","dependencies_parsed_at":"2023-01-24T01:30:58.718Z","dependency_job_id":"38d7f9a0-fb15-4723-b4c4-f9463e1fd0f9","html_url":"https://github.com/meeb/whoisit","commit_stats":{"total_commits":129,"total_committers":5,"mean_commits":25.8,"dds":0.06201550387596899,"last_synced_commit":"157fbd171ea8176c7f6506e24c585a8cfd80be2c"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/meeb/whoisit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Fwhoisit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Fwhoisit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Fwhoisit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Fwhoisit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meeb","download_url":"https://codeload.github.com/meeb/whoisit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meeb%2Fwhoisit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28338996,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["python","rdap","whois"],"created_at":"2024-10-29T17:15:10.197Z","updated_at":"2026-01-12T13:18:17.296Z","avatar_url":"https://github.com/meeb.png","language":"Python","funding_links":["https://github.com/sponsors/meeb"],"categories":["Python"],"sub_categories":[],"readme":"# whoisit\n\nA Python client to RDAP WHOIS-like services for internet resources (IPs, ASNs, domains,\netc.). `whoisit` is a simple library that makes requests to the \"new\" RDAP (Registration\nData Access Protocol) query services for internet resource information. These services\nstarted to appear in 2017 and have become more widespread since 2020.\n\n`whoisit` is designed to abstract over RDAP. While RDAP is a basic HTTP and JSON based\nprotocol which can be implemented in a single line of Python with `requests` the\nbootstrapping (which RDAP service to query for what item) and extracting useful\ninformation from the RDAP responses is extensive enough that a library like this is\nuseful.\n\n\n## Installation\n\n`whoisit` is pure Python and only has a dependancy on the `requests` and `dateutil`\nlibraries. You can install `whoisit` via pip:\n\n```bash\n$ pip install whoisit\n```\n\nAny modern version of Python3 will be compatible.\n\n\n## Usage\n\n`whoisit` supports the 4 main types of lookups supported by RDAP services. These are:\n\n * ASNs (autonomous systems numbers) known as `autnum` objects\n * DNS registrations known as `domain` objects - only some TLDs are supported\n * IPv4 and IPv6 addresses and CIDRs / prefixes known as `ip` objects\n * Entities (People, organisations etc. by ENTITY-HANDLES) known as `entity` objects\n\n`whoisit` returns parsed RDAP formatted JSON as (mostly) flat dictionaries by default.\n\nBasic examples:\n\n```python\nimport whoisit\n\nwhoisit.bootstrap()\n\nresults = whoisit.asn(1234)\nprint(results['name'])\n\nresults = whoisit.domain('example.com')\nprint(results['nameservers'])\n\nresults = whoisit.ip('1.2.3.4')\nprint(results['name'])\n\nresults = whoisit.ip('1.2.3.0/24')\nprint(results['name'])\n\nresults = whoisit.ip('2404:1234:1234:1234:1234:1234:1234:1234')\nprint(results['name'])\n\nresults = whoisit.ip('2404:1234::/32')\nprint(results['name'])\n\nresults = whoisit.entity('ARIN')\nprint(results['last_changed_date'])\n```\n\nBasic async examples:\n\n```python\nimport whoisit\nimport asyncio\n\nasync def whoisit_lookups():\n    results = await whoisit.asn_async(1234)\n    print(results['name'])\n    results = await whoisit.domain_async('example.com')\n    print(results['nameservers'])\n    results = await whoisit.ip_async('1.2.3.4')\n    print(results['name'])\n    results = await whoisit.ip_async('1.2.3.0/24')\n    print(results['name'])\n    results = await whoisit.ip_async('2404:1234:1234:1234:1234:1234:1234:1234')\n    print(results['name'])\n    results = await whoisit.ip_async('2404:1234::/32')\n    print(results['name'])\n    results = await whoisit.entity_async('ARIN')\n    print(results['last_changed_date'])\n\nloop = asyncio.get_event_loop()\nloop.run_until_complete(whoisit.bootstrap_async())\nloop.run_until_complete(whoisit_lookups())\nloop.close()\n```\n\n\n### Raw response data\n\nIn each case `results` will be a dictionary containing the most useful information for\neach request type. If the data you want is not in the response you can request the raw,\nunparsed and large RDAP JSON data by adding the `raw=True` argument to the request, for\nexample:\n\n```python\nresults = whoisit.domain('example.com', raw=True)\n# 'results' is now the full, raw response from the RDAP service\n```\n\nIf you want to obtain both the parsed and raw data you can use the `include_raw=True`\nargument. In this case, the `results` will contain an additional `raw` key that contains the raw data. For example:\n\n```python\nresults = whoisit.domain('example.com', include_raw=True)\n# 'results' is the parsed response from whoisit\n# the raw response can now be accessed as 'results[\"raw\"]'\n```\n\nThe `raw` and `include_raw` arguments cannot be used together. In such a case an `ArgumentError` will be raised.\n```python\nresults = whoisit.domain('example.com', raw=True, include_raw=True)\n# This raises a whoisit.errors.ArgumentError\n```\n\n### Specifying RDAP service / RIR\n\nIf for some reason you accidentally end up querying the wrong RDAP endpoint your query\nshould end up still working, for example if you query ARIN for information on the IP\naddress `1.1.1.1` it will redirect you to APNIC (where `1.1.1.1` is allocated)\nautomatically.\n\nSome resources, most notably entity handles, do not redirect or have assigned obvious\nnamespaces linked to particular registries. For these queries `whoisit` will attempt to\nguess the RDAP service to query by examining the name for prefixes or postfix, such as\nmany RIPE entities are named `RIPE-SOMETHING`. If your entity does not have an obvious\nprefix or postfix like `ARIN-*` or `*-AP` you will need to tell `whoisit` which registry\nto make the request to by specifying the `rir=name` argument. The `rir` argument stands\nfor \"Regional Internet Registry\". For example:\n\n```python\n# This will work OK because the entity is prefixed with an obvious RIR name\nresults = whoisit.entity('RIPE-NCC-MNT')\n\n# This will cause a QueryError to be raised because ARIN returns a 404 for RIPE-NCC-MNT\nresults = whoisit.entity('RIPE-NCC-MNT', rir='arin')\n\n# This will cause a UnsupportedError to be raised because we have no way to detect\n# which RDAP service to query as the entity has no RIR prefix or postfix\nresults = whoisit.entity('AS5089-MNT')\n\n# This will work OK because the entity is registered at RIPE\nresults = whoisit.entity('AS5089-MNT', rir='ripe')\n```\n\n\n### Weaken SSL ciphers\n\nSome RDAP servers do not have particularly secure SSL implementations. As RDAP returns\nread-only and public information it may be acceptable for you to want to downgrade the\nsecurity of your `whoisit` requests to successfully return data.\n\nYou can use the `allow_insecure_ssl=True` argument to your queries to enable this.\n\nFor example (as of 2021-07-25):\n\n```python\n# This will result in an SSL error\nresults = whoisit.domain('nic.work')\n# ... SSLError(SSLError(1, '[SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:1129)')))\n\n# This will work\nresults = whoisit.domain('nic.work', allow_insecure_ssl=True)\n```\n\nNote that with `allow_insecure_ssl=True` the upstream RDAP server certificate is\nstill validated, it just permits weaker SSL ciphers during the handshake. You should\nonly use `allow_insecure_ssl=True` if your request fails with an SSL cipher or\nhandshake error first.\n\n\n### Domain lookup subrequests\n\nMany RDAP endpoints for domains supply a related RDAP server run by a registry which\nmay contain more information about the domain. `whoisit` by default will attempt to\nmake a subrequest to the related RDAP endpoint if available to obtain more detailed\nresults. Occasionally, the related RDAP endpoints may fail or return data in an\ninvalid format. You can disable related RDAP endpoint subrequests by passing the\n`follow_related=False` argument to `whoisit.domain(...)`. For example (as of 2024-04-30):\n\n```python\nresults = whoisit.domain('example.com', follow_related=False)\n```\n\nIf you encounter a parsing error when using related RDAP endpoint data you can also\nskip the parsing by using `raw=True` but continue to use related RDAP data. `whoisit`\nwill attempt to handle the RDAP data returned but there will be occasions when RDAP\nresults change beyond what `whoisit` can parse. When using raw data you will need to\nparse the data yourself.\n\nYou can also write a fallback:\n\n```python\ntry:\n    results = whoisit.domain('example.com')\n    # Assume an error parsing the related RDAP data occurs here\nexcept Exception as e:\n    print(f'Failed to look up domain, trying fallback: {e}')\n    results = whoisit.domain('example.com', follow_related=False)\n    # Likely to succeed if the related RDAP data was the issue\n```\n\n\n## Bootstrapping\n\n`whoisit` needs to know which RDAP service to query for a resource. This information is\nprovided by the IANA as bootstrapping information. Bootstrapping data simply says things\nlike \"this CIDR is allocated to ARIN, this CIDR is allocated to RIPE\" and so on for all\nresources. The bootstrap data means you should be directly querying the correct RDAP\nserver for your request at all times. You should cache the bootstrap information locally\nif you plan to make more than a single request otherwise you'll make additional requests\nto the IANA every time you run a query. Example bootstrap information caching:\n\n```python\nimport whoisit\n\nprint(whoisit.is_bootstrapped())  # -\u003e False\nwhoisit.bootstrap()               # Slow, makes several HTTP requests to the IANA\nprint(whoisit.is_bootstrapped())  # -\u003e True\n\n# bootstrap_info returned here is a string of JSON serialised bootstap information\n# You can store it in a memory cache or write it to disk for a few days\nbootstrap_info = whoisit.save_bootstrap_data()\n\n# Clear bootstrapping data\nwhoisit.clear_bootstrapping()\n\n# Later, you can do\nprint(whoisit.is_bootstrapped())  # -\u003e False\nif not whoisit.is_bootstrapped():\n    whoisit.load_bootstrap_data(bootstrap_info)  # Fast, no HTTP requests made\nprint(whoisit.is_bootstrapped())  # -\u003e True\n\n# For convenience internally whoisit stores a timestamp of when the bootstrap data was\n# last updated and has a \"is older than\" helper method\nif whoisit.bootstrap_is_older_than(days=3):\n    # Bootstrap data was last updated over 3 days ago, refresh it\n    whoisit.clear_bootstrapping()\n    whoisit.bootstrap()\n    bootstrap_info = whoisit.save_bootstrap_data()  # and save it to upload your cache\n```\n\nAs of `whoisit` version 3.0.0 there is also an optional async interface:\n\n```python\nawait whoisit.bootstrap_async()\n```\n\nA reasonable suggested way to handle bootstrapping data would be to use Memcached or\nRedis, for example:\n\n```python\nimport whoisit\nimport redis\n\nr = redis.Redis(host='localhost', port=6379, db=0)\n\nbootstrap_info = r.get('whoisit_bootstrap_info')\nif bootstrap_info:\n    whoisit.load_bootstrap_data(bootstrap_info)\nelse:\n    whoisit.bootstrap()\n    bootstrap_info = whoisit.save_bootstrap_data()\n    expire_in_3_days = 60 * 60 * 24 *3\n    r.set('whoisit_bootstrap_info', bootstrap_info, ex=expire_in_3_days)\n\n# Send queries as normal once bootstrapped\nwhoisit.asn(12345)\n```\n\nSome services, most notably TLDs, do have RDAP servers which may not be set properly\nin the IANA bootstrap data. `whoisit` maintains a record of these and can patch the\nIANA data to allow more TLDs to be queried. You can enable this with the\n`overrides=True` parameter when loading bootstrap data:\n\n```python\nwhoisit.bootstrap(overrides=True)\n```\n\nor\n\n```python\nwhoisit.load_bootstrap_data(bootstrap_info, overrides=True)\n```\n\nBoth `whoisit.save_bootstrap_data()` and `whoisit.load_bootstrap_data(some_data)` also\nsupport `as_json=True` as a default argument. The default operation is to return bootstrap\ndata as a JSON encoded string and load it from a JSON encoded string. If you want to\nserialise the bootstrapping information in some other format you can use set `as_json=False` on\nboth `whoisit.save_bootstrap_data(as_json=False)` and\n`whoisit.load_bootstrap_data(some_data, as_json=False)`. These methods will then return and\nload a Python dictionary instead of JSON and you can perform serialisation yourself however\nyou need in your application.\n\n**Important**: when using the overrides you may recieve non-standard data, data that\nis not in the same format as officially listed IANA data and you may not recieve a copy\nof any required terms of service or terms of use. You will have to manually verify data\nreturned by overridden endpoints.\n\n\n### Insecure (HTTP) RDAP endpoints\n\nSome RDAP servers are only available over HTTP and not HTTPS. This is disabled by\ndefault. When you bootstrap `whoisit` a `debug` notice will be emitted for any RDAP\nendpoint that is not loaded because it is insecure. For example:\n\n```python\n# Enable debug logging\nimport os\nos.environ['DEBUG'] = 'true'\n # Load and boostrap whoisit\nimport whoisit\n# \u003e [datetime] bootstrap [DEBUG] Cleared bootstrap data\nwhoisit.bootstrap()\n# \u003e ... debug logs ...\n# \u003e [datetime] bootstrap [DEBUG] No valid RDAP service URLs could be parsed\n#              from: ['http://cctld.uz:9000/'] (insecure scheme,\n#              try whoisit.bootstrap(allow_insecure=True))\n# \u003e ... debug logs ...\n# \u003e [datetime] bootstrap [DEBUG] Bootstrapped\n```\n\nThis line informs you that an RDAP endpoint has been skipped because it is only\navailable over HTTP. You can opt-in to allow insecure endpoints by calling the\nbootstrap methods `bootstrap()` and `load_bootstrap_data()` with the optional\n`allow_insecure=True` argument. For example:\n\n```python\n# Bootstrap with allowing insecure endpoints\nwhoisit.bootstrap(allow_insecure=True)\n```\n\nor\n\n```python\n# Load saved bootstrap data with allowing insecure endpoints\nwhoisit.load_bootstrap_data(bootstrap_info, allow_insecure=True)\n```\n\n## Proxies\n\nYou can specify an HTTP proxy to use for all requests made by `whoisit` by calling the\n`set_proxy(...)` method. You can clear the proxy with `clear_proxy()`. All requests made\nby `whoisit` will use the proxy specified by the last call to `set_proxy(...)`. For example:\n\n```python\nwhoisit.set_proxy('http://127.0.0.1:8080')\n# Both bootstrapping and the IP query for 1.1.1.1 will use the proxy at http://127.0.0.1:8080\nwhoisit.bootstrap()\nresult = whoisit.ip('1.1.1.1')\nwhoisit.clear_proxy()\n# All future requests will not use a proxy\nresult = whoisit.domain('example.com')\n```\n\nYou can switch or clear proxies at any time. Note that setting or clearing a proxy will also\nreset the session. Proxies are supported by both the asynchonous and synchronous interfaces.\n\n## Sessions\n\n`whoisit` shared connection pools for all requests by default. This creates HTTP sessions that\nare shared when multiple connections are made to the same RDAP endpoints. If required, you can\nreset these sessions with the `clear_session()` method. For example:\n\n```python\nwhoisit.clear_session()\n```\n\n\n## Response data\n\nBy default `whoisit` returns parsed, summary useful information. This information is\n*simplified*. This means that some information is lost from the raw, original data. For\nexample, `whoisit` doesn't return the date that nameservers were last updated. If you\nneed more information than `whoisit` returns by default remember to add `raw=True` to\nyour query and parse the RDAP response yourself.\n\nData from `whoisit` is returned, where possible, as rich data types such as `datetime`,\n`IPv4Network` and `IPv6Network` objects.\n\nThe following values are returned for every successful response:\n\n```python\nresponse = {\n    'handle': str,               # Entity handle for the object, always set\n    'parent_handle': str,        # Parent entity handle for the object\n    'name': str,                 # Name of the object\n    'whois_server': str,         # WHOIS server hostname object data can be found on\n    'type': str,                 # Object type, such as autnum or domain\n    'terms_of_service_url': str, # URL to the terms of service for using the object data\n    'copyright_notice', str,     # Copyright notice for the object data\n    'description': list,         # List of text lines that describe the object\n    'last_changed_date': datetime or None,  # Date and time the object was last updated\n    'registration_date': datetime or None,  # Date and time the object was registered\n    'expiration_date': datetime or None,    # Date and time the object expires\n    'rir': str,                  # Short name of the RIR for the object, such as 'arin'\n    'url': str,                  # URL to the RDAP query which was made for this request\n    'entities': dict,            # A dict of entities linked to the object\n}\n```\n\nThe entities dictionary has the following format, note there may be multiple entities\nfor each role:\n\n```python\nresponse['entities']['some_role'][] = { # Role names are strings, like 'registrant'\n    'email': str,          # Email address of the entity\n    'handle': str,         # Handle of the entity\n    'name': str,           # Name of the entity\n    'rir': str,            # Short name of the RIR where the entity is registered\n    'type': str,           # Type of the entity, usually 'entity'\n    'url': str,            # URL to an RDAP service to query this entity \n    'whois_server': str,   # WHOIS server hostname entity data can be found on\n}\n```\n\nIn addition to the default data for all responses listed above requests have additional\nextra fields in their responses, these are:\n\n### Additional ASN response data\n\n```python\n# ASN response data includes all shared general response fields above and also:\nresponse = {\n    'asn_range': list,       # A list of the start and end range for an AS allocation\n                             # For example, [123,134] or [123,123]\n}\n```\n\n### Additional domain response data\n\n```python\n# Domain response data includes all shared general response fields above and also:\nresponse = {\n    'unicode_name': str,     # Domain name in unicode if available\n    'nameservers': list,     # List of name servers for the domain as strings\n    'status': list,          # List of the domain states as strings\n}\n```\n\n### Additional IP response data\n\n```python\n# IP response data includes all shared general response fields above and also:\nresponse = {\n    'country': str,          # Two letter country code for the IP block\n    'ip_version': int,       # 4 or 6 to denote the IP version\n    'assignment_type': str,  # Assignment type, such as 'assigned portable'\n    'network': IPvXNetwork,  # A IPv4Network or IPv6Network object for the prefix\n}\n```\n\n### Additional entity response data\n\n```python\n# Entity response data includes all shared general response fields above and also:\nresponse = {\n    'email': str,            # If the entity as a root vcard the email address\n}\n```\n\n### Full response example\n\nA full example response for an IP query for the IPv4 address `1.1.1.1`:\n\n```python\nimport whoisit\nwhoisit.bootstrap()\nresponse = whoisit.ip('1.1.1.1')\nprint(response)\n{\n    'handle': '1.1.1.0 - 1.1.1.255',\n    'parent_handle': '',\n    'name': 'APNIC-LABS',\n    'whois_server': 'whois.apnic.net',\n    'type': 'ip network',\n    'terms_of_service_url': 'http://www.apnic.net/db/dbcopyright.html',\n    'copyright_notice': '',\n    'description': [\n        'APNIC and Cloudflare DNS Resolver project',\n        'Routed globally by AS13335/Cloudflare',\n        'Research prefix for APNIC Labs'\n    ],\n    'last_changed_date': datetime.datetime(2020, 7, 15, 13, 10, 57, tzinfo=tzutc()),\n    'registration_date': None,\n    'expiration_date': None,\n    'url': 'https://rdap.apnic.net/ip/1.1.1.0/24',\n    'rir': 'apnic',\n    'entities': {\n        'abuse': [\n            {\n                'handle': 'IRT-APNICRANDNET-AU',\n                'url': 'https://rdap.apnic.net/entity/IRT-APNICRANDNET-AU',\n                'type': 'entity',\n                'name': 'IRT-APNICRANDNET-AU',\n                'email': 'helpdesk@apnic.net',\n                'rir': 'apnic'\n            }\n        ],\n        'administrative': [\n            {\n                'handle': 'AR302-AP',\n                'url': 'https://rdap.apnic.net/entity/AR302-AP',\n                'type': 'entity',\n                'name': 'APNIC RESEARCH',\n                'email': 'research@apnic.net',\n                'rir': 'apnic'\n            }\n        ],\n        'technical': [\n            {\n                'handle': 'AR302-AP',\n                'url': 'https://rdap.apnic.net/entity/AR302-AP',\n                'type': 'entity',\n                'name': 'APNIC RESEARCH',\n                'email': 'research@apnic.net',\n                'rir': 'apnic'\n        ]\n    },\n    'country': 'AU',\n    'ip_version': 4,\n    'assignment_type': 'assigned portable',\n    'network': IPv4Network('1.1.1.0/24')\n}\n```\n\n## Full API synopsis\n\n### `whoisit.is_bootstrapped()` -\u003e `bool`\n\nReturns boolean True or False if your `whoisit` instance is bootstrapped or not.\n\n### `whoisit.bootstrap(overrides=bool, allow_insecure=bool)` -\u003e `bool`\n\nBootstraps your `whoisit` instance with remote IANA bootstrap information. Returns\nTrue or raises a `whoisit.errors.BootstrapError` exception if it fails. This method\nmakes HTTP requests to the IANA.\n\n### `whoisit.clear_bootstrapping()` -\u003e `bool`\n\nClears any stored bootstrap information. Always returns boolean True.\n\n### `whoisit.save_bootstrap_data()` -\u003e `str`\n\nReturns a string of JSON serialised bootstrap information if any is loaded. If no\nbootstrap information loaded a `whoisit.errors.BootstrapError` will be raised.\n\n### `whoisit.load_bootstrap_data(data=str, overrides=bool, allow_insecure=bool)` -\u003e `bool`\n\nLoads a string of JSON serialised bootstrap data as returned by `save_bootstrap_data()`.\nReturns True if the data is loaded or raises a `whoisit.errors.BootstrapError` if\nloading fails.\n\n### `whoisit.bootstrap_is_older_than(days=int)` -\u003e `bool`\n\nTests if the loaded bootstrap data is older than the specified number of days as an\ninteger. Returns True or False. If no bootstrap information is loaded a\n`whoisit.errors.BootstrapError` exception will be raised.\n\n### `whoisit.asn(asn=int, rir=str, raw=bool, include_raw=False, allow_insecure_ssl=bool)` -\u003e `dict`\n\nQueries a remote RDAP server for information about the specified AS number. AS number\nmust be an integer. Returns a dict of information. If `raw=True` is passed a large dict\nof the raw RDAP response will be returned. If `include_raw` is passed the raw RDAP response will be included in the parsed response under the `raw` key. If both `raw` and `include_raw` are set a `whoisit.errors.ArgumentError` will be raised. If the query fails a\n`whoisit.errors.QueryError` exception will be raised. If no bootstrap data is loaded\na `whoisit.errors.BootstrapError` exception will be raised. if `allow_insecure_ssl=True`\nis passed the RDAP queries will allow weaker SSL handshakes. Examples:\n\n```python\nwhoisit.asn(12345)\nwhoisit.asn(12345, rir='arin')\nwhoisit.asn(12345, raw=True)\nwhoisit.asn(12345, include_raw=True)\nwhoisit.asn(12345, rir='arin', raw=True)\nwhoisit.asn(12345, allow_insecure_ssl=True)\n```\n\nAs of `whoisit` version 3.0.0 there is also an optional async interface:\n\n```python\nresponse = await whoisit.asn_async(12345)\n```\n\n### `whoisit.domain(domain=str, raw=bool, include_raw=False, allow_insecure_ssl=bool)` -\u003e `dict`\n\nQueries a remote RDAP server for information about the specified domain name. The domain\nname must be a string and in a valid domain name \"something.tld\" style format. Returns a\ndict of information. If `raw=True` is passed a large dict of the raw RDAP response will\nbe returned. If `include_raw` is passed the raw RDAP response will be included in the parsed response under the `raw` key. If both `raw` and `include_raw` are set a `whoisit.errors.ArgumentError` will be raised. If the query fails a `whoisit.errors.QueryError` exception will be raised.\nIf no bootstrap data is loaded a `whoisit.errors.BootstrapError` exception will be\nraised. If the TLD is unsupported a `whoisit.errors.UnsupportedError` exception will be\nraised.  if `allow_insecure_ssl=True` is passed the RDAP queries will allow weaker SSL\nhandshakes. **Note that not all TLDs are supported, only some have RDAP services!**\nExamples:\n\n```python\nwhoisit.domain('example.com')\nwhoisit.domain('example.com', raw=True)\nwhoisit.domain('example.com', include_raw=True)\nwhoisit.domain('example.com', allow_insecure_ssl=True)\n```\n\nAs of `whoisit` version 3.0.0 there is also an optional async interface:\n\n```python\nresponse = await whoisit.domain_async('example.com')\n```\n\n### `whoisit.ip(ip=\"1.1.1.1\", rir=str, raw=bool, include_raw=False, allow_insecure_ssl=bool)` -\u003e `dict`\n\nQueries a remote RDAP server for information about the specified IP address or CIDR. The\nIP address or CIDR must be a string and in the correct IP address or CIDR format or\nany one of IPv4Address, IPv4Network, IPv6Address or IPv6Network objects. Returns a dict\nof information. If `raw=True` is passed a large dict of the raw RDAP response will be\nreturned. If `include_raw` is passed the raw RDAP response will be included in the parsed response under the `raw` key. If both `raw` and `include_raw` are set a `whoisit.errors.ArgumentError` will be raised. If the query fails a `whoisit.errors.QueryError` exception will be raised. If\nno bootstrap data is loaded a `whoisit.errors.BootstrapError` exception will be raised.\nif `allow_insecure_ssl=True` is passed the RDAP queries will allow weaker SSL handshakes.\nExamples:\n\n```python\nwhoisit.ip('1.1.1.1')\nwhoisit.ip('1.1.1.1', rir='apnic')\nwhoisit.ip('1.1.1.1', raw=True, rir='apnic')\nwhoisit.ip('1.1.1.1', include_raw=True, rir='apnic')\nwhoisit.ip('1.1.1.0/24')\nwhoisit.ip(IPv4Address('1.1.1.1'))\nwhoisit.ip(IPv4Network('1.1.1.0/24'))\nwhoisit.ip(IPv6Address('2001:4860:4860::8888'))\nwhoisit.ip(IPv6Network('2001:4860::/32'), rir='arin')\nwhoisit.ip('1.1.1.1', allow_insecure_ssl=True)\n```\n\nAs of `whoisit` version 3.0.0 there is also an optional async interface:\n\n```python\nresponse = await whoisit.ip_async('1.1.1.1')\n```\n\n### `whoisit.entity(entity=str, rir=str, raw=bool, include_raw=False, allow_insecure_ssl=bool)` -\u003e `dict`\n\nQueries a remote RDAP server for information about the specified entity name. The\nentity name must be a string and in the correct entity format. Returns a dict of\ninformation. If `raw=True` is passed a large dict of the raw RDAP response will be\nreturned. If `include_raw` is passed the raw RDAP response will be included in the parsed response under the `raw` key. If both `raw` and `include_raw` are set a `whoisit.errors.ArgumentError` will be raised. If the query fails a `whoisit.errors.QueryError` exception will be raised.\nIf no bootstrap data is loaded a `whoisit.errors.BootstrapError` exception will be\nraised. if `allow_insecure_ssl=True` is passed the RDAP queries will allow weaker\nSSL handshakes. Examples:\n\n```python\nwhoisit.entity('ZG39-ARIN')\nwhoisit.entity('ZG39-ARIN', rir='arin')\nwhoisit.entity('ZG39-ARIN', rir='arin', raw=True)\nwhoisit.entity('ZG39-ARIN', rir='arin', include_raw=True)\nwhoisit.entity('ZG39-ARIN', allow_insecure_ssl=True)\n```\n\nAs of `whoisit` version 3.0.0 there is also an optional async interface:\n\n```python\nresponse = await whoisit.entity_async('ZG39-ARIN')\n```\n\n\n## Data usage\n\nAll data returned by RDAP servers are covered by the various policies embeddd in the\nresults. As such you should carefuly review your usage of the data to make sure it\ncomplies with the policy of the RDAP server you are querying.\n\n\n## Excessive use\n\nAs an API client `whoisit` is entirely subject to the resource and request limits\napplied by the remote RDAP servers it queries. If you recieve request errors for rate\nlimiting you should slow down your requests. Different servers have different limits.\nThe LACNIC RDAP server in particular only permits a low number of requests per minute.\n\n\n# Tests\n\nThere is a test suite that you can run by cloning this repository, installing the\nrequired dependancies and execuiting:\n\n```bash\n$ make test\n```\n\n\n# Debugging\n\n`whoisit` will check for a `DEBUG` environment variable and if set, will output debug\nlogs that detail the internals for the bootstrapping, requests and parsing operations.\nIf you want to enable debug logging, set `DEBUG=true` (or `1` or `y` etc.). For example:\n\n```bash\n$ export DEBUG=true\n$ python3 some-script-that-uses-whoisit.py\n```\n\n\n# Contributing\n\nAll properly formatted and sensible pull requests, issues and comments are welcome.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeeb%2Fwhoisit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeeb%2Fwhoisit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeeb%2Fwhoisit/lists"}