Usage
Output
Results print as one table.
+--------------+---------------------+------+
| Domain | Date | Days |
+--------------+---------------------+------+
| example.com | 15th March 2027 | 174 |
| example.com | 22nd September 2026 | 0 |
| example.com | Expired | -12 |
| missing.test | Available | — |
| example.net | unpublished | — |
| slow.test | timed out | — |
| nope.invalid | Invalid Domain | — |
+--------------+---------------------+------+
A published date is the day, with st, nd, rd, or th, then the month
name and the year, as in 11th November 2026. Expired means that date is
already past. Days is the number of UTC calendar days remaining. 0 means
the name expires today. A negative number is how many days ago it expired.
Available means the registry has no registration. unpublished means the
lookup succeeded but WHOIS included no date, which is common when a registry
redacts the record. Invalid Domain means the name was not queried: it is
empty, not a hostname, or its suffix is not a known top-level domain. A query
failure, including a connection timeout, puts the error in the date column.
Every name is a row.
International names are converted to ASCII before the query, and that form is what the domain column prints.
CLI
domain-expiry example.com example.org example.net
domain-expiry example.com,example.org
domain-expiry --file domains.txt --warn-days 14
domain-expiry --file - --timeout 5
domain-expiry --sort domain example.org example.com
domain-expiry --sort days --order descending example.com example.org
With no domains, the command prints help and exits 2.
--file reads one domain per line. Blank lines and # comments are ignored.
- reads stdin. Repeat --file to combine lists. Names on the command line
are checked first, then names from each file.
--timeout is the socket timeout for that WHOIS query, in seconds. It must
be greater than 0.
--warn-days is how close a date can be before the command exits 1. The
comparison is inclusive: a domain with 30 days left exits 1 when
--warn-days is 30. 0 means only today or earlier. Available,
unpublished, expired, and invalid names also exit 1. A failed query,
including a timeout, exits 2. When one name needs attention and another
query fails, the command exits 1.
--sort orders the table by domain, date, or days. --order is
ascending (the default) or descending. asc and desc are accepted.
Domain order is alphabetical and ignores case. Date order uses the expiration
date, including names that show Expired. Day order uses the day count.
Rows with no date or day count stay at the end. Without --sort, rows stay
in the order the names were given. --order without --sort exits 2.
Library
from lupaxa.domain_expiry import lookup
result = lookup("example.com", timeout=10.0)
if result.status == "expires":
print(result.expiration, result.days_remaining)
else:
print(result.status, result.error)
lookup returns a result for registry misses, unpublished dates, invalid
names, and query failures, including a connection timeout. An invalid name
has status invalid and is not sent to WHOIS. It raises ValueError when
timeout is not greater than 0.
Pass whois_query to replace the network call in tests. The callable receives
the ASCII domain and the timeout in seconds, and returns an object with an
expiration_date attribute. That attribute may be a datetime, a date, an
ISO-8601 string, or a list of those. The earliest date is kept. Naive values
are treated as UTC.