Skip to content

Commit 10aae68

Browse files
committed
code refactoring
1 parent 3cde770 commit 10aae68

File tree

22 files changed

+327
-114
lines changed

22 files changed

+327
-114
lines changed

ellar/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Ellar - Python ASGI web framework for building fast, efficient, and scalable RESTful APIs and server-side applications."""
22

3-
__version__ = "0.8.0"
3+
__version__ = "0.8b"

ellar/auth/interceptor.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import typing as t
22
from functools import partial
33

4-
from ellar.common import APIException, EllarInterceptor, IExecutionContext
4+
from ellar.common import APIException, EllarInterceptor, IExecutionContext, constants
5+
from ellar.core.services import reflector
56
from ellar.di import injectable
67
from starlette import status
78

@@ -34,6 +35,12 @@ def _get_policy_instance(
3435
async def intercept(
3536
self, context: IExecutionContext, next_interceptor: t.Callable[..., t.Coroutine]
3637
) -> t.Any:
38+
skip_auth = reflector.get_all_and_override(
39+
constants.SKIP_AUTH, context.get_handler(), context.get_class()
40+
)
41+
if skip_auth is True:
42+
return await next_interceptor()
43+
3744
if not context.user.is_authenticated:
3845
raise self.exception_class(status_code=401)
3946

ellar/events/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@
33
app_context_started = EventManager()
44
app_context_teardown = EventManager()
55

6+
request_started = EventManager()
7+
request_teardown = EventManager()
8+
69
__all__ = [
710
"app_context_started",
811
"app_context_teardown",
12+
"request_started",
13+
"request_teardown",
914
"EventHandler",
1015
"EventManager",
1116
]

ellar/openapi/builder.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,17 @@
44
from ellar.common import IIdentitySchemes
55
from ellar.common.compatible import AttributeDict, cached_property
66
from ellar.common.constants import GUARDS_KEY
7-
from ellar.core.routing import ControllerRouteOperation, EllarMount, RouteOperation
8-
from ellar.openapi.constants import OPENAPI_OPERATION_KEY, OPENAPI_TAG, REF_TEMPLATE
7+
from ellar.core.routing import (
8+
ControllerRouteOperation,
9+
EllarControllerMount,
10+
RouteOperation,
11+
)
12+
from ellar.openapi.constants import (
13+
IGNORE_CONTROLLER_TYPE,
14+
OPENAPI_OPERATION_KEY,
15+
OPENAPI_TAG,
16+
REF_TEMPLATE,
17+
)
918
from ellar.pydantic import (
1019
EmailStr,
1120
GenerateJsonSchema,
@@ -54,17 +63,20 @@ def _get_openapi_route_document_models(self, app: "App") -> t.List[OpenAPIRoute]
5463

5564
for route in app.routes:
5665
if (
57-
isinstance(route, EllarMount)
66+
isinstance(route, EllarControllerMount)
5867
and len(route.routes) > 0
5968
and route.include_in_schema
60-
and route.get_control_type()
69+
and route.get_controller_type()
6170
):
62-
control_type = route.get_control_type()
71+
control_type = route.get_controller_type()
6372
assert control_type
6473

6574
openapi_tags = AttributeDict(
6675
reflector.get(OPENAPI_TAG, control_type) or {}
6776
)
77+
ignore_tag = (
78+
reflector.get(IGNORE_CONTROLLER_TYPE, control_type) or False
79+
)
6880
if route.name:
6981
openapi_tags.setdefault("name", route.name)
7082

@@ -80,7 +92,7 @@ def _get_openapi_route_document_models(self, app: "App") -> t.List[OpenAPIRoute]
8092
),
8193
)
8294
)
83-
if openapi_tags:
95+
if openapi_tags and not ignore_tag:
8496
self._build.setdefault("tags", []).append(openapi_tags)
8597
elif (
8698
isinstance(route, (RouteOperation, ControllerRouteOperation))
@@ -126,7 +138,7 @@ def create_document(self, app: "App") -> OpenAPI:
126138
separate_input_output_schemas=True,
127139
)
128140

129-
# mounts: t.List[t.Union[BaseRoute, EllarMount, Mount]] = []
141+
# mounts: t.List[t.Union[BaseRoute, EllarControllerMount, Mount]] = []
130142
# for _, item in app.injector.get_templating_modules().items():
131143
# mounts.extend(item.routers)
132144

ellar/openapi/docs_ui/redocs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
class ReDocUI(IDocumentationUI):
55
@property
66
def name(self) -> str:
7-
return "swagger"
7+
return "redoc"
88

99
@property
1010
def template_name(self) -> str:

ellar/openapi/module.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,12 @@ def _get_document() -> OpenAPI:
9292

9393
document = _get_document
9494

95-
@router.get(openapi_url, include_in_schema=False, response=OpenAPI)
95+
@router.get(
96+
openapi_url,
97+
include_in_schema=False,
98+
response=OpenAPI,
99+
name="openapi_schema",
100+
)
96101
@set_metadata(OPENAPI_OPERATION_KEY, True)
97102
def openapi_schema() -> t.Any:
98103
_docs = document
@@ -139,9 +144,9 @@ def _setup_document_manager(
139144

140145
@t.no_type_check
141146
async def _doc(ctx: IExecutionContext) -> HTMLResponse:
142-
request = ctx.switch_to_http_connection().get_request()
147+
ctx.switch_to_http_connection().get_request()
143148
html_str = render_template_string(
144-
docs_ui.template_string, request, **docs_ui.template_context
149+
docs_ui.template_string, **docs_ui.template_context
145150
)
146151
return HTMLResponse(html_str)
147152

ellar/openapi/route_doc_models.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
RouteParameterModelField,
1818
)
1919
from ellar.common.shortcuts import normalize_path
20-
from ellar.core.routing import EllarMount, RouteOperation
20+
from ellar.core.routing import EllarControllerMount, RouteOperation
2121
from ellar.core.services.reflector import reflector
2222
from ellar.openapi.constants import (
2323
IGNORE_CONTROLLER_TYPE,
@@ -58,7 +58,7 @@ def get_openapi_path(
5858
class OpenAPIMountDocumentation(OpenAPIRoute):
5959
def __init__(
6060
self,
61-
mount: t.Union[EllarMount, Mount],
61+
mount: t.Union[EllarControllerMount, Mount],
6262
global_route_models_update: t.Callable[
6363
["OpenAPIMountDocumentation", t.Dict], t.Any
6464
],
@@ -103,15 +103,20 @@ def _build_routes(self) -> t.List["OpenAPIRouteDocumentation"]:
103103
**openapi,
104104
)
105105
)
106-
elif isinstance(route, EllarMount):
106+
elif isinstance(route, EllarControllerMount):
107107
openapi_tags = AttributeDict(
108-
reflector.get(OPENAPI_TAG, route.get_control_type()) or {}
108+
reflector.get(OPENAPI_TAG, route.get_controller_type()) or {}
109+
)
110+
ignore_tag = (
111+
reflector.get(IGNORE_CONTROLLER_TYPE, route.get_controller_type())
112+
or False
109113
)
110-
111114
if route.name:
112115
openapi_tags.setdefault("name", route.name)
113116

114-
guards = reflector.get(GUARDS_KEY, route.get_control_type())
117+
openapi_tags.update(name=f"{self.tag}:{openapi_tags.name}")
118+
119+
guards = reflector.get(GUARDS_KEY, route.get_controller_type())
115120

116121
self._global_route_models_update(
117122
OpenAPIMountDocumentation(
@@ -121,7 +126,7 @@ def _build_routes(self) -> t.List["OpenAPIRouteDocumentation"]:
121126
global_route_models_update=self._global_route_models_update,
122127
path_prefix=self.path_format,
123128
),
124-
openapi_tags,
129+
openapi_tags if not ignore_tag else None,
125130
)
126131
return routes
127132

ellar/pydantic/decorator.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import typing as t
22

3+
from ellar.utils.importer import import_from_string
34
from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler
45
from pydantic.json_schema import JsonSchemaValue
56
from pydantic_core import CoreSchema
@@ -44,23 +45,41 @@ def __get_pydantic_core_schema__(
4445

4546

4647
class AllowTypeOfSource:
47-
def __init__(self, schema: t.Optional[t.Dict[str, t.Any]] = None) -> None:
48+
def __init__(
49+
self,
50+
schema: t.Optional[t.Dict[str, t.Any]] = None,
51+
validator: t.Callable[..., bool] = None,
52+
error_message: t.Optional[t.Callable[..., str]] = None,
53+
) -> None:
4854
self._schema = schema
55+
self.validator = validator
56+
self.error_message = error_message
4957

5058
def __get_pydantic_core_schema__(
5159
self,
5260
source: t.Type[t.Any],
5361
handler: GetCoreSchemaHandler,
5462
) -> CoreSchema:
5563
def validate(value: t.Any, *args: t.Any) -> t.Any:
56-
if not isinstance(value, source):
57-
raise ValueError(
58-
f"Expected an instance of {source}, got an instance of {type(value)}"
59-
)
64+
if isinstance(value, str) and len(value.split(":")) == 2:
65+
value = import_from_string(value)
66+
67+
if (self.validator and not self.validator(source, value)) or (
68+
not self.validator and not isinstance(value, source)
69+
):
70+
self._handle_error(source, value)
6071
return value
6172

6273
return with_info_plain_validator_function(validate)
6374

75+
def _handle_error(self, source: t.Any, value: t.Any) -> None:
76+
error_message = (
77+
f"Expected an instance of {source}, got an instance of {type(value)}"
78+
if self.error_message is None
79+
else self.error_message(source, value)
80+
)
81+
raise ValueError(error_message)
82+
6483
def __get_pydantic_json_schema__(
6584
self, core_schema: CoreSchema, handler: GetJsonSchemaHandler
6685
) -> JsonSchemaValue: # pragma: no cover

ellar/reflect/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from ._reflect import reflect
2-
from .constants import REFLECT_TYPE
2+
from .utils import ensure_target, transfer_metadata
33

4-
__all__ = ["reflect", "REFLECT_TYPE"]
4+
__all__ = ["reflect", "ensure_target", "transfer_metadata"]

0 commit comments

Comments
 (0)