Skip to content

maxmind reader

use Python

toml
[tool.poetry.dependencies]
python = "^3.11"
geoip2 = "^4.6.0"

[[tool.poetry.source]]
name = "aliyun"
url = "http://mirrors.aliyun.com/pypi/simple"
default = true
python
import geoip2.database
import os

class GeoIP:

    def __init__(self) -> None:
        self.filename_mmdb = os.path.join(os.path.dirname(__file__), 'GeoLite2-City.mmdb')
        self.country_name = 'zh-CN'
        self.reader = geoip2.database.Reader(self.filename_mmdb)

    @staticmethod
    def get_data_by_key(data, keys: list) -> object:
        if not data:
            return None
        for k in keys:
            if k not in data:
                return None
            data = data[k]
        return data

    def get_ip_location_data(self, ip: str) -> dict:

        data_loc = dict()
        try:
            city_data = self.reader.city(ip).raw
        except:
            return data_loc
        
        dict_ = dict(
            location_city                       = ['city', 'names', self.country_name],
            location_continent                  = ['continent', 'names', self.country_name],
            location_continent_code             = ['continent', 'code'],
            location_country                    = ['country', 'names', self.country_name],
            location_country_isocode            = ['country', 'iso_code'],
            location_registered_country         = ['registered_country', 'names', self.country_name],
            location_registered_country_isocode = ['registered_country', 'iso_code'],
            location_latitude                   = ['location', 'latitude'],
            location_longitude                  = ['location', 'longitude'],
            location_timezone                   = ['location', 'time_zone'],
        )
        if city_data:
            for name, keys in dict_.items():
                data_loc[name] = self.get_data_by_key(city_data, keys)
        return data_loc

if __name__ == '__main__':
    from pprint import pprint
    geoip = GeoIP()
    pprint(geoip.get_ip_location_data("1.1.1.1"))
    pprint(geoip.get_ip_location_data("127.0.0.1"))

use Rust

toml
[dependencies]
maxminddb = "0.17"
serde_json = "1.0"
rust
use std::net::IpAddr;
use std::str::FromStr;
use maxminddb::geoip2;
use serde_json;

fn get_ip_location(ip_str: &str) -> Result<String, serde_json::Error> {
    let location = "./GeoLite2-City.mmdb";
    let reader = maxminddb::Reader::open_readfile(location).unwrap();
    let ip = IpAddr::from_str(ip_str).unwrap();
    let city: geoip2::City = reader.lookup(ip).unwrap();
    serde_json::to_string(&city)
}

fn main() -> Result<(), String> {
    println!("{:#?}", get_ip_location("8.8.8.8"));
    Ok(())
}

Released under the MIT License.