Skip to content

Commit

Permalink
Merge pull request #12 from yanasirina/danchik
Browse files Browse the repository at this point in the history
Danchik
  • Loading branch information
khoribz authored Dec 8, 2024
2 parents 5ae381e + 1cdef3d commit c4bfefa
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 12 deletions.
3 changes: 2 additions & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ disable=
W1203,
R1732,
W0621,
W0613
W0613,
C0206


[FORMAT]
Expand Down
8 changes: 7 additions & 1 deletion playground/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def after(self, _request, response):
return response


router.use_middleware(ExampleMiddleware)
# router.use_middleware(ExampleMiddleware)


@router.get('/main', middlewares=[ExampleMiddleware])
Expand All @@ -39,6 +39,12 @@ def get_example(request):
return web.responses.RedirectResponse('/main')


@router.get('/hello/{name}/{age}')
def get_example_with_params(request, name: str, age: int):
logger.info(f'got {request=}')
return web.responses.JsonResponse({'message': 'hello, world!', 'name': name, 'age': age})


@router.post('/hello', middlewares=[ExampleMiddleware])
def post_example(request):
logger.info(f'got {request=}')
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mccabe==0.7.0
mypy==1.13.0
mypy-extensions==1.0.0
packaging==24.2
parse==1.20.2
platformdirs==4.3.6
pluggy==1.5.0
pycodestyle==2.12.1
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def main() -> None:
'webob',
'jinja2',
'python-dotenv',
'parse',
'locust'
],
)
Expand Down
45 changes: 35 additions & 10 deletions web/router.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import logging
from http import HTTPMethod
from typing import Type, Callable
from typing import Callable, Type

from webob import Request, Response
from webob.exc import HTTPNotFound, HTTPInternalServerError
from webob.exc import HTTPNotFound, HTTPInternalServerError, HTTPBadRequest
from parse import parse

from .middleware import Middleware

Expand Down Expand Up @@ -33,35 +35,35 @@ def _add_route(
self.global_middlewares + middlewares,
)

def get(self, path: str, middlewares: list[Middleware] | None = None):
def get(self, path: str, middlewares: list[Type[Middleware]] | None = None):
def decorator(func):
self._add_route(HTTPMethod.GET, path, func, middlewares)
return func

return decorator

def post(self, path: str, middlewares: list[Middleware] | None = None):
def post(self, path: str, middlewares: list[Type[Middleware]] | None = None):
def decorator(func):
self._add_route(HTTPMethod.POST, path, func, middlewares)
return func

return decorator

def put(self, path: str, middlewares: list[Middleware] | None = None):
def put(self, path: str, middlewares: list[Type[Middleware]] | None = None):
def decorator(func):
self._add_route(HTTPMethod.PUT, path, func, middlewares)
return func

return decorator

def patch(self, path: str, middlewares: list[Middleware] | None = None):
def patch(self, path: str, middlewares: list[Type[Middleware]] | None = None):
def decorator(func):
self._add_route(HTTPMethod.PATCH, path, func, middlewares)
return func

return decorator

def delete(self, path: str, middlewares: list[Middleware] | None = None):
def delete(self, path: str, middlewares: list[Type[Middleware]] | None = None):
def decorator(func):
self._add_route(HTTPMethod.DELETE, path, func, middlewares)
return func
Expand All @@ -85,12 +87,25 @@ def __call__(self, environ, start_response):
request = Request(environ)
response = Response()

method_routes = self._routes.get(request.path_info, {})
handler = method_routes.get(request.method)
handler, kwargs = self._find_handler(request)

if kwargs and handler:
# получаем типы аргументов из сигнатуры функции
logging.info(f'{handler=}')
signature = handler.__annotations__
# приводим аргументы к нужным типам
try:
kwargs = {name: signature[name](value) for name, value in
kwargs.items()}
except ValueError:
response = HTTPBadRequest(
json={"error": "invalid type arguments"})
return response(environ, start_response)

if handler is not None:
try:
response = handler(request)

response = handler(request, **kwargs)
except Exception:
response = HTTPInternalServerError()
else:
Expand All @@ -107,3 +122,13 @@ def _apply_middlewares(handler, middlewares):
handler = middleware(handler)

return handler

def _find_handler(self, request):
for route in self._routes:
parse_result = parse(route, request.path)
if parse_result:
handler = self._routes[route].get(request.method)
if handler is not None:
return handler, parse_result.named

return None, None

0 comments on commit c4bfefa

Please sign in to comment.