refactor(container): replace Request model with utils version

This commit is contained in:
ZhymabekRoman 2024-11-06 21:08:58 +05:00
parent 261f9955cc
commit 411095ceb0
12 changed files with 91 additions and 37 deletions

View file

@ -1,6 +1,6 @@
from dependency_injector import containers, providers
from freedium_library.models.request import Request
from freedium_library.utils.http import Request
class Container(containers.DeclarativeContainer):

View file

@ -1,3 +0,0 @@
from .request import Request
__all__ = ["Request"]

View file

@ -1,27 +1,69 @@
from abc import ABC, abstractmethod
from dependency_injector.wiring import Provide
from loguru import logger
from freedium_library.container import Container
from freedium_library.models.request import Request
from freedium_library.utils.http import Request
class BaseService(ABC):
def __init__(self, request: Request = Provide[Container.request]):
self.request = request
@abstractmethod
def _prepare(self):
pass
def is_valid(self, path: str) -> bool:
pass
with logger.contextualize(cls=str(self)):
return self._is_valid(path)
@abstractmethod
async def ais_valid(self, path: str) -> bool:
pass
with logger.contextualize(cls=str(self)):
return await self._ais_valid(path)
@abstractmethod
def render(self, path: str) -> str:
with logger.contextualize(cls=str(self)):
return self._render(path)
async def arender(self, path: str) -> str:
with logger.contextualize(cls=str(self)):
return await self._arender(path)
async def asearch(self, keywords: list[str]) -> list[dict[str, str]]:
with logger.contextualize(cls=str(self)):
return await self._asearch(keywords)
def search(self, keywords: list[str]) -> list[dict[str, str]]:
with logger.contextualize(cls=str(self)):
return self._search(keywords)
@abstractmethod
def _is_valid(self, path: str) -> bool:
pass
@abstractmethod
async def arender(self, path: str) -> str:
async def _ais_valid(self, path: str) -> bool:
pass
@abstractmethod
def _render(self, path: str) -> str:
pass
@abstractmethod
async def _arender(self, path: str) -> str:
pass
@abstractmethod
async def _asearch(self, keywords: list[str]) -> list[dict]:
pass
@abstractmethod
def _search(self, keywords: list[str]) -> list[dict]:
pass
def __str__(self) -> str:
return self.__class__.__name__
def __repr__(self) -> str:
return f"{self.__class__.__name__}()"

View file

@ -14,7 +14,7 @@ from .models import MediumPostDataResponse
from .validators import MediumServicePathValidator
if TYPE_CHECKING:
from freedium_library.models.request import Request
from freedium_library.utils.http import Request
class MediumService(BaseService):
@ -31,27 +31,27 @@ class MediumService(BaseService):
self.path_validator = path_validator
_content: Optional[str] = None
def is_valid(self, path: str) -> bool:
def _is_valid(self, path: str) -> bool:
return self.path_validator.is_valid(path)
async def ais_valid(self, path: str) -> bool:
async def _ais_valid(self, path: str) -> bool:
return await self.path_validator.ais_valid(path)
def render(self, path: str) -> str:
if not self.is_valid(path):
def _render(self, path: str) -> str:
if not self._is_valid(path):
raise InvalidMediumServicePathError("Invalid Medium URL")
response = self.request.get(self._url)
response = self.request.get(path)
response_json = response.json()
_model = self._process_response(response_json)
_content = self._process_content(_model)
return _content
async def arender(self, path: str) -> str:
if not await self.ais_valid(path):
async def _arender(self, path: str) -> str:
if not await self._ais_valid(path):
raise InvalidMediumServicePathError("Invalid Medium URL")
response = await self.request.aget(self._url)
response = await self.request.aget(path)
_model = self._process_response(response.json())
_content = self._process_content(_model)
return _content
@ -61,7 +61,3 @@ class MediumService(BaseService):
def _process_content(self, data: MediumPostDataResponse) -> str:
return "data"
def set_url(self, url: str) -> None:
self._url = url
_content = None

View file

@ -8,10 +8,10 @@ from dependency_injector.wiring import Provide
from loguru import logger
from freedium_library.container import Container
from freedium_library.utils import URLProcessor
from freedium_library.utils.http import URLProcessor
if TYPE_CHECKING:
from freedium_library.models.request import Request
from freedium_library.utils.http import Request
from .api import MediumApiService
@ -49,7 +49,7 @@ class _MediumServiceURLValidator:
self.request = request
self.hash_validator = hash_validator
def is_valid(self, url: str) -> bool: ...
def is_valid(self, url: str | URLProcessor) -> bool: ...
def _get_short_link_request_params(
self, short_url_id: str

View file

@ -2,12 +2,12 @@ from unittest.mock import AsyncMock, Mock
import pytest
from freedium_library.models.request import Request
from freedium_library.services.medium.api import MediumApiService
from freedium_library.services.medium.validators import (
_MediumServiceHashesValidator, # type: ignore
_MediumServiceURLValidator, # type: ignore
)
from freedium_library.utils.http import Request
@pytest.fixture

View file

@ -0,0 +1,4 @@
from .client import Request, RequestConfig
from .url import URLProcessor
__all__ = ["Request", "URLProcessor", "RequestConfig"]

View file

@ -1,10 +1,9 @@
from typing import Any, Literal, Optional
import pytest
from httpx import Response
from pytest_httpx import HTTPXMock
from freedium_library.models.request import Request, RequestConfig
from freedium_library.utils.http.client import Request, RequestConfig
@pytest.fixture
@ -51,7 +50,7 @@ async def test_async_context_manager(
@pytest.mark.asyncio
async def test_async_without_context_manager(
httpx_mock: HTTPXMock, mock_response: Response
httpx_mock: HTTPXMock, mock_response: dict[str, Any]
):
httpx_mock.add_response(**mock_response)
@ -312,7 +311,10 @@ async def test_invalid_json_response_async(
def test_closed_context_manager_access(httpx_mock: HTTPXMock):
mock_response_json = {"test": "hahaha"}
httpx_mock.add_response(json=mock_response_json)
mock_headers = {"Content-Type": "application/json"}
httpx_mock.add_response(
json=mock_response_json, headers=mock_headers, status_code=200
)
client = Request()
with client:
@ -320,7 +322,12 @@ def test_closed_context_manager_access(httpx_mock: HTTPXMock):
response = client.get("https://api.example.com/data")
assert response.is_closed is True
response.json() == mock_response_json
assert response.json() == mock_response_json
assert response.status_code == 200
assert response.headers["Content-Type"] == "application/json"
assert response.text == '{"test": "hahaha"}'
assert response.request.method == "GET"
assert str(response.request.url) == "https://api.example.com/data"
response.close()
assert response.is_closed
@ -329,7 +336,10 @@ def test_closed_context_manager_access(httpx_mock: HTTPXMock):
@pytest.mark.asyncio
async def test_closed_context_manager_access_async(httpx_mock: HTTPXMock):
mock_response_json = {"test": "hahaha"}
httpx_mock.add_response(json=mock_response_json)
mock_headers = {"Content-Type": "application/json"}
httpx_mock.add_response(
json=mock_response_json, headers=mock_headers, status_code=200
)
client = Request()
with client:
@ -337,7 +347,12 @@ async def test_closed_context_manager_access_async(httpx_mock: HTTPXMock):
response = await client.aget("https://api.example.com/data")
assert response.is_closed is True
response.json() == mock_response_json
assert response.json() == mock_response_json
assert response.status_code == 200
assert response.headers["Content-Type"] == "application/json"
assert response.text == '{"test": "hahaha"}'
assert response.request.method == "GET"
assert str(response.request.url) == "https://api.example.com/data"
response.aclose()
await response.aclose()
assert response.is_closed

View file

@ -1,6 +1,6 @@
import pytest
from freedium_library.utils import URLProcessor
from freedium_library.utils.http import URLProcessor
class TestUnWwwify: