Browse Source

precommit

jelle.prins 1 year ago
parent
commit
fb7cf09ad6
40 changed files with 269 additions and 156 deletions
  1. 6 6
      README.md
  2. 17 16
      clean_python/__init__.py
  3. 11 4
      clean_python/base/application/manage.py
  4. 3 1
      clean_python/base/domain/domain_event.py
  5. 5 2
      clean_python/base/domain/exceptions.py
  6. 4 1
      clean_python/base/domain/pagination.py
  7. 12 3
      clean_python/base/domain/repository.py
  8. 4 2
      clean_python/base/domain/root_entity.py
  9. 5 2
      clean_python/base/domain/value_object.py
  10. 9 3
      clean_python/base/infrastructure/gateway.py
  11. 9 4
      clean_python/base/infrastructure/internal_gateway.py
  12. 2 1
      clean_python/base/infrastructure/now.py
  13. 2 1
      clean_python/celery/celery_rmq_broker.py
  14. 7 2
      clean_python/dramatiq/async_actor.py
  15. 5 3
      clean_python/dramatiq/dramatiq_task_logger.py
  16. 7 8
      clean_python/fastapi/error_responses.py
  17. 4 2
      clean_python/fastapi/fastapi_access_logger.py
  18. 1 1
      clean_python/fastapi/request_query.py
  19. 7 1
      clean_python/fastapi/resource.py
  20. 33 19
      clean_python/fastapi/service.py
  21. 2 1
      clean_python/fluentbit/fluentbit_gateway.py
  22. 6 3
      clean_python/oauth2/oauth2.py
  23. 24 6
      clean_python/sql/sql_gateway.py
  24. 7 3
      clean_python/sql/sql_provider.py
  25. 2 2
      pytest.ini
  26. 4 6
      tests/test_async_actor.py
  27. 1 1
      tests/test_dramatiq_task_logger.py
  28. 2 1
      tests/test_exceptions.py
  29. 4 2
      tests/test_fastapi_access_logger.py
  30. 8 9
      tests/test_gateway.py
  31. 7 9
      tests/test_internal_gateway.py
  32. 3 1
      tests/test_manage.py
  33. 3 1
      tests/test_oauth2.py
  34. 8 10
      tests/test_repository.py
  35. 1 1
      tests/test_request_query.py
  36. 5 1
      tests/test_resource.py
  37. 5 2
      tests/test_root_entity.py
  38. 3 1
      tests/test_service.py
  39. 17 12
      tests/test_sql_gateway.py
  40. 4 2
      tests/test_value_object.py

+ 6 - 6
README.md

@@ -19,7 +19,7 @@ A big inspiration for this was the ``easy`` typescript framework by S. Hoogendoo
 The main goals of using layered architecture is isolating the domain-specific concepts from
 other functions related only to software technology. In this way:
 
-- The knowledge embedded in the domain is distilled and can more easily be 
+- The knowledge embedded in the domain is distilled and can more easily be
   understood and changed.
 - Developers are able to quickly grasp the code base because it uses
   a consistent structure and naming system.
@@ -31,7 +31,7 @@ Layers are loosly coupled with dependencies in only one direction: presentation
 
 A module may only depend on another module though its infrastructure layer. See ``InternalGateway``.
 
-This library was initially developed as a web backend using FastAPI. Its core dependency is ``pydantic``, 
+This library was initially developed as a web backend using FastAPI. Its core dependency is ``pydantic``,
 for strict type parsing and validation. Optional dependencies may be added as needed.
 
 ## Core concepts
@@ -40,7 +40,7 @@ for strict type parsing and validation. Optional dependencies may be added as ne
 
 The domain layer is where the model lives. The domain model is a set of concepts; the domain layer
 is the manifestation of that model. Concepts in the domain model must have a 1:1 representation in the
-code and vice versa. 
+code and vice versa.
 
 THe layer does not depend on all other layers. Interaction with the infrastructure layer may be done
 using dependency injection from the application layer. It is allowable to have runtime dependencies on the
@@ -49,14 +49,14 @@ infrastructure layer to set for instance default ``Gateway`` implementations.
 There are 5 kinds of objects in this layer:
 
 - *Entity*: Types that have an identity (all attributes of an instance may change- but the instance is still the same)
-  Entities have an ``id`` and default fields associated with state changes ()``created_at``, ``updated_at``). 
+  Entities have an ``id`` and default fields associated with state changes ()``created_at``, ``updated_at``).
 - *ValueObject*: Types that have no identity (these are just complex values like a datetime).
 - *DomainService*: Important domain operations that aren't natural to model as objects. A service is stateless.
 - *Repository*: A repository is responsible for persistence (``add`` / ``get`` / ``filter``). This needs
   a *Gateway* to interface with e.g. a database; an instance of a *Gateway* is typically injected into a
   Repository from the application layer.
 - *DomainEvent*: A domain event may be emitted to signal a state change.
-  
+
 Associations between objects are hard. Especially many-to-many relations. We approach this by grouping objects
 into *aggregates*. An aggregate is a set of objects that change together / have the same lifecycle (e.g. delete together). One entity is the aggregate root; we call this the ``RootEntity``. A ``ChildEntity`` occurs only very
 rarely; mostly a nested object derive its identity from a ``RootEntity``.
@@ -81,7 +81,7 @@ the business of the presentation layer.
 In addition to directing the domain objects, an application layer method could trigger other behavior
 like logging or triggering other applications. At first, it may as well be just a single function call.
 
-This layer is kept thin. It directs domain objects, and possibly interacts with other systems 
+This layer is kept thin. It directs domain objects, and possibly interacts with other systems
 (for instance by sending a message through the infrastructure layer). The application layer should
 not contain fundamental domain rules.
 

+ 17 - 16
clean_python/__init__.py

@@ -1,30 +1,31 @@
 # -*- coding: utf-8 -*-
 # (c) Nelen & Schuurmans
 
-from .dramatiq.async_actor import *  # NOQA
-from .testing.attr_dict import AttrDict  # NOQA
-from .celery.celery_rmq_broker import *  # NOQA
-from .fastapi.context import *  # NOQA
+from .base.application.manage import Manage  # NOQA
 from .base.domain.domain_event import *  # NOQA
 from .base.domain.domain_service import DomainService  # NOQA
-from .dramatiq.dramatiq_task_logger import *  # NOQA
 from .base.domain.exceptions import *  # NOQA
-from .fastapi.fastapi_access_logger import *  # NOQA
-from .fluentbit.fluentbit_gateway import FluentbitGateway  # NOQA
+from .base.domain.pagination import *  # NOQA
+from .base.domain.repository import Repository  # NOQA
+from .base.domain.root_entity import RootEntity  # NOQA
+from .base.domain.value import Value  # NOQA
+from .base.domain.value_object import ValueObject  # NOQA
+from .base.domain.value_object import ValueObjectWithId  # NOQA
 from .base.infrastructure.gateway import *  # NOQA
 from .base.infrastructure.internal_gateway import InternalGateway  # NOQA
-from .base.presentation.link import Link  # NOQA
-from .base.application.manage import Manage  # NOQA
 from .base.infrastructure.now import now  # NOQA
-from .oauth2.oauth2 import *  # NOQA
-from .base.domain.pagination import *  # NOQA
-from .base.domain.repository import Repository  # NOQA
+from .base.infrastructure.tmpdir_provider import *  # NOQA
+from .base.presentation.link import Link  # NOQA
+from .celery.celery_rmq_broker import *  # NOQA
+from .dramatiq.async_actor import *  # NOQA
+from .dramatiq.dramatiq_task_logger import *  # NOQA
+from .fastapi.context import *  # NOQA
+from .fastapi.fastapi_access_logger import *  # NOQA
 from .fastapi.request_query import *  # NOQA
 from .fastapi.resource import *  # NOQA
-from .base.domain.root_entity import RootEntity  # NOQA
 from .fastapi.service import Service  # NOQA
+from .fluentbit.fluentbit_gateway import FluentbitGateway  # NOQA
+from .oauth2.oauth2 import *  # NOQA
 from .sql.sql_gateway import SQLGateway  # NOQA
 from .sql.sql_provider import *  # NOQA
-from .base.infrastructure.tmpdir_provider import *  # NOQA
-from .base.domain.value import Value  # NOQA
-from .base.domain.value_object import ValueObject, ValueObjectWithId  # NOQA
+from .testing.attr_dict import AttrDict  # NOQA

+ 11 - 4
clean_python/base/application/manage.py

@@ -1,12 +1,19 @@
 # -*- coding: utf-8 -*-
 # (c) Nelen & Schuurmans
 
-from typing import Any, Generic, List, Optional, Type, TypeVar
-
-from clean_python.base.infrastructure.gateway import Filter, Json
-from clean_python.base.domain.pagination import Page, PageOptions
+from typing import Any
+from typing import Generic
+from typing import List
+from typing import Optional
+from typing import Type
+from typing import TypeVar
+
+from clean_python.base.domain.pagination import Page
+from clean_python.base.domain.pagination import PageOptions
 from clean_python.base.domain.repository import Repository
 from clean_python.base.domain.root_entity import RootEntity
+from clean_python.base.infrastructure.gateway import Filter
+from clean_python.base.infrastructure.gateway import Json
 
 T = TypeVar("T", bound=RootEntity)
 

+ 3 - 1
clean_python/base/domain/domain_event.py

@@ -2,7 +2,9 @@
 # (c) Nelen & Schuurmans
 
 from abc import ABC
-from typing import Awaitable, Callable, TypeVar
+from typing import Awaitable
+from typing import Callable
+from typing import TypeVar
 
 import blinker
 

+ 5 - 2
clean_python/base/domain/exceptions.py

@@ -1,9 +1,12 @@
 # -*- coding: utf-8 -*-
 # (c) Nelen & Schuurmans
 
-from typing import Any, Optional, Union
+from typing import Any
+from typing import Optional
+from typing import Union
 
-from pydantic import create_model, ValidationError
+from pydantic import create_model
+from pydantic import ValidationError
 from pydantic.error_wrappers import ErrorWrapper
 
 __all__ = [

+ 4 - 1
clean_python/base/domain/pagination.py

@@ -1,7 +1,10 @@
 # -*- coding: utf-8 -*-
 # (c) Nelen & Schuurmans
 
-from typing import Generic, Optional, Sequence, TypeVar
+from typing import Generic
+from typing import Optional
+from typing import Sequence
+from typing import TypeVar
 
 from pydantic import BaseModel
 from pydantic.generics import GenericModel

+ 12 - 3
clean_python/base/domain/repository.py

@@ -1,12 +1,21 @@
 # -*- coding: utf-8 -*-
 # (c) Nelen & Schuurmans
 
-from typing import Any, Generic, List, Optional, Type, TypeVar, Union
+from typing import Any
+from typing import Generic
+from typing import List
+from typing import Optional
+from typing import Type
+from typing import TypeVar
+from typing import Union
 
 from clean_python.base.domain.exceptions import DoesNotExist
-from clean_python.base.infrastructure.gateway import Filter, Gateway, Json
-from clean_python.base.domain.pagination import Page, PageOptions
+from clean_python.base.domain.pagination import Page
+from clean_python.base.domain.pagination import PageOptions
 from clean_python.base.domain.root_entity import RootEntity
+from clean_python.base.infrastructure.gateway import Filter
+from clean_python.base.infrastructure.gateway import Gateway
+from clean_python.base.infrastructure.gateway import Json
 
 T = TypeVar("T", bound=RootEntity)
 

+ 4 - 2
clean_python/base/domain/root_entity.py

@@ -1,9 +1,11 @@
 from datetime import datetime
-from typing import Optional, Type, TypeVar
+from typing import Optional
+from typing import Type
+from typing import TypeVar
 
 from clean_python.base.domain.exceptions import BadRequest
-from clean_python.base.infrastructure.now import now
 from clean_python.base.domain.value_object import ValueObject
+from clean_python.base.infrastructure.now import now
 
 T = TypeVar("T", bound="RootEntity")
 

+ 5 - 2
clean_python/base/domain/value_object.py

@@ -1,6 +1,9 @@
-from typing import Optional, Type, TypeVar
+from typing import Optional
+from typing import Type
+from typing import TypeVar
 
-from pydantic import BaseModel, ValidationError
+from pydantic import BaseModel
+from pydantic import ValidationError
 
 from .exceptions import BadRequest
 

+ 9 - 3
clean_python/base/infrastructure/gateway.py

@@ -3,9 +3,15 @@
 
 from copy import deepcopy
 from datetime import datetime
-from typing import Any, Callable, Dict, List, Optional
-
-from clean_python.base.domain.exceptions import AlreadyExists, Conflict, DoesNotExist
+from typing import Any
+from typing import Callable
+from typing import Dict
+from typing import List
+from typing import Optional
+
+from clean_python.base.domain.exceptions import AlreadyExists
+from clean_python.base.domain.exceptions import Conflict
+from clean_python.base.domain.exceptions import DoesNotExist
 from clean_python.base.domain.pagination import PageOptions
 from clean_python.base.domain.value_object import ValueObject
 

+ 9 - 4
clean_python/base/infrastructure/internal_gateway.py

@@ -1,14 +1,19 @@
 # -*- coding: utf-8 -*-
 # (c) Nelen & Schuurmans
-from abc import abstractmethod, abstractproperty
-from typing import Generic, List, Optional, TypeVar
+from abc import abstractmethod
+from abc import abstractproperty
+from typing import Generic
+from typing import List
+from typing import Optional
+from typing import TypeVar
 
-from clean_python.base.domain.exceptions import BadRequest, DoesNotExist
-from clean_python.base.infrastructure.gateway import Filter
 from clean_python.base.application.manage import Manage
+from clean_python.base.domain.exceptions import BadRequest
+from clean_python.base.domain.exceptions import DoesNotExist
 from clean_python.base.domain.pagination import PageOptions
 from clean_python.base.domain.root_entity import RootEntity
 from clean_python.base.domain.value_object import ValueObject
+from clean_python.base.infrastructure.gateway import Filter
 
 E = TypeVar("E", bound=RootEntity)  # External
 T = TypeVar("T", bound=ValueObject)  # Internal

+ 2 - 1
clean_python/base/infrastructure/now.py

@@ -1,4 +1,5 @@
-from datetime import datetime, timezone
+from datetime import datetime
+from datetime import timezone
 
 
 def now():

+ 2 - 1
clean_python/celery/celery_rmq_broker.py

@@ -9,8 +9,9 @@ import pika
 from asgiref.sync import sync_to_async
 from pydantic import AnyUrl
 
-from clean_python.base.infrastructure.gateway import Gateway, Json
 from clean_python.base.domain.value_object import ValueObject
+from clean_python.base.infrastructure.gateway import Gateway
+from clean_python.base.infrastructure.gateway import Json
 
 __all__ = ["CeleryRmqBroker"]
 

+ 7 - 2
clean_python/dramatiq/async_actor.py

@@ -8,12 +8,17 @@ import logging
 import threading
 import time
 from concurrent.futures import TimeoutError
-from typing import Any, Awaitable, Dict, Optional, TypeVar
+from typing import Any
+from typing import Awaitable
+from typing import Dict
+from typing import Optional
+from typing import TypeVar
 
 import dramatiq
 from asgiref.sync import sync_to_async
 from dramatiq.brokers.stub import StubBroker
-from dramatiq.middleware import Interrupt, Middleware
+from dramatiq.middleware import Interrupt
+from dramatiq.middleware import Middleware
 
 __all__ = ["AsyncActor", "AsyncMiddleware", "async_actor"]
 

+ 5 - 3
clean_python/dramatiq/dramatiq_task_logger.py

@@ -4,13 +4,15 @@ import time
 from typing import Optional
 
 import inject
-from dramatiq import get_encoder, Middleware
-from dramatiq.errors import RateLimitExceeded, Retry
+from dramatiq import get_encoder
+from dramatiq import Middleware
+from dramatiq.errors import RateLimitExceeded
+from dramatiq.errors import Retry
 from dramatiq.message import Message
 from dramatiq.middleware import SkipMessage
 
-from clean_python.fluentbit.fluentbit_gateway import FluentbitGateway
 from clean_python.base.infrastructure.gateway import Gateway
+from clean_python.fluentbit.fluentbit_gateway import FluentbitGateway
 
 __all__ = ["AsyncLoggingMiddleware"]
 

+ 7 - 8
clean_python/fastapi/error_responses.py

@@ -1,17 +1,16 @@
-from typing import List, Union
+from typing import List
+from typing import Union
 
 from fastapi.encoders import jsonable_encoder
 from fastapi.requests import Request
 from fastapi.responses import JSONResponse
 from starlette import status
 
-from clean_python.base.domain.exceptions import (
-    BadRequest,
-    Conflict,
-    DoesNotExist,
-    PermissionDenied,
-    Unauthorized,
-)
+from clean_python.base.domain.exceptions import BadRequest
+from clean_python.base.domain.exceptions import Conflict
+from clean_python.base.domain.exceptions import DoesNotExist
+from clean_python.base.domain.exceptions import PermissionDenied
+from clean_python.base.domain.exceptions import Unauthorized
 from clean_python.base.domain.value_object import ValueObject
 
 __all__ = [

+ 4 - 2
clean_python/fastapi/fastapi_access_logger.py

@@ -1,15 +1,17 @@
 import os
 import time
 from datetime import datetime
-from typing import Awaitable, Callable, Optional
+from typing import Awaitable
+from typing import Callable
+from typing import Optional
 
 import inject
 from starlette.background import BackgroundTasks
 from starlette.requests import Request
 from starlette.responses import Response
 
-from clean_python.fluentbit.fluentbit_gateway import FluentbitGateway
 from clean_python.base.infrastructure.gateway import Gateway
+from clean_python.fluentbit.fluentbit_gateway import FluentbitGateway
 
 __all__ = ["FastAPIAccessLogger"]
 

+ 1 - 1
clean_python/fastapi/request_query.py

@@ -6,9 +6,9 @@ from typing import List
 from fastapi import Query
 from pydantic import validator
 
-from clean_python.base.infrastructure.gateway import Filter
 from clean_python.base.domain.pagination import PageOptions
 from clean_python.base.domain.value_object import ValueObject
+from clean_python.base.infrastructure.gateway import Filter
 
 __all__ = ["RequestQuery"]
 

+ 7 - 1
clean_python/fastapi/resource.py

@@ -1,6 +1,12 @@
 from enum import Enum
 from functools import partial
-from typing import Any, Callable, Dict, List, Optional, Sequence, Type
+from typing import Any
+from typing import Callable
+from typing import Dict
+from typing import List
+from typing import Optional
+from typing import Sequence
+from typing import Type
 
 from fastapi.routing import APIRouter
 

+ 33 - 19
clean_python/fastapi/service.py

@@ -1,30 +1,44 @@
 import logging
-from typing import Any, Callable, Dict, List, Optional, Set
+from typing import Any
+from typing import Callable
+from typing import Dict
+from typing import List
+from typing import Optional
+from typing import Set
 
 from asgiref.sync import sync_to_async
-from fastapi import Depends, FastAPI, Request
-from fastapi.exceptions import HTTPException, RequestValidationError
+from fastapi import Depends
+from fastapi import FastAPI
+from fastapi import Request
+from fastapi.exceptions import HTTPException
+from fastapi.exceptions import RequestValidationError
 from fastapi.security import OAuth2AuthorizationCodeBearer
-from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
+from starlette.status import HTTP_401_UNAUTHORIZED
+from starlette.status import HTTP_403_FORBIDDEN
 from starlette.types import ASGIApp
 
+from clean_python.base.domain.exceptions import Conflict
+from clean_python.base.domain.exceptions import DoesNotExist
+from clean_python.base.domain.exceptions import PermissionDenied
+from clean_python.base.domain.exceptions import Unauthorized
+from clean_python.base.infrastructure.gateway import Gateway
+from clean_python.oauth2.oauth2 import OAuth2AccessTokenVerifier
+from clean_python.oauth2.oauth2 import OAuth2Settings
+
 from .context import RequestMiddleware
-from .error_responses import (
-    BadRequest,
-    conflict_handler,
-    DefaultErrorResponse,
-    not_found_handler,
-    not_implemented_handler,
-    permission_denied_handler,
-    unauthorized_handler,
-    validation_error_handler,
-    ValidationErrorResponse,
-)
-from clean_python.base.domain.exceptions import Conflict, DoesNotExist, PermissionDenied, Unauthorized
+from .error_responses import BadRequest
+from .error_responses import conflict_handler
+from .error_responses import DefaultErrorResponse
+from .error_responses import not_found_handler
+from .error_responses import not_implemented_handler
+from .error_responses import permission_denied_handler
+from .error_responses import unauthorized_handler
+from .error_responses import validation_error_handler
+from .error_responses import ValidationErrorResponse
 from .fastapi_access_logger import FastAPIAccessLogger
-from clean_python.base.infrastructure.gateway import Gateway
-from clean_python.oauth2.oauth2 import OAuth2AccessTokenVerifier, OAuth2Settings
-from .resource import APIVersion, clean_resources, Resource
+from .resource import APIVersion
+from .resource import clean_resources
+from .resource import Resource
 
 logger = logging.getLogger(__name__)
 

+ 2 - 1
clean_python/fluentbit/fluentbit_gateway.py

@@ -1,7 +1,8 @@
 # -*- coding: utf-8 -*-
 # (c) Nelen & Schuurmans
 
-from typing import Any, Dict
+from typing import Any
+from typing import Dict
 
 from asgiref.sync import sync_to_async
 from fluent.sender import FluentSender

+ 6 - 3
clean_python/oauth2/oauth2.py

@@ -2,14 +2,17 @@
 # (c) Nelen & Schuurmans
 
 import logging
-from typing import Dict, List
+from typing import Dict
+from typing import List
 
 import jwt
 from jwt import PyJWKClient
 from jwt.exceptions import PyJWTError
-from pydantic import AnyHttpUrl, BaseModel
+from pydantic import AnyHttpUrl
+from pydantic import BaseModel
 
-from clean_python.base.domain.exceptions import PermissionDenied, Unauthorized
+from clean_python.base.domain.exceptions import PermissionDenied
+from clean_python.base.domain.exceptions import Unauthorized
 
 __all__ = ["OAuth2Settings", "OAuth2AccessTokenVerifier"]
 

+ 24 - 6
clean_python/sql/sql_gateway.py

@@ -2,19 +2,37 @@
 # (c) Nelen & Schuurmans
 from contextlib import asynccontextmanager
 from datetime import datetime
-from typing import AsyncIterator, Callable, List, Optional, TypeVar
+from typing import AsyncIterator
+from typing import Callable
+from typing import List
+from typing import Optional
+from typing import TypeVar
 
 import inject
-from sqlalchemy import asc, delete, desc, func, select, Table, true, update
+from sqlalchemy import asc
+from sqlalchemy import delete
+from sqlalchemy import desc
+from sqlalchemy import func
+from sqlalchemy import select
+from sqlalchemy import Table
+from sqlalchemy import true
+from sqlalchemy import update
 from sqlalchemy.dialects.postgresql import insert
 from sqlalchemy.exc import IntegrityError
 from sqlalchemy.sql import Executable
-from sqlalchemy.sql.expression import ColumnElement, false
+from sqlalchemy.sql.expression import ColumnElement
+from sqlalchemy.sql.expression import false
 
-from clean_python.base.domain.exceptions import AlreadyExists, Conflict, DoesNotExist
-from clean_python.base.infrastructure.gateway import Filter, Gateway, Json
+from clean_python.base.domain.exceptions import AlreadyExists
+from clean_python.base.domain.exceptions import Conflict
+from clean_python.base.domain.exceptions import DoesNotExist
 from clean_python.base.domain.pagination import PageOptions
-from .sql_provider import SQLDatabase, SQLProvider
+from clean_python.base.infrastructure.gateway import Filter
+from clean_python.base.infrastructure.gateway import Gateway
+from clean_python.base.infrastructure.gateway import Json
+
+from .sql_provider import SQLDatabase
+from .sql_provider import SQLProvider
 
 
 def _is_unique_violation_error_id(e: IntegrityError, id: int):

+ 7 - 3
clean_python/sql/sql_provider.py

@@ -1,11 +1,15 @@
-from abc import ABC, abstractmethod
+from abc import ABC
+from abc import abstractmethod
 from contextlib import asynccontextmanager
-from typing import AsyncIterator, List
+from typing import AsyncIterator
+from typing import List
 from unittest import mock
 
 from sqlalchemy.dialects import postgresql
 from sqlalchemy.exc import DBAPIError
-from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, create_async_engine
+from sqlalchemy.ext.asyncio import AsyncConnection
+from sqlalchemy.ext.asyncio import AsyncEngine
+from sqlalchemy.ext.asyncio import create_async_engine
 from sqlalchemy.sql import Executable
 
 from clean_python.base.domain.exceptions import Conflict

+ 2 - 2
pytest.ini

@@ -1,4 +1,4 @@
-; Usage of setup.cfg is not recommended unless for very simple use cases. 
+; Usage of setup.cfg is not recommended unless for very simple use cases.
 ; https://docs.pytest.org/en/latest/reference/customize.html
 
 [pytest]
@@ -10,4 +10,4 @@ testpaths = tests
 filterwarnings =
     ignore:The value of the smallest subnormal for <class 'numpy.float32'> type is zero.:UserWarning
     ignore:The value of the smallest subnormal for <class 'numpy.float64'> type is zero.:UserWarning
-    ignore:coroutine 'test_async_actor.<locals>.foo' was never awaited:RuntimeWarning
+    ignore:coroutine 'test_async_actor.<locals>.foo' was never awaited:RuntimeWarning

+ 4 - 6
tests/test_async_actor.py

@@ -4,12 +4,10 @@ from unittest import mock
 
 import pytest
 
-from clean_python.dramatiq.async_actor import (
-    async_actor,
-    AsyncActor,
-    AsyncMiddleware,
-    EventLoopThread,
-)
+from clean_python.dramatiq.async_actor import async_actor
+from clean_python.dramatiq.async_actor import AsyncActor
+from clean_python.dramatiq.async_actor import AsyncMiddleware
+from clean_python.dramatiq.async_actor import EventLoopThread
 
 
 @pytest.fixture

+ 1 - 1
tests/test_dramatiq_task_logger.py

@@ -5,8 +5,8 @@ import pytest
 from dramatiq.errors import Retry
 from dramatiq.message import Message
 
-from clean_python.dramatiq.dramatiq_task_logger import DramatiqTaskLogger
 from clean_python.base.infrastructure.gateway import InMemoryGateway
+from clean_python.dramatiq.dramatiq_task_logger import DramatiqTaskLogger
 
 
 @pytest.fixture

+ 2 - 1
tests/test_exceptions.py

@@ -1,7 +1,8 @@
 from pydantic import ValidationError
 
+from clean_python.base.domain.exceptions import BadRequest
+from clean_python.base.domain.exceptions import DoesNotExist
 from clean_python.base.domain.value_object import ValueObject
-from clean_python.base.domain.exceptions import BadRequest, DoesNotExist
 
 
 def test_bad_request_short_str():

+ 4 - 2
tests/test_fastapi_access_logger.py

@@ -3,9 +3,11 @@ from unittest import mock
 import pytest
 from fastapi.routing import APIRoute
 from starlette.requests import Request
-from starlette.responses import JSONResponse, StreamingResponse
+from starlette.responses import JSONResponse
+from starlette.responses import StreamingResponse
 
-from clean_python import FastAPIAccessLogger, InMemoryGateway
+from clean_python import FastAPIAccessLogger
+from clean_python import InMemoryGateway
 
 
 @pytest.fixture

+ 8 - 9
tests/test_gateway.py

@@ -1,16 +1,15 @@
-from datetime import datetime, timezone
+from datetime import datetime
+from datetime import timezone
 from unittest import mock
 
 import pytest
 
-from clean_python import (
-    AlreadyExists,
-    Conflict,
-    DoesNotExist,
-    Filter,
-    InMemoryGateway,
-    PageOptions,
-)
+from clean_python import AlreadyExists
+from clean_python import Conflict
+from clean_python import DoesNotExist
+from clean_python import Filter
+from clean_python import InMemoryGateway
+from clean_python import PageOptions
 
 
 @pytest.fixture

+ 7 - 9
tests/test_internal_gateway.py

@@ -3,15 +3,13 @@ from typing import cast
 import pytest
 from pydantic import Field
 
-from clean_python import (
-    Filter,
-    InMemoryGateway,
-    InternalGateway,
-    Manage,
-    Repository,
-    RootEntity,
-    ValueObject,
-)
+from clean_python import Filter
+from clean_python import InMemoryGateway
+from clean_python import InternalGateway
+from clean_python import Manage
+from clean_python import Repository
+from clean_python import RootEntity
+from clean_python import ValueObject
 
 
 # domain - other module

+ 3 - 1
tests/test_manage.py

@@ -5,7 +5,9 @@ from unittest import mock
 
 import pytest
 
-from clean_python import Filter, Manage, RootEntity
+from clean_python import Filter
+from clean_python import Manage
+from clean_python import RootEntity
 
 
 class User(RootEntity):

+ 3 - 1
tests/test_oauth2.py

@@ -7,7 +7,9 @@ from unittest import mock
 import jwt
 import pytest
 
-from clean_python import OAuth2AccessTokenVerifier, PermissionDenied, Unauthorized
+from clean_python import OAuth2AccessTokenVerifier
+from clean_python import PermissionDenied
+from clean_python import Unauthorized
 
 
 @pytest.fixture

+ 8 - 10
tests/test_repository.py

@@ -2,16 +2,14 @@ from unittest import mock
 
 import pytest
 
-from clean_python import (
-    BadRequest,
-    DoesNotExist,
-    Filter,
-    InMemoryGateway,
-    Page,
-    PageOptions,
-    Repository,
-    RootEntity,
-)
+from clean_python import BadRequest
+from clean_python import DoesNotExist
+from clean_python import Filter
+from clean_python import InMemoryGateway
+from clean_python import Page
+from clean_python import PageOptions
+from clean_python import Repository
+from clean_python import RootEntity
 
 
 class User(RootEntity):

+ 1 - 1
tests/test_request_query.py

@@ -3,8 +3,8 @@ from typing import Optional
 import pytest
 from pydantic import ValidationError
 
-from clean_python.base.infrastructure.gateway import Filter
 from clean_python.base.domain.pagination import PageOptions
+from clean_python.base.infrastructure.gateway import Filter
 from clean_python.fastapi.request_query import RequestQuery
 
 

+ 5 - 1
tests/test_resource.py

@@ -1,7 +1,11 @@
 import pytest
 from fastapi.routing import APIRouter
 
-from clean_python.fastapi.resource import APIVersion, get, Resource, Stability, v
+from clean_python.fastapi.resource import APIVersion
+from clean_python.fastapi.resource import get
+from clean_python.fastapi.resource import Resource
+from clean_python.fastapi.resource import Stability
+from clean_python.fastapi.resource import v
 
 
 def test_subclass():

+ 5 - 2
tests/test_root_entity.py

@@ -1,4 +1,5 @@
-from datetime import datetime, timezone
+from datetime import datetime
+from datetime import timezone
 from unittest import mock
 
 import pytest
@@ -24,7 +25,9 @@ def user():
 
 @pytest.fixture
 def patched_now():
-    with mock.patch("clean_python.base.domain.root_entity.now", return_value=SOME_DATETIME):
+    with mock.patch(
+        "clean_python.base.domain.root_entity.now", return_value=SOME_DATETIME
+    ):
         yield
 
 

+ 3 - 1
tests/test_service.py

@@ -1,6 +1,8 @@
 import pytest
 
-from clean_python import Resource, Service, v
+from clean_python import Resource
+from clean_python import Service
+from clean_python import v
 
 
 class V1Foo(Resource, version=v(1), name="foo"):

+ 17 - 12
tests/test_sql_gateway.py

@@ -1,18 +1,23 @@
-from datetime import datetime, timezone
+from datetime import datetime
+from datetime import timezone
 from unittest import mock
 
 import pytest
-from sqlalchemy import Column, DateTime, ForeignKey, Integer, MetaData, Table, Text
-
-from clean_python import (
-    assert_query_equal,
-    Conflict,
-    DoesNotExist,
-    FakeSQLDatabase,
-    Filter,
-    PageOptions,
-    SQLGateway,
-)
+from sqlalchemy import Column
+from sqlalchemy import DateTime
+from sqlalchemy import ForeignKey
+from sqlalchemy import Integer
+from sqlalchemy import MetaData
+from sqlalchemy import Table
+from sqlalchemy import Text
+
+from clean_python import assert_query_equal
+from clean_python import Conflict
+from clean_python import DoesNotExist
+from clean_python import FakeSQLDatabase
+from clean_python import Filter
+from clean_python import PageOptions
+from clean_python import SQLGateway
 
 writer = Table(
     "writer",

+ 4 - 2
tests/test_value_object.py

@@ -1,7 +1,9 @@
 import pytest
-from pydantic import ValidationError, validator
+from pydantic import ValidationError
+from pydantic import validator
 
-from clean_python import BadRequest, ValueObject
+from clean_python import BadRequest
+from clean_python import ValueObject
 
 
 class Color(ValueObject):