Name
python-location - Python module to query the IPFire Location Database
Synopsis
import location
db = location.open()
network = db.lookup("81.3.27.38")
Description
The location module makes libloc available in Python. It can look up addresses, list networks, Autonomous Systems and countries, verify databases, and write new ones.
It is the module that location(1) and location-importer(1) are written with. Its classes are written in C, and call libloc directly (see libloc(3)).
All functions that look something up return None if there is nothing. Invalid arguments raise ValueError or TypeError, and anything else that goes wrong in the library raises OSError with the error number that the library has returned.
Importing the module adds two handlers to the location logger of the logging module: one that writes to the console, and one that writes to syslog.
Functions and Constants
- location.open(path=None)
-
Opens the database at path, or the database of the system if path is omitted, and returns a Database.
- location.country_code_is_valid(code)
-
Returns whether code is a valid country code, which has two upper case letters, and does not start with an X (see loc_country_code_is_valid(3)).
- location.discover_latest_version(version=DATABASE_VERSION_LATEST)
-
Asks the DNS when the latest database was published, and returns the time as seconds since the epoch, or None if that could not be found out (see loc_discover_latest_version(3)). Other threads can run while it is waiting for the answer.
- location.set_log_level(priority)
-
Sets the priority of the messages that the library logs, as a syslog(3) priority, for example 7 for LOG_DEBUG.
- location.DATABASE_PATH
-
The path of the database of the system, usually /var/lib/location/database.db.
- location.DATABASE_VERSION_LATEST
-
The latest version of the database format.
- location.NETWORK_FLAG_ANONYMOUS_PROXY, location.NETWORK_FLAG_SATELLITE_PROVIDER, location.NETWORK_FLAG_ANYCAST, location.NETWORK_FLAG_DROP
-
The flags that a network can have.
- location.__version__
-
The version of libloc.
Database
- location.Database(path)
-
Opens the database at path. The database is mapped into memory, and is read again automatically when its file has been replaced, so that it only needs to be opened once. If it cannot be opened, OSError is raised.
- lookup(address)
-
Returns the Network that address is in, or None if the database knows nothing about it. address is a string, for example "81.3.27.38" or "2001:db8::1". Invalid addresses raise ValueError.
- get_as(number)
-
Returns the AS with that number, or None.
- get_country(code)
-
Returns the Country with that code, or None. Invalid codes raise ValueError.
- search_networks(country_codes=None, asns=None, flags=0, family=0, flatten=False)
-
Returns an iterator over all networks that are in one of the countries in the list country_codes, or belong to one of the AS numbers in the list asns, or have one of the flags, or over all networks if none of them are given. family can be socket.AF_INET or socket.AF_INET6 to only return networks of that family. If flatten is true, networks that are inside other networks are being taken out of those, so that no two networks that are being returned overlap.
- search_as(string)
-
Returns an iterator over all Autonomous Systems whose names contain string, ignoring case.
- list_bogons(family=0)
-
Returns an iterator over all networks that should not be seen on the Internet, because they are reserved, or have not been allocated to anybody.
- ases, countries, networks
-
Iterators over all Autonomous Systems, countries, and networks.
- networks_flattened
-
An iterator over all networks, of which none overlap.
- verify(key)
-
Returns whether the database has been signed with the public key, which is an open file. This is False when there is no signature or when key is not a key. Verifying reads the entire database, and other threads can run in the meantime.
- reload()
-
Reads the database again if its file has been replaced, and returns whether it has. This happens automatically every once in a while (see loc_database_reload(3)).
- created_at, vendor, description, license
-
When the database was created, as seconds since the epoch, and who has created it, what it is, and under which license it has been published.
A Database can be used by any number of threads at the same time.
Network
- location.Network(network)
-
Creates a network from a string, for example "10.0.0.0/8". Invalid networks raise ValueError.
- country_code, asn
-
The country code and the AS number of the network, or None. Both can be changed.
- family
-
socket.AF_INET or socket.AF_INET6.
- first_address, last_address
-
The first and last address of the network as strings.
- has_flag(flag), set_flag(flag)
-
Return whether the network has flag, and give it flag.
- is_subnet_of(other)
-
Returns whether the network is inside the network other.
- subnets
-
A tuple with the two halves of the network. Networks that only have one address raise ValueError.
- exclude(other)
-
Returns a list of the networks that are left of the network after other has been taken out of it.
- reverse_pointer(suffix=None)
-
Returns the name of the network in the DNS, which ends in suffix, or in in-addr.arpa. or ip6.arpa. if suffix is omitted, for example "*.10.in-addr.arpa.", or None if the prefix of the network is not a multiple of 8 for IPv4, or of 4 for IPv6.
Networks can be compared with == and sorted. str() returns the network as a string.
AS
- location.AS(number)
-
Creates an Autonomous System.
- number
-
The AS number.
- name
-
The name of the Autonomous System, or None. It can be changed.
ASes can be compared, sorted, and used in sets and as keys in dictionaries. str() returns for example "AS204867 - Lightning Wire Labs GmbH".
Country
- location.Country(code)
-
Creates a country. Invalid codes raise ValueError.
- code
-
The country code.
- name, continent_code
-
The name of the country, and the code of its continent, or None. Both can be changed.
Countries can be compared, sorted, and used in sets and as keys in dictionaries. str() returns the code.
Writer
- location.Writer(private_key1=None, private_key2=None)
-
Creates a new database, which is signed with up to two private keys, which are open files (see loc_writer_new(3)).
- vendor, description, license
-
Who has created the database, what it is, and under which license it is published.
- add_network(network)
-
Adds a network, and returns it as a Network, whose country code, AS number and flags can then be set. If the network has already been added, IndexError is raised.
- add_as(number)
-
Adds an Autonomous System, and returns it as an AS, whose name can then be set.
- add_country(code)
-
Adds a country, and returns it as a Country, whose name and continent can then be set.
- write(path, version=DATABASE_VERSION_LATEST)
-
Writes the database to path. Other threads can run while the database is being written. Until it has been written, the writer cannot be changed, and anything that tries raises RuntimeError. The networks, Autonomous Systems and countries that have been added to it must not be changed either.
Other Modules
- location.export
-
Exports networks for ipset, nftables, and xt_geoip, which is what location export uses (see location(1)). Exporter(db, writer) takes one of the writers in location.export.formats, and its export(directory, families, countries, asns) writes one file for every country and AS number and family into directory.
- location.downloader
-
Downloads new databases, which is what location update uses. Downloader().download(public_key, timestamp=None) downloads a database that is newer than timestamp from one of the mirrors, and verifies it with the public key in the file public_key. It returns a temporary file, whose name is in name.
Examples
Look up an address:
import location
db = location.open()
network = db.lookup("81.3.27.38")
if network:
print(network, network.country_code, network.asn)
Print all networks in Germany that are not inside each other:
import socket
for network in db.search_networks(country_codes=["DE"],
family=socket.AF_INET, flatten=True):
print(network)
Find out who an AS number belongs to:
print(db.get_as(204867))
Verify a database:
with open("/var/lib/location/signing-key.pem") as f:
if not db.verify(f):
raise RuntimeError("The database has not been signed by the vendor")
Write a new database:
writer = location.Writer()
writer.vendor = "Example"
network = writer.add_network("192.0.2.0/24")
network.country_code = "DE"
network.asn = 64512
writer.write("example.db")
See Also
Authors
Michael Tremer