aicheckv2-api/utils/ip_manage.py

72 lines
2.4 KiB
Python
Raw Normal View History

2025-04-11 08:54:28 +08:00
#!/usr/bin/python
# -*- coding: utf-8 -*-
# @version : 1.0
# @Create Time : 2022/11/3 17:23
# @File : ip_manage.py
# @IDE : PyCharm
# @desc : 获取IP地址归属地
"""
文档https://user.ip138.com/ip/doc
IP查询第三方服务有1000次的免费次数
JSONP请求示例IPv4
https://api.ip138.com/ip/?ip=58.16.180.3&datatype=jsonp&token=cc87f3c77747bccbaaee35006da1ebb65e0bad57
aiohttp 异步请求文档https://docs.aiohttp.org/en/stable/client_quickstart.html
"""
from aiohttp import TCPConnector
from application.settings import IP_PARSE_TOKEN, IP_PARSE_ENABLE
import aiohttp
from core.logger import logger
from pydantic import BaseModel
from typing import Optional
class IPLocationOut(BaseModel):
ip: str | None = None
address: str | None = None
country: str | None = None
province: str | None = None
city: str | None = None
county: str | None = None
operator: str | None = None
postal_code: str | None = None
area_code: str | None = None
class IPManage:
def __init__(self, ip: str):
self.ip = ip
self.url = f"https://api.ip138.com/ip/?ip={ip}&datatype=jsonp&token={IP_PARSE_TOKEN}"
async def parse(self):
"""
IP 数据解析
接口返回{'ret': 'ok', 'ip': '114.222.121.253','data': ['中国', '江苏', '南京', '江宁区', '电信', '211100', '025']}
"""
out = IPLocationOut()
out.ip = self.ip
if not IP_PARSE_ENABLE:
logger.warning("未开启IP地址数据解析无法获取到IP所属地请在application/config/production.py:IP_PARSE_ENABLE中开启")
return out
async with aiohttp.ClientSession(connector=TCPConnector(ssl=False)) as session:
async with session.get(self.url) as resp:
body = await resp.json()
if body.get("ret") != 'ok':
logger.error(f"获取IP所属地失败{body}")
return out
data = body.get("data")
out.address = f"{''.join(data[i] for i in range(0, 4))} {data[4]}"
out.country = data[0]
out.province = data[1]
out.city = data[2]
out.county = data[3]
out.operator = data[4]
out.postal_code = data[5]
out.area_code = data[6]
return out