Skip to content

Commit

Permalink
Merge pull request #38 from reagento/refactor/setup_ci
Browse files Browse the repository at this point in the history
pyproject.toml, ruff
  • Loading branch information
Tishka17 authored Jul 27, 2024
2 parents 448746d + 508ccf1 commit 92c7203
Show file tree
Hide file tree
Showing 23 changed files with 188 additions and 96 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/setup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install '.' -r requirements_dev.txt
- name: Run ruff
run: |
ruff check .
- name: Run tests
run: |
pytest
42 changes: 42 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
line-length = 79
target-version="py38"
src = ["src"]

include = ["src/**.py", "tests/**.py"]
exclude = ["src/dishka/_adaptix/**"]

lint.select = [
"ALL"
]
lint.ignore = [
"ARG",
"ANN",
"D",
"EM101",
"EM102",
"PT001",
"PT023",
"SIM108",
"SIM114",
"TRY003",
"PLW2901",
"RET505",
"RET506",
"PLR0913",
"UP038",
"TCH001",
"FA100",
# tempraty disabled
"PGH005",
"PLR2004",
"N818", # compatibility issue
]

[lint.per-file-ignores]
"tests/**" = ["TID252", "PLR2004", "S101", "A002"]

[lint.isort]
no-lines-before = ["local-folder"]

[lint.flake8-tidy-imports]
ban-relative-imports = "parents"
38 changes: 38 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[build-system]
requires = ["setuptools>=66.0"]
build-backend = "setuptools.build_meta"

[tool.setuptools]
include-package-data = true

[tool.setuptools.packages.find]
where = ["src"]

[project]
name = "dataclass_rest"
version = "0.4"
readme = "README.md"
authors = [
{ name = "Andrey Tikhonov", email = "[email protected]" },
]
license = { text = "Apache-2.0" }
description = "An utility for writing simple clients for REST like APIs"
requires-python = ">=3.8"
classifiers = [
"Programming Language :: Python :: 3",
"Topic :: Software Development :: Libraries",
"Typing :: Typed",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
]
dependencies = [
"adaptix",
]

[project.urls]
"Source" = "https://github.com/reagento/dataclass-rest"
"Homepage" = "https://github.com/reagento/dataclass-rest"
"Bug Tracker" = "https://github.com/reagento/dataclass-rest/issues"


4 changes: 3 additions & 1 deletion requirements_dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ requests
requests-mock
mypy
pytest
pytest-asyncio
pytest-asyncio

ruff==0.5.*
37 changes: 0 additions & 37 deletions setup.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
]

from .http_request import File
from .rest import rest, get, put, post, patch, delete
from .rest import delete, get, patch, post, put, rest
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from adaptix import Retort

from .client_protocol import (
ClientProtocol, FactoryProtocol,
ClientProtocol,
FactoryProtocol,
)


Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from abc import ABC, abstractmethod
from inspect import getcallargs
from logging import getLogger
from typing import Dict, Any, Callable, Optional, NoReturn, Type
from typing import Any, Callable, Dict, NoReturn, Optional, Type

from .client_protocol import ClientProtocol, ClientMethodProtocol
from .exceptions import MalformedResponse
from .http_request import HttpRequest, File
from .client_protocol import ClientMethodProtocol, ClientProtocol
from .exceptions import ClientLibraryError, MalformedResponse
from .http_request import File, HttpRequest
from .methodspec import MethodSpec

logger = getLogger(__name__)
Expand Down Expand Up @@ -74,7 +74,7 @@ def __call__(self, *args, **kwargs):
raise NotImplementedError

def _on_error_default(self, response: Any) -> Any:
raise RuntimeError # TODO exceptions
raise ClientLibraryError


class SyncMethod(BoundMethod):
Expand All @@ -90,8 +90,7 @@ def __call__(self, *args, **kwargs):
request = self._pre_process_request(request)
raw_response = self.client.do_request(request)
response = self._pre_process_response(raw_response)
response = self._post_process_response(response)
return response
return self._post_process_response(response)

def _pre_process_request(self, request: HttpRequest) -> HttpRequest:
return request
Expand Down Expand Up @@ -135,8 +134,7 @@ async def __call__(self, *args, **kwargs):
raw_response = await self.client.do_request(request)
response = await self._pre_process_response(raw_response)
await self._release_raw_response(raw_response)
response = await self._post_process_response(response)
return response
return await self._post_process_response(response)

async def _pre_process_request(self, request: HttpRequest) -> HttpRequest:
return request
Expand All @@ -162,7 +160,7 @@ async def _pre_process_response(self, response: Any) -> Any:
raise MalformedResponse from e

async def _on_error_default(self, response: Any) -> NoReturn:
raise RuntimeError # TODO exceptions
raise ClientLibraryError

@abstractmethod
async def _response_body(self, response: Any) -> Any:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
from typing import (
Protocol, Any, Optional, Callable, Type, runtime_checkable, TypeVar,
Any,
Callable,
Optional,
Protocol,
Type,
TypeVar,
runtime_checkable,
)

from .http_request import HttpRequest
Expand All @@ -18,7 +24,9 @@ class FactoryProtocol(Protocol):
def load(self, data: Any, class_: Type[TypeT]) -> TypeT:
raise NotImplementedError

def dump(self, data: TypeT, class_: Type[TypeT] = None) -> Any:
def dump(
self, data: TypeT, class_: Optional[Type[TypeT]] = None,
) -> Any:
raise NotImplementedError


Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,22 @@

from aiohttp import FormData
from aiohttp.client import (
ClientResponse, ClientSession, ClientError as AioHttpClientError,
ClientError as AioHttpClientError,
)
from aiohttp.client import (
ClientResponse,
ClientSession,
)

from ..base_client import BaseClient
from ..boundmethod import AsyncMethod
from ..exceptions import (
ClientError, ClientLibraryError, ServerError, MalformedResponse,
from dataclass_rest.base_client import BaseClient
from dataclass_rest.boundmethod import AsyncMethod
from dataclass_rest.exceptions import (
ClientError,
ClientLibraryError,
MalformedResponse,
ServerError,
)
from ..http_request import HttpRequest
from dataclass_rest.http_request import HttpRequest


class AiohttpMethod(AsyncMethod):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
from json import JSONDecodeError
from typing import Any, Optional, Tuple

from requests import Session, Response, RequestException
from requests import RequestException, Response, Session

from ..base_client import BaseClient
from ..boundmethod import SyncMethod
from ..exceptions import (
ClientLibraryError, ClientError, ServerError, MalformedResponse,
from dataclass_rest.base_client import BaseClient
from dataclass_rest.boundmethod import SyncMethod
from dataclass_rest.exceptions import (
ClientError,
ClientLibraryError,
MalformedResponse,
ServerError,
)
from ..http_request import HttpRequest, File
from dataclass_rest.http_request import File, HttpRequest


class RequestsMethod(SyncMethod):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from dataclasses import dataclass
from typing import Any, Dict, Union, IO, Optional
from typing import IO, Any, Dict, Optional, Union


@dataclass
Expand Down
2 changes: 1 addition & 1 deletion dataclass_rest/method.py → src/dataclass_rest/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __set_name__(self, owner, name):
f"No type for bound method is specified. "
f"Provide either `{owner.__name__}.method_class` attribute or "
f"`method_class=` argument for decorator "
f"on your `{name}` method"
f"on your `{name}` method",
)

def __get__(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from typing import Any, Dict, Type, Callable, List
from typing import Any, Callable, Dict, List, Type


class MethodSpec:
def __init__(
self,
func: Callable,
*,
url_template: str,
http_method: str,
response_type: Type,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import string
from inspect import getfullargspec, FullArgSpec, isclass
from typing import Callable, List, Sequence, Any, Type, TypedDict, Dict
from inspect import FullArgSpec, getfullargspec, isclass
from typing import Any, Callable, Dict, List, Sequence, Type, TypedDict

from .http_request import File
from .methodspec import MethodSpec
Expand Down Expand Up @@ -53,6 +53,7 @@ def get_file_params(spec):

def parse_func(
func: Callable,
*,
method: str,
url_template: str,
additional_params: Dict[str, Any],
Expand Down
Empty file added src/dataclass_rest/py.typed
Empty file.
File renamed without changes.
5 changes: 4 additions & 1 deletion tests/requests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@

from dataclass_rest.http import requests


@pytest.fixture
def session():
return requests.Session()


@pytest.fixture
def mocker(session):
with requests_mock.Mocker(session=session, case_sensitive=True) as session_mock:
with requests_mock.Mocker(
session=session, case_sensitive=True,
) as session_mock:
yield session_mock
11 changes: 7 additions & 4 deletions tests/requests/test_factory.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from dataclasses import dataclass
from enum import Enum

from adaptix import Retort, NameStyle, name_mapping
from adaptix import NameStyle, Retort, name_mapping

from dataclass_rest import patch
from dataclass_rest.http.requests import RequestsClient
Expand Down Expand Up @@ -43,7 +43,7 @@ def _init_response_body_factory(self) -> Retort:

@patch("/post/")
def post_x(self, long_param: str, body: RequestBody) -> ResponseBody:
raise NotImplementedError()
raise NotImplementedError

mocker.patch(
url="http://example.com/post/?LONG.PARAM=hello",
Expand All @@ -52,8 +52,11 @@ def post_x(self, long_param: str, body: RequestBody) -> ResponseBody:
)
client = Api(base_url="http://example.com", session=session)
result = client.post_x(
long_param="hello", body=RequestBody(int_param=42, selection=Selection.ONE),
long_param="hello",
body=RequestBody(int_param=42, selection=Selection.ONE),
)
assert result == ResponseBody(int_param=1, selection=Selection.TWO)
assert mocker.called_once
assert mocker.request_history[0].json() == {"intParam": 42, "selection": "ONE"}

resp = mocker.request_history[0].json()
assert resp == {"intParam": 42, "selection": "ONE"}
Loading

0 comments on commit 92c7203

Please sign in to comment.