Skip to content

Add ip location cache#205

Merged
wu-clan merged 3 commits into
fastapi-practices:masterfrom
downdawn:ip-location-cache
Aug 28, 2023
Merged

Add ip location cache#205
wu-clan merged 3 commits into
fastapi-practices:masterfrom
downdawn:ip-location-cache

Conversation

@downdawn

Copy link
Copy Markdown
Collaborator

No description provided.

@downdawn

Copy link
Copy Markdown
Collaborator Author

PLR.

@downdawn
downdawn requested a review from wu-clan August 28, 2023 02:03

@wu-clan wu-clan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please update.

Comment thread backend/app/core/conf.py Outdated
Comment thread backend/app/utils/request_parse.py Outdated
Comment thread backend/app/utils/request_parse.py Outdated
@downdawn

Copy link
Copy Markdown
Collaborator Author
@sync_to_async
def get_location_offline(ip: str) -> dict | None:
    """
    离线获取 ip 地址属地,无法保证准确率,100%可用

    :param ip:
    :return:
    """
    try:
        cb = XdbSearcher.loadContentFromFile(dbfile=IP2REGION_XDB)
        searcher = XdbSearcher(contentBuff=cb)
        data = searcher.search(ip)
        searcher.close()
        data = data.split('|')
        return {'country': data[0], 'regionName': data[2], 'city': data[3]}
    except Exception as e:
        log.error(f'离线获取 ip 地址属地失败,错误信息:{e}')
        return None


async def parse_ip_info(request: Request) -> tuple[str, str, str, str]:
    country, region, city = None, None, None
    ip = await get_request_ip(request)
    location = await redis_client.get(f'{settings.IP_LOCATION_REDIS_PREFIX}:{ip}')
    if location:
        country, region, city = location.split(' ')
        return ip, country, region, city
    if settings.LOCATION_PARSE == 'online':
        location_info = await get_location_online(ip, request.headers.get('User-Agent'))
    elif settings.LOCATION_PARSE == 'offline':
        location_info = await get_location_offline(ip)
    else:
        location_info = None
    if location_info:
        country = location_info.get('country')
        region = location_info.get('regionName')
        city = location_info.get('city')
    await redis_client.set(f'{settings.IP_LOCATION_REDIS_PREFIX}:{ip}', f'{country} {region} {city}',
                           ex=settings.IP_LOCATION_EXPIRE_SECONDS)
    return ip, country, region, city

@wu-clan

wu-clan commented Aug 28, 2023

Copy link
Copy Markdown
Member

Is judgment being passed here?

# return {'country': data[0], 'regionName': data[2], 'city': data[3]}

country = location_info[0] if location_info[0] != '0' else None
region = location_info[2] if location_info[2] != '0' else None
city = location_info[3] if location_info[3] != '0' else None
return {'country': country, 'regionName': region, 'city': city}

Also, await redis_client.set() should be in if location_info:.

@downdawn

Copy link
Copy Markdown
Collaborator Author

Update.

@wu-clan wu-clan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@wu-clan
wu-clan merged commit 26d7492 into fastapi-practices:master Aug 28, 2023
chuxijin pushed a commit to chuxijin/fba that referenced this pull request Feb 8, 2026
* Add ip location cache

* Fix ip location cache

* Fix getting subscripts for offline locations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants