Browse Source

import path refactor, fix tests

jelle.prins 1 year ago
parent
commit
ea978584c7
46 changed files with 108 additions and 94 deletions
  1. 27 27
      clean_python/__init__.py
  2. 0 0
      clean_python/base/application/__init__.py
  3. 4 4
      clean_python/base/application/manage.py
  4. 4 4
      clean_python/base/domain/repository.py
  5. 3 3
      clean_python/base/domain/root_entity.py
  6. 0 0
      clean_python/base/infrastructure/__init__.py
  7. 3 3
      clean_python/base/infrastructure/gateway.py
  8. 6 6
      clean_python/base/infrastructure/internal_gateway.py
  9. 0 0
      clean_python/base/presentation/__init__.py
  10. 0 0
      clean_python/celery/__init__.py
  11. 2 2
      clean_python/celery/celery_rmq_broker.py
  12. 0 0
      clean_python/dramatiq/__init__.py
  13. 2 2
      clean_python/dramatiq/dramatiq_task_logger.py
  14. 0 0
      clean_python/fastapi/__init__.py
  15. 2 2
      clean_python/fastapi/error_responses.py
  16. 2 2
      clean_python/fastapi/fastapi_access_logger.py
  17. 3 3
      clean_python/fastapi/request_query.py
  18. 1 1
      clean_python/fastapi/resource.py
  19. 3 3
      clean_python/fastapi/service.py
  20. 0 0
      clean_python/fluentbit/__init__.py
  21. 1 1
      clean_python/fluentbit/fluentbit_gateway.py
  22. 0 0
      clean_python/oauth2/__init__.py
  23. 1 1
      clean_python/oauth2/oauth2.py
  24. 0 0
      clean_python/sql/__init__.py
  25. 3 3
      clean_python/sql/sql_gateway.py
  26. 2 2
      clean_python/sql/sql_provider.py
  27. 0 0
      clean_python/testing/__init__.py
  28. 4 3
      pyproject.toml
  29. 13 0
      pytest.ini
  30. 0 0
      tests/__init__.py
  31. 1 1
      tests/test_async_actor.py
  32. 2 2
      tests/test_celery_rmq_broker.py
  33. 2 2
      tests/test_dramatiq_task_logger.py
  34. 2 2
      tests/test_exceptions.py
  35. 1 1
      tests/test_fastapi_access_logger.py
  36. 1 1
      tests/test_gateway.py
  37. 1 1
      tests/test_internal_gateway.py
  38. 1 1
      tests/test_manage.py
  39. 1 1
      tests/test_oauth2.py
  40. 1 1
      tests/test_repository.py
  41. 3 3
      tests/test_request_query.py
  42. 1 1
      tests/test_resource.py
  43. 2 2
      tests/test_root_entity.py
  44. 1 1
      tests/test_service.py
  45. 1 1
      tests/test_sql_gateway.py
  46. 1 1
      tests/test_value_object.py

+ 27 - 27
clean_python/__init__.py

@@ -1,30 +1,30 @@
 # -*- coding: utf-8 -*-
 # (c) Nelen & Schuurmans
 
-from .async_actor import *  # NOQA
-from .attr_dict import AttrDict  # NOQA
-from .celery_rmq_broker import *  # NOQA
-from .context import *  # NOQA
-from .domain_event import *  # NOQA
-from .domain_service import DomainService  # NOQA
-from .dramatiq_task_logger import *  # NOQA
-from .exceptions import *  # NOQA
-from .fastapi_access_logger import *  # NOQA
-from .fluentbit_gateway import FluentbitGateway  # NOQA
-from .gateway import *  # NOQA
-from .internal_gateway import InternalGateway  # NOQA
-from .link import Link  # NOQA
-from .manage import Manage  # NOQA
-from .now import now  # NOQA
-from .oauth2 import *  # NOQA
-from .pagination import *  # NOQA
-from .repository import Repository  # NOQA
-from .request_query import *  # NOQA
-from .resource import *  # NOQA
-from .root_entity import RootEntity  # NOQA
-from .service import Service  # NOQA
-from .sql_gateway import SQLGateway  # NOQA
-from .sql_provider import *  # NOQA
-from .tmpdir_provider import *  # NOQA
-from .value import Value  # NOQA
-from .value_object import ValueObject, ValueObjectWithId  # NOQA
+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.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.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 .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 .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

+ 0 - 0
clean_python/base/application/__init__.py


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

@@ -3,10 +3,10 @@
 
 from typing import Any, Generic, List, Optional, Type, TypeVar
 
-from .gateway import Filter, Json
-from .pagination import Page, PageOptions
-from .repository import Repository
-from .root_entity import RootEntity
+from clean_python.base.infrastructure.gateway import Filter, Json
+from clean_python.base.domain.pagination import Page, PageOptions
+from clean_python.base.domain.repository import Repository
+from clean_python.base.domain.root_entity import RootEntity
 
 T = TypeVar("T", bound=RootEntity)
 

+ 4 - 4
clean_python/base/domain/repository.py

@@ -3,10 +3,10 @@
 
 from typing import Any, Generic, List, Optional, Type, TypeVar, Union
 
-from .exceptions import DoesNotExist
-from .gateway import Filter, Gateway, Json
-from .pagination import Page, PageOptions
-from .root_entity import RootEntity
+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.root_entity import RootEntity
 
 T = TypeVar("T", bound=RootEntity)
 

+ 3 - 3
clean_python/base/domain/root_entity.py

@@ -1,9 +1,9 @@
 from datetime import datetime
 from typing import Optional, Type, TypeVar
 
-from .exceptions import BadRequest
-from .now import now
-from .value_object import ValueObject
+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
 
 T = TypeVar("T", bound="RootEntity")
 

+ 0 - 0
clean_python/base/infrastructure/__init__.py


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

@@ -5,9 +5,9 @@ from copy import deepcopy
 from datetime import datetime
 from typing import Any, Callable, Dict, List, Optional
 
-from .exceptions import AlreadyExists, Conflict, DoesNotExist
-from .pagination import PageOptions
-from .value_object import ValueObject
+from clean_python.base.domain.exceptions import AlreadyExists, Conflict, DoesNotExist
+from clean_python.base.domain.pagination import PageOptions
+from clean_python.base.domain.value_object import ValueObject
 
 __all__ = ["Gateway", "Json", "Filter", "InMemoryGateway"]
 Json = Dict[str, Any]

+ 6 - 6
clean_python/base/infrastructure/internal_gateway.py

@@ -3,12 +3,12 @@
 from abc import abstractmethod, abstractproperty
 from typing import Generic, List, Optional, TypeVar
 
-from .exceptions import BadRequest, DoesNotExist
-from .gateway import Filter
-from .manage import Manage
-from .pagination import PageOptions
-from .root_entity import RootEntity
-from .value_object import ValueObject
+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.pagination import PageOptions
+from clean_python.base.domain.root_entity import RootEntity
+from clean_python.base.domain.value_object import ValueObject
 
 E = TypeVar("E", bound=RootEntity)  # External
 T = TypeVar("T", bound=ValueObject)  # Internal

+ 0 - 0
clean_python/base/presentation/__init__.py


+ 0 - 0
clean_python/celery/__init__.py


+ 2 - 2
clean_python/celery/celery_rmq_broker.py

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

+ 0 - 0
clean_python/dramatiq/__init__.py


+ 2 - 2
clean_python/dramatiq/dramatiq_task_logger.py

@@ -9,8 +9,8 @@ from dramatiq.errors import RateLimitExceeded, Retry
 from dramatiq.message import Message
 from dramatiq.middleware import SkipMessage
 
-from .fluentbit_gateway import FluentbitGateway
-from .gateway import Gateway
+from clean_python.fluentbit.fluentbit_gateway import FluentbitGateway
+from clean_python.base.infrastructure.gateway import Gateway
 
 __all__ = ["AsyncLoggingMiddleware"]
 

+ 0 - 0
clean_python/fastapi/__init__.py


+ 2 - 2
clean_python/fastapi/error_responses.py

@@ -5,14 +5,14 @@ from fastapi.requests import Request
 from fastapi.responses import JSONResponse
 from starlette import status
 
-from .exceptions import (
+from clean_python.base.domain.exceptions import (
     BadRequest,
     Conflict,
     DoesNotExist,
     PermissionDenied,
     Unauthorized,
 )
-from .value_object import ValueObject
+from clean_python.base.domain.value_object import ValueObject
 
 __all__ = [
     "ValidationErrorResponse",

+ 2 - 2
clean_python/fastapi/fastapi_access_logger.py

@@ -8,8 +8,8 @@ from starlette.background import BackgroundTasks
 from starlette.requests import Request
 from starlette.responses import Response
 
-from .fluentbit_gateway import FluentbitGateway
-from .gateway import Gateway
+from clean_python.fluentbit.fluentbit_gateway import FluentbitGateway
+from clean_python.base.infrastructure.gateway import Gateway
 
 __all__ = ["FastAPIAccessLogger"]
 

+ 3 - 3
clean_python/fastapi/request_query.py

@@ -6,9 +6,9 @@ from typing import List
 from fastapi import Query
 from pydantic import validator
 
-from .gateway import Filter
-from .pagination import PageOptions
-from .value_object import ValueObject
+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
 
 __all__ = ["RequestQuery"]
 

+ 1 - 1
clean_python/fastapi/resource.py

@@ -4,7 +4,7 @@ from typing import Any, Callable, Dict, List, Optional, Sequence, Type
 
 from fastapi.routing import APIRouter
 
-from .value_object import ValueObject
+from clean_python.base.domain.value_object import ValueObject
 
 __all__ = [
     "Resource",

+ 3 - 3
clean_python/fastapi/service.py

@@ -20,10 +20,10 @@ from .error_responses import (
     validation_error_handler,
     ValidationErrorResponse,
 )
-from .exceptions import Conflict, DoesNotExist, PermissionDenied, Unauthorized
+from clean_python.base.domain.exceptions import Conflict, DoesNotExist, PermissionDenied, Unauthorized
 from .fastapi_access_logger import FastAPIAccessLogger
-from .gateway import Gateway
-from .oauth2 import OAuth2AccessTokenVerifier, OAuth2Settings
+from clean_python.base.infrastructure.gateway import Gateway
+from clean_python.oauth2.oauth2 import OAuth2AccessTokenVerifier, OAuth2Settings
 from .resource import APIVersion, clean_resources, Resource
 
 logger = logging.getLogger(__name__)

+ 0 - 0
clean_python/fluentbit/__init__.py


+ 1 - 1
clean_python/fluentbit/fluentbit_gateway.py

@@ -6,7 +6,7 @@ from typing import Any, Dict
 from asgiref.sync import sync_to_async
 from fluent.sender import FluentSender
 
-from .gateway import Gateway
+from clean_python.base.infrastructure.gateway import Gateway
 
 Json = Dict[str, Any]
 

+ 0 - 0
clean_python/oauth2/__init__.py


+ 1 - 1
clean_python/oauth2/oauth2.py

@@ -9,7 +9,7 @@ from jwt import PyJWKClient
 from jwt.exceptions import PyJWTError
 from pydantic import AnyHttpUrl, BaseModel
 
-from .exceptions import PermissionDenied, Unauthorized
+from clean_python.base.domain.exceptions import PermissionDenied, Unauthorized
 
 __all__ = ["OAuth2Settings", "OAuth2AccessTokenVerifier"]
 

+ 0 - 0
clean_python/sql/__init__.py


+ 3 - 3
clean_python/sql/sql_gateway.py

@@ -11,9 +11,9 @@ from sqlalchemy.exc import IntegrityError
 from sqlalchemy.sql import Executable
 from sqlalchemy.sql.expression import ColumnElement, false
 
-from .exceptions import AlreadyExists, Conflict, DoesNotExist
-from .gateway import Filter, Gateway, Json
-from .pagination import PageOptions
+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.pagination import PageOptions
 from .sql_provider import SQLDatabase, SQLProvider
 
 

+ 2 - 2
clean_python/sql/sql_provider.py

@@ -8,8 +8,8 @@ from sqlalchemy.exc import DBAPIError
 from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, create_async_engine
 from sqlalchemy.sql import Executable
 
-from .exceptions import Conflict
-from .gateway import Json
+from clean_python.base.domain.exceptions import Conflict
+from clean_python.base.infrastructure.gateway import Json
 
 __all__ = ["SQLProvider", "SQLDatabase", "FakeSQLDatabase", "assert_query_equal"]
 

+ 0 - 0
clean_python/testing/__init__.py


+ 4 - 3
pyproject.toml

@@ -10,7 +10,7 @@ license = {text = "MIT"}
 classifiers = ["Programming Language :: Python"]
 keywords = []
 requires-python = ">=3.7"
-dependencies = ["pydantic==1.*", "inject", "asgiref"]
+dependencies = ["pydantic==1.*", "inject", "asgiref", "blinker"]
 dynamic = ["version"]
 
 [project.optional-dependencies]
@@ -20,8 +20,9 @@ test = [
 ]
 dramatiq = ["dramatiq"]
 fastapi = ["fastapi"]
-auth = ["jwt"]
-fluentbit = ["fluentbit"]
+auth = ["pyjwt[crypto]==2.6.0"]
+celery = ["pika"]
+fluentbit = ["fluent-logger"]
 sql = ["sqlalchemy==2.*"]
 
 [project.urls]

+ 13 - 0
pytest.ini

@@ -0,0 +1,13 @@
+; Usage of setup.cfg is not recommended unless for very simple use cases. 
+; https://docs.pytest.org/en/latest/reference/customize.html
+
+[pytest]
+asyncio_mode = auto
+testpaths = tests
+; Apparently, gevent is enabling "flush to zero":
+; https://github.com/numpy/numpy/issues/20895
+; Suppress the corresponding warnings:
+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

+ 0 - 0
tests/__init__.py


+ 1 - 1
clean_python/tests/test_async_actor.py → tests/test_async_actor.py

@@ -4,7 +4,7 @@ from unittest import mock
 
 import pytest
 
-from base_lib.async_actor import (
+from clean_python.dramatiq.async_actor import (
     async_actor,
     AsyncActor,
     AsyncMiddleware,

+ 2 - 2
clean_python/tests/test_celery_rmq_broker.py → tests/test_celery_rmq_broker.py

@@ -2,7 +2,7 @@ from unittest import mock
 
 import pytest
 
-from base_lib import CeleryRmqBroker
+from clean_python.celery.celery_rmq_broker import CeleryRmqBroker
 
 
 @pytest.fixture
@@ -10,7 +10,7 @@ def celery_rmq_broker():
     return CeleryRmqBroker("amqp://rmq:1234//", "some_queue", "host", False)
 
 
-@mock.patch("base_lib.celery_rmq_broker.pika.BlockingConnection")
+@mock.patch("clean_python.celery.celery_rmq_broker.pika.BlockingConnection")
 async def test_celery_rmq_broker(connection, celery_rmq_broker):
     await celery_rmq_broker.add({"task": "some.task", "args": ["foo", 15]})
 

+ 2 - 2
clean_python/tests/test_dramatiq_task_logger.py → tests/test_dramatiq_task_logger.py

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

+ 2 - 2
clean_python/tests/test_exceptions.py → tests/test_exceptions.py

@@ -1,7 +1,7 @@
 from pydantic import ValidationError
 
-from base_lib import ValueObject
-from base_lib.exceptions import BadRequest, 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():

+ 1 - 1
clean_python/tests/test_fastapi_access_logger.py → tests/test_fastapi_access_logger.py

@@ -5,7 +5,7 @@ from fastapi.routing import APIRoute
 from starlette.requests import Request
 from starlette.responses import JSONResponse, StreamingResponse
 
-from base_lib import FastAPIAccessLogger, InMemoryGateway
+from clean_python import FastAPIAccessLogger, InMemoryGateway
 
 
 @pytest.fixture

+ 1 - 1
clean_python/tests/test_gateway.py → tests/test_gateway.py

@@ -3,7 +3,7 @@ from unittest import mock
 
 import pytest
 
-from base_lib import (
+from clean_python import (
     AlreadyExists,
     Conflict,
     DoesNotExist,

+ 1 - 1
clean_python/tests/test_internal_gateway.py → tests/test_internal_gateway.py

@@ -3,7 +3,7 @@ from typing import cast
 import pytest
 from pydantic import Field
 
-from base_lib import (
+from clean_python import (
     Filter,
     InMemoryGateway,
     InternalGateway,

+ 1 - 1
clean_python/tests/test_manage.py → tests/test_manage.py

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

+ 1 - 1
clean_python/tests/test_oauth2.py → tests/test_oauth2.py

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

+ 1 - 1
clean_python/tests/test_repository.py → tests/test_repository.py

@@ -2,7 +2,7 @@ from unittest import mock
 
 import pytest
 
-from base_lib import (
+from clean_python import (
     BadRequest,
     DoesNotExist,
     Filter,

+ 3 - 3
clean_python/tests/test_request_query.py → tests/test_request_query.py

@@ -3,9 +3,9 @@ from typing import Optional
 import pytest
 from pydantic import ValidationError
 
-from base_lib.gateway import Filter
-from base_lib.pagination import PageOptions
-from base_lib.request_query import RequestQuery
+from clean_python.base.infrastructure.gateway import Filter
+from clean_python.base.domain.pagination import PageOptions
+from clean_python.fastapi.request_query import RequestQuery
 
 
 class SomeQuery(RequestQuery):

+ 1 - 1
clean_python/tests/test_resource.py → tests/test_resource.py

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

+ 2 - 2
clean_python/tests/test_root_entity.py → tests/test_root_entity.py

@@ -3,7 +3,7 @@ from unittest import mock
 
 import pytest
 
-from base_lib import RootEntity
+from clean_python import RootEntity
 
 SOME_DATETIME = datetime(2023, 1, 1, tzinfo=timezone.utc)
 
@@ -24,7 +24,7 @@ def user():
 
 @pytest.fixture
 def patched_now():
-    with mock.patch("base_lib.root_entity.now", return_value=SOME_DATETIME):
+    with mock.patch("clean_python.base.domain.root_entity.now", return_value=SOME_DATETIME):
         yield
 
 

+ 1 - 1
clean_python/tests/test_service.py → tests/test_service.py

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

+ 1 - 1
clean_python/tests/test_sql_gateway.py → tests/test_sql_gateway.py

@@ -4,7 +4,7 @@ from unittest import mock
 import pytest
 from sqlalchemy import Column, DateTime, ForeignKey, Integer, MetaData, Table, Text
 
-from base_lib import (
+from clean_python import (
     assert_query_equal,
     Conflict,
     DoesNotExist,

+ 1 - 1
clean_python/tests/test_value_object.py → tests/test_value_object.py

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