All notable changes to ipwhois-python will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- README "Error response fields" table now lists
successexplicitly as the first row — it is always present on error responses (set tofalse) and is the canonical field to branch on. Previously the table started withmessage, even though every example in the README checksinfo["success"]. - README "Response shape" example for errors updated to show an HTTP 429
scenario (rate limit) instead of an HTTP 400 (invalid IP). The new example
illustrates
retry_afteras a real present field rather than a commented- out hint, which better reflects how callers actually consume the response on the free plan.
- Every error response now carries an
error_typefield, including errors returned by the API. The new value'api'joins the existing'network'and'invalid_argument'codes, so callers can branch on the category of any failure with a singleinfo["error_type"]check — no need to combinesuccesswithhttp_statusto distinguish API vs. non-API errors. Applies to HTTP 4xx / 5xx responses, malformed JSON bodies, and HTTP 2xx responses where the API itself setssuccess: false(e.g. "Invalid IP address", "Reserved range").
retry_afteris now only attached to HTTP 429 responses on the free plan (ipwho.is). The paid endpoint (ipwhois.pro) does not send aRetry-Afterheader, so reading it on paid plans is now skipped and the field will not appear there. Behaviour on the free plan is unchanged.- README "Setting defaults once" section now shows the Free and Paid plans as two separate code blocks, matching the layout used in "Quick start" and "HTTPS encryption". The setters work identically on both plans, so the lookup-override snippet is shared underneath.
- README "Error response fields" table now lists
messageexplicitly (it has always been present on every error response) and theerror_typerow covers the new'api'value as well. - The
_request()HTTP-error code path was lightly refactored so theRetry-Afterheader is parsed in one place instead of two (one for the dict branch and one for the list branch). No behaviour change beyond the free-plan gating noted above.
- The
outputoption has been removed. The library only ever processed JSON responses meaningfully, sooutput="xml"andoutput="csv"were a thin pass-through that returned the raw payload as a string. The option has been dropped fromlookup(),bulk_lookup(), and the constructor's keyword arguments; theIPWhois.SUPPORTED_OUTPUTSconstant is gone. Passingoutput=...will silently no-op. - The 2xx + non-JSON
{"success": True, "raw": ...}fallback in the response handler (which only existed to support the removedoutputparameter) is gone. The API always returns JSON, so any non-JSON 2xx body is now treated as a transport error and returned as asuccess: Falsedict.
set_fields()docstring now mentions that"success"should be included in the field whitelist if you rely oninfo["success"]for error checking — whenfieldsis set, the API only returns the fields you list.- README "Setting defaults once" section rewritten for clarity: the two
ways of passing options (per call vs. as defaults), the available
setters, and the
success-in-fieldsgotcha are now spelled out explicitly. The free/paid example pair was collapsed into a single example, since the setters work identically on both plans. - All examples that filter fields (
README.md,examples/basic.py,examples/defaults.py) now include"success"in the field list.
If your code passes output="json" you can simply remove it — the library
always returns the decoded JSON anyway. If you were relying on
output="xml" or output="csv" to get the raw payload, that use case is
no longer supported; call the API directly with urllib for those formats.
# Before (1.0.1):
info = ipwhois.lookup("8.8.8.8", output="json", fields=["country", "city"])
# After (1.0.2):
info = ipwhois.lookup("8.8.8.8", fields=["success", "country", "city"])- Renamed the main class
ClienttoIPWhoisfor consistency with the package and brand. The recommended import is nowfrom ipwhois import IPWhois. The source module moved fromsrc/ipwhois/client.pytosrc/ipwhois/ipwhois.py, and the test module fromtests/test_client.pytotests/test_ipwhois.py. Public behaviour, method signatures, constructor arguments, and return shapes are all unchanged.
# Before (1.0.0):
from ipwhois import Client
client = Client("YOUR_API_KEY")
info = client.lookup("8.8.8.8")
# After (1.0.1+):
from ipwhois import IPWhois
ipwhois = IPWhois("YOUR_API_KEY")
info = ipwhois.lookup("8.8.8.8")The variable name (client, ipwhois, anything else) is up to you; only
the class identifier changed.
- Initial release.