diff --git a/freedium-library/src/freedium_library/container.py b/freedium-library/src/freedium_library/container.py index 00150e9..802f023 100644 --- a/freedium-library/src/freedium_library/container.py +++ b/freedium-library/src/freedium_library/container.py @@ -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): diff --git a/freedium-library/src/freedium_library/models/__init__.py b/freedium-library/src/freedium_library/models/__init__.py index cb269ee..e69de29 100644 --- a/freedium-library/src/freedium_library/models/__init__.py +++ b/freedium-library/src/freedium_library/models/__init__.py @@ -1,3 +0,0 @@ -from .request import Request - -__all__ = ["Request"] diff --git a/freedium-library/src/freedium_library/services/base.py b/freedium-library/src/freedium_library/services/base.py index 8fa6523..7bd272c 100644 --- a/freedium-library/src/freedium_library/services/base.py +++ b/freedium-library/src/freedium_library/services/base.py @@ -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__}()" diff --git a/freedium-library/src/freedium_library/services/medium/medium.py b/freedium-library/src/freedium_library/services/medium/medium.py index 8f740db..1d91cf7 100644 --- a/freedium-library/src/freedium_library/services/medium/medium.py +++ b/freedium-library/src/freedium_library/services/medium/medium.py @@ -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 diff --git a/freedium-library/src/freedium_library/services/medium/validators.py b/freedium-library/src/freedium_library/services/medium/validators.py index c2ef38e..fcbf6eb 100644 --- a/freedium-library/src/freedium_library/services/medium/validators.py +++ b/freedium-library/src/freedium_library/services/medium/validators.py @@ -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 diff --git a/freedium-library/src/freedium_library/services/medium/validators_url_test.py b/freedium-library/src/freedium_library/services/medium/validators_url_test.py index ef5092b..15e9e12 100644 --- a/freedium-library/src/freedium_library/services/medium/validators_url_test.py +++ b/freedium-library/src/freedium_library/services/medium/validators_url_test.py @@ -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 diff --git a/freedium-library/src/freedium_library/utils/__init__.py b/freedium-library/src/freedium_library/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/freedium-library/src/freedium_library/utils/http/__init__.py b/freedium-library/src/freedium_library/utils/http/__init__.py new file mode 100644 index 0000000..cbda7b3 --- /dev/null +++ b/freedium-library/src/freedium_library/utils/http/__init__.py @@ -0,0 +1,4 @@ +from .client import Request, RequestConfig +from .url import URLProcessor + +__all__ = ["Request", "URLProcessor", "RequestConfig"] diff --git a/freedium-library/src/freedium_library/models/request.py b/freedium-library/src/freedium_library/utils/http/client.py similarity index 100% rename from freedium-library/src/freedium_library/models/request.py rename to freedium-library/src/freedium_library/utils/http/client.py diff --git a/freedium-library/src/freedium_library/models/test_request.py b/freedium-library/src/freedium_library/utils/http/client_test.py similarity index 89% rename from freedium-library/src/freedium_library/models/test_request.py rename to freedium-library/src/freedium_library/utils/http/client_test.py index 057863f..b7f19c0 100644 --- a/freedium-library/src/freedium_library/models/test_request.py +++ b/freedium-library/src/freedium_library/utils/http/client_test.py @@ -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 diff --git a/freedium-library/src/freedium_library/utils.py b/freedium-library/src/freedium_library/utils/http/url.py similarity index 100% rename from freedium-library/src/freedium_library/utils.py rename to freedium-library/src/freedium_library/utils/http/url.py diff --git a/freedium-library/src/freedium_library/utils_test.py b/freedium-library/src/freedium_library/utils/http/url_test.py similarity index 98% rename from freedium-library/src/freedium_library/utils_test.py rename to freedium-library/src/freedium_library/utils/http/url_test.py index 536dec7..be180e8 100644 --- a/freedium-library/src/freedium_library/utils_test.py +++ b/freedium-library/src/freedium_library/utils/http/url_test.py @@ -1,6 +1,6 @@ import pytest -from freedium_library.utils import URLProcessor +from freedium_library.utils.http import URLProcessor class TestUnWwwify: