LoginSignup
1
0
お題は不問!Qiita Engineer Festa 2023で記事投稿!

GeoIP2のデータベースを手に入れたのでgradioで描画しpythonanywhereを使おうとしたけどreder.comでデプロイした話

Posted at

試したい方はこちらから
https://geoip2-demo.onrender.com/

データベースの入手

データベースは無料で入手できますが、登録が必要です。
まずは以下からサインアップしてください。

登録には以下のフォームを埋める必要がありますが、適当でも大丈夫です。すぐに使えるようになりました。

  • Full name
  • Company
  • Industry
  • Country Intended use
  • How you plan to use the geolocation data
  • Email address Please provide a valid email address. This will become your username.
  • Phone (optional)
  • How do you plan to use the data?

メールアドレスにパスワード設定のメールが来るのでパスワードを設定します。

そしてデータベースをダウンロードします。

gradioで描画する

gradioとgeoip2をインストールします。

pip install gradio geoip2

IPアドレスのASを知るデータベースとどこにIPアドレスがあるかのデータベースは別れていますので別々に読み込みます。
subdivisionsはあったりなかったり、あっても日本語がなかったりします。なかったら英語を使うようにします。

import geoip2.database
import gradio as gr

asn_db = "./GeoLite2-ASN.mmdb"
city_db = "./GeoLite2-City.mmdb"


def get_asn(ip_address: str):
    with geoip2.database.Reader(asn_db) as reader:
        return reader.asn(ip_address)


def get_city(ip_address: str):
    with geoip2.database.Reader(city_db) as reader:
        return reader.city(ip_address)


def main(ip_address):
    asn = get_asn(ip_address)
    city = get_city(ip_address)
    return {
        "AS管理組織": asn.autonomous_system_organization,
        "大陸": city.continent.names["ja"],
        "": city.country.names["ja"],
        "緯度": city.location.latitude,
        "経度": city.location.longitude,
        "精度": city.location.accuracy_radius,
        "登録国": city.registered_country.names["ja"],
        "細分": list(map(lambda x: x.names["ja"] or x.names["en"], city.subdivisions)),
        "IPアドレス": city.traits.ip_address,
    }

gradioで描画します。

demo = gr.Interface(fn=main, inputs="text", outputs="json")
demo.launch(share=True)

これで好きなIPアドレスを入れて遊ぶことができます。

これを早速pythonanywhereで動かそうと思いましたが以下の問題が発生しました。

  • gradioを直接動かしても反応がない
  • gradioにはgunicornの後ろで動かす方法がない
  • ならばfastapiの後ろで動かそうとしてもpythonanywhereではサポートしていない(https://www.pythonanywhere.com/forums/topic/32484/)

というわけで代替サービスを探したところrender.comにいきつきました。
ただこれもgradioを直接動かせないのでfastapiの後ろで動かします。

gradioのところをいかに書き直します。

from fastapi import FastAPI

app = FastAPI()

io = gr.Interface(fn=main, inputs="text", outputs="json")
app = gr.mount_gradio_app(app, io, path="/")

それでも以下のエラーが置きます。

"POST /run/predict HTTP/1.1" 422 Unprocessable Entity
{"detail":[{"type":"missing","loc":["body","event_id"],"msg":"Field required","input":{"data":["1.2.3.4"],"event_data":null,"fn_index":0,"session_hash":"w1mt4r43ag"},"url":"https://errors.pydantic.dev/2.1.2/v/missing"}]}

pydanticのバージョン違いのようです。

requirements.txtに以下を追記します。

pydantic==1.10.11

最終的なコードは以下のとおりです。

.
├── GeoLite2-ASN.mmdb
├── GeoLite2-City.mmdb
├── main.py
└── requirements.txt

main.py
import geoip2.database
import gradio as gr
from fastapi import FastAPI

asn_db='./GeoLite2-ASN.mmdb'
city_db='./GeoLite2-City.mmdb'

def get_asn(ip_address:str):
  with geoip2.database.Reader(asn_db) as reader:
    return reader.asn(ip_address)

def get_city(ip_address:str):
  with geoip2.database.Reader(city_db) as reader:
    return reader.city(ip_address)


def main(ip_address):
  asn=get_asn(ip_address)
  city=get_city(ip_address)
  return {
  "AS管理組織":asn.autonomous_system_organization, 
  "大陸":city.continent.names['ja'],
  "":city.country.names['ja'],  
  "緯度":city.location.latitude,
  "経度":city.location.longitude,
  "精度":city.location.accuracy_radius,
  "登録国":city.registered_country.names['ja'],
  "細分":list(map(lambda x:x.names['ja'] or x.names['en'],city.subdivisions)),
  "IPアドレス":city.traits.ip_address,
  }


app = FastAPI()

io = gr.Interface(fn=main, inputs="text", outputs="json")
app = gr.mount_gradio_app(app, io, path="/")
requirements.txt
pydantic==1.10.11
geoip2
gradio
fastapi
uvicorn

render.comの設定には名前を入力し、Start Commandには以下のコマンドを入れて、その他はデフォルトにしてください。

uvicorn main:app --host 0.0.0.0

image.png

デプロイするとgradioが使えるようになります。

image.png

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0