Redis клиент сменен с синхронного на ассинхронный

This commit is contained in:
2025-11-06 13:54:22 +03:00
parent 45af5e247c
commit 4dd1e4b1a6
3 changed files with 13 additions and 12 deletions

View File

@ -1,6 +1,6 @@
[project] [project]
name = "aiohttpx" name = "aiohttpx"
version = "1.1.0" version = "1.2.0"
description = "Custom HTTPX client with aiohttp transport, rate limiter and caching" description = "Custom HTTPX client with aiohttp transport, rate limiter and caching"
readme = "README.md" readme = "README.md"
authors = [ authors = [

View File

@ -2,9 +2,10 @@ from httpx import Request
from httpx import Response as HTTPXResponse from httpx import Response as HTTPXResponse
from httpx import _models as m # type: ignore from httpx import _models as m # type: ignore
from orjson import dumps, loads from orjson import dumps, loads
from redis.asyncio import Redis
from aiohttpx.responses import Response from aiohttpx.responses import Response
from aiohttpx.transports.rate_limiter import AsyncRateLimit, Redis from aiohttpx.transports.rate_limiter import AsyncRateLimit
def generate_cache_key(request: Request) -> str: def generate_cache_key(request: Request) -> str:
@ -15,7 +16,7 @@ def generate_cache_key(request: Request) -> str:
return f'cache:{hash(str(dumps(request_data)))}' return f'cache:{hash(str(dumps(request_data)))}'
def cache_response( async def cache_response(
client: Redis[bytes], client: Redis[bytes],
cache_key: str, cache_key: str,
request: Request, request: Request,
@ -25,7 +26,7 @@ def cache_response(
ttl = get_ttl_from_headers(request.headers) ttl = get_ttl_from_headers(request.headers)
if ttl: if ttl:
client.set(cache_key, serialized_response, ex=ttl) await client.set(cache_key, serialized_response, ex=ttl)
def get_ttl_from_headers(headers: m.Headers) -> int | None: def get_ttl_from_headers(headers: m.Headers) -> int | None:
@ -36,10 +37,10 @@ def get_ttl_from_headers(headers: m.Headers) -> int | None:
return None return None
def get_cached_response( async def get_cached_response(
client: Redis[bytes], cache_key: str client: Redis[bytes], cache_key: str
) -> Response | None: ) -> Response | None:
cached_data = client.get(cache_key) cached_data = await client.get(cache_key)
if cached_data: if cached_data:
return deserialize_response(cached_data) return deserialize_response(cached_data)
@ -83,13 +84,13 @@ class AsyncCacheTransport(AsyncRateLimit):
return await self.transport.handle_async_request(request) return await self.transport.handle_async_request(request)
cache_key = generate_cache_key(request) cache_key = generate_cache_key(request)
cached_response = get_cached_response(self.client, cache_key) cached_response = await get_cached_response(self.client, cache_key)
if cached_response: if cached_response:
return cached_response return cached_response
response = await self.transport.handle_async_request(request) response = await self.transport.handle_async_request(request)
cache_response(self.client, cache_key, request, response) await cache_response(self.client, cache_key, request, response)
return response return response

View File

@ -1,7 +1,7 @@
from asyncio import sleep as async_sleep from asyncio import sleep as async_sleep
from httpx import Request from httpx import Request
from redis import Redis from redis.asyncio import Redis
from aiohttpx.responses import Response from aiohttpx.responses import Response
from aiohttpx.transports.aio import AiohttpTransport from aiohttpx.transports.aio import AiohttpTransport
@ -30,14 +30,14 @@ class AsyncRateLimit(AiohttpTransport):
t: int = int(self.client.time()[0]) # type: ignore t: int = int(self.client.time()[0]) # type: ignore
separation = round(60 / self.limit) separation = round(60 / self.limit)
value = self.client.get(self.key) or t value = await self.client.get(self.key) or t
self.client.setnx(self.key, value) await self.client.setnx(self.key, value)
tat = max(int(value), t) tat = max(int(value), t)
if tat - t <= 60 - separation: if tat - t <= 60 - separation:
new_tat = max(tat, t) + separation new_tat = max(tat, t) + separation
self.client.set(self.key, new_tat) await self.client.set(self.key, new_tat)
return False return False
return True return True