fix: add async cache to async operations and sync cache (stdlib) for sync operations
This commit is contained in:
@@ -6,6 +6,7 @@ readme = "README.md"
|
|||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aiofiles>=25.1.0",
|
"aiofiles>=25.1.0",
|
||||||
|
"async-lru>=2.3.0",
|
||||||
"bs4>=0.0.2",
|
"bs4>=0.0.2",
|
||||||
"fastapi>=0.136.3",
|
"fastapi>=0.136.3",
|
||||||
"httpx>=0.28.1",
|
"httpx>=0.28.1",
|
||||||
|
|||||||
+17
-8
@@ -3,12 +3,15 @@ from typing import Optional, Dict, Any, Tuple
|
|||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
from fastapi import APIRouter, Request
|
from fastapi import APIRouter, Request
|
||||||
from functools import lru_cache
|
|
||||||
|
|
||||||
from httpx import AsyncClient
|
from httpx import AsyncClient
|
||||||
|
from async_lru import alru_cache
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
@@ -64,6 +67,7 @@ class IPInfo:
|
|||||||
def __init__(self, html: str):
|
def __init__(self, html: str):
|
||||||
self._data = self._parse(html)
|
self._data = self._parse(html)
|
||||||
|
|
||||||
|
@lru_cache(maxsize=1000)
|
||||||
def _parse(self, html: str) -> Optional[IPInfoModel]:
|
def _parse(self, html: str) -> Optional[IPInfoModel]:
|
||||||
"""Парсит HTML и возвращает модель"""
|
"""Парсит HTML и возвращает модель"""
|
||||||
soup = BeautifulSoup(html, 'html.parser')
|
soup = BeautifulSoup(html, 'html.parser')
|
||||||
@@ -168,7 +172,14 @@ class IPInfo:
|
|||||||
router = APIRouter(prefix='/api/v1', tags=['ip'])
|
router = APIRouter(prefix='/api/v1', tags=['ip'])
|
||||||
|
|
||||||
|
|
||||||
@lru_cache
|
@alru_cache(maxsize=1000, ttl=86400)
|
||||||
|
async def get_ip_info(ip: str, user_agent: str):
|
||||||
|
"""Асинхронная функция для получения информации об IP с кешированием."""
|
||||||
|
async with AsyncClient(headers={'User-Agent': user_agent}) as client:
|
||||||
|
response = await client.get(f'https://ipinfo.io/{ip}')
|
||||||
|
return response.text
|
||||||
|
|
||||||
|
|
||||||
@router.get('/ip')
|
@router.get('/ip')
|
||||||
async def get_ip(request: Request):
|
async def get_ip(request: Request):
|
||||||
forwarded = request.headers.get('X-Forwarded-For')
|
forwarded = request.headers.get('X-Forwarded-For')
|
||||||
@@ -180,11 +191,9 @@ async def get_ip(request: Request):
|
|||||||
else:
|
else:
|
||||||
client_ip = request.client.host
|
client_ip = request.client.host
|
||||||
|
|
||||||
async with AsyncClient(headers={'User-Agent': user_agent}) as client:
|
html = await get_ip_info(client_ip, user_agent)
|
||||||
response = await client.get(f'https://ipinfo.io/{client_ip}')
|
|
||||||
|
|
||||||
html = response.text
|
result = await asyncio.to_thread(lambda: IPInfo(html).dict())
|
||||||
ipinfo = IPInfo(html)
|
logging.info(result)
|
||||||
logging.info(ipinfo._data)
|
|
||||||
|
|
||||||
return ipinfo.dict()
|
return result
|
||||||
+8
-7
@@ -1,15 +1,16 @@
|
|||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
from functools import lru_cache
|
import aiofiles
|
||||||
import json
|
import json
|
||||||
import asyncio
|
from async_lru import alru_cache
|
||||||
|
|
||||||
router = APIRouter(prefix='/api/v1', tags=['tariffs'])
|
router = APIRouter(prefix='/api/v1', tags=['tariffs'])
|
||||||
|
|
||||||
@lru_cache(maxsize=1)
|
@alru_cache(maxsize=1, ttl=86400)
|
||||||
def get_tariffs_sync():
|
async def get_tariffs_sync():
|
||||||
with open('data/tariffs.json', 'r', encoding='utf-8') as f:
|
async with aiofiles.open('data/tariffs.json', 'r', encoding='utf-8') as f:
|
||||||
return json.load(f)
|
content = await f.read()
|
||||||
|
return json.loads(content)
|
||||||
|
|
||||||
@router.get('/tariffs')
|
@router.get('/tariffs')
|
||||||
async def get_tariffs():
|
async def get_tariffs():
|
||||||
return await asyncio.to_thread(get_tariffs_sync)
|
return await get_tariffs_sync()
|
||||||
@@ -47,6 +47,15 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" },
|
{ url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-lru"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/e8/1f/989ecfef8e64109a489fff357450cb73fa73a865a92bd8c272170a6922c2/async_lru-2.3.0.tar.gz", hash = "sha256:89bdb258a0140d7313cf8f4031d816a042202faa61d0ab310a0a538baa1c24b6", size = 16332, upload-time = "2026-03-19T01:04:32.413Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e5/e2/c2e3abf398f80732e58b03be77bde9022550d221dd8781bf586bd4d97cc1/async_lru-2.3.0-py3-none-any.whl", hash = "sha256:eea27b01841909316f2cc739807acea1c623df2be8c5cfad7583286397bb8315", size = 8403, upload-time = "2026-03-19T01:04:30.883Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "beautifulsoup4"
|
name = "beautifulsoup4"
|
||||||
version = "4.15.0"
|
version = "4.15.0"
|
||||||
@@ -889,10 +898,11 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uvpn-backend"
|
name = "uvpn-backend"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "aiofiles" },
|
{ name = "aiofiles" },
|
||||||
|
{ name = "async-lru" },
|
||||||
{ name = "bs4" },
|
{ name = "bs4" },
|
||||||
{ name = "fastapi" },
|
{ name = "fastapi" },
|
||||||
{ name = "httpx" },
|
{ name = "httpx" },
|
||||||
@@ -907,6 +917,7 @@ dev = [
|
|||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "aiofiles", specifier = ">=25.1.0" },
|
{ name = "aiofiles", specifier = ">=25.1.0" },
|
||||||
|
{ name = "async-lru", specifier = ">=2.3.0" },
|
||||||
{ name = "bs4", specifier = ">=0.0.2" },
|
{ name = "bs4", specifier = ">=0.0.2" },
|
||||||
{ name = "fastapi", specifier = ">=0.136.3" },
|
{ name = "fastapi", specifier = ">=0.136.3" },
|
||||||
{ name = "httpx", specifier = ">=0.28.1" },
|
{ name = "httpx", specifier = ">=0.28.1" },
|
||||||
|
|||||||
Reference in New Issue
Block a user