Simple FastAPI geolocation app

This commit is contained in:
Ruben van Staveren 2023-12-12 10:43:09 +01:00
parent 3bf89e4306
commit 4c4203a679
Signed by: ruben
GPG Key ID: 886F6BECD477A93F
2 changed files with 61 additions and 0 deletions

0
app/__init__.py Normal file
View File

61
app/main.py Normal file
View File

@ -0,0 +1,61 @@
'''
Simple Geolocation with FastAPI
'''
import dataclasses
from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network
from typing import Annotated, Optional, Union
import geoip2.database
from fastapi import FastAPI, Path
from pydantic import BaseModel
app = FastAPI()
GEOLITE2_ASN_DB = '/usr/local/share/GeoIP/GeoLite2-ASN.mmdb'
GEOLITE2_CITY_DB = '/usr/local/share/GeoIP/GeoLite2-City.mmdb'
@dataclasses.dataclass
class Locality(BaseModel):
'''
Locality data
'''
city: Optional[str]
country: Optional[str]
continent: Optional[str]
is_eu: bool
@dataclasses.dataclass
class GeoLocation(BaseModel):
'''
Geolocation data model
'''
ip: Union[IPv6Address,IPv4Address]
asn: Optional[int]
asn_org: Optional[str]
network: Union[IPv6Network,IPv4Network,None]
locality: Locality
@app.get("/{ipaddress}")
async def root(ipaddress: Annotated[Union[IPv4Address,IPv6Address],
Path(title="The IPAddress to geolocate")]
) -> GeoLocation:
'''
Look up geolocation for ip in path parameter
'''
with (geoip2.database.Reader(GEOLITE2_ASN_DB) as reader_asn,
geoip2.database.Reader(GEOLITE2_CITY_DB) as reader_city):
asn_data = reader_asn.asn(ipaddress)
city_data = reader_city.city(ipaddress)
return GeoLocation(
ip=ipaddress,
asn=asn_data.autonomous_system_number,
asn_org=asn_data.autonomous_system_organization,
network=asn_data.network,
locality=Locality(
city=city_data.city.name,
country=city_data.country.iso_code,
continent=city_data.continent.code,
is_eu=city_data.country.is_in_european_union
)
)