Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

apply django ninja for new-ara #470

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ tqdm = "*"
lxml = "*"
django-ses = "*"
pydantic = "*"
django-ninja = "*"
ratelimit = "*"

[dev-packages]
black = "*"
Expand Down
1,083 changes: 589 additions & 494 deletions Pipfile.lock

Large diffs are not rendered by default.

Empty file added ara/common/__init__.py
Empty file.
20 changes: 20 additions & 0 deletions ara/common/exceptions/ara_exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from ara.controller.constants import HttpStatusCode


class AraException(Exception):
error_code: int | None
error_reason: str | None


class TooManyRequestException(AraException):
"""too many requests exception"""

error_code = HttpStatusCode.TOO_MANY_REQUESTS
error_reason = "Too many requests"


class InvalidRequestException(AraException):
"""invalid request exception"""

error_code = HttpStatusCode.BAD_REQUEST
error_reason = "Invalid request"
36 changes: 36 additions & 0 deletions ara/controller/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from ninja import NinjaAPI
from ninja.errors import ValidationError
from ratelimit.exception import RateLimitException

from ara.common.exceptions.ara_exception import (
InvalidRequestException,
TooManyRequestException,
)
from ara.controller.constants import HttpStatusCode
from ara.controller.ping import router as ping_router
from ara.controller.response import AraErrorResponseBody
from ara.settings import env

docs_url = None if env("DJANGO_ENV") == "production" else "/docs"
api = NinjaAPI(docs_url=docs_url)


@api.exception_handler(RateLimitException)
def too_many_requests(request, exception):
return api.create_response(
request,
AraErrorResponseBody(TooManyRequestException()),
status=HttpStatusCode.TOO_MANY_REQUESTS,
)


@api.exception_handler(ValidationError)
def invalid_request(request, exception):
return api.create_response(
request,
AraErrorResponseBody(InvalidRequestException()),
status=HttpStatusCode.BAD_REQUEST,
)


api.add_router("/ping", ping_router)
30 changes: 27 additions & 3 deletions ara/controller/authentication.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
class AuthLoggedInUser:
# TODO
pass
from typing import Any

from django.http import HttpRequest
from ninja.security import HttpBearer
from rest_framework.authentication import SessionAuthentication


class AuthLoggedInUser(HttpBearer):
def __call__(self, request: HttpRequest) -> Any | None:
headers = request.headers
auth_value = headers.get(self.header)
if not auth_value:
return None
parts = auth_value.split(" ")

if parts[0].lower() != self.openapi_scheme:
return None
return self.authenticate(request)

def authenticate(self, request: HttpRequest, token: str) -> bool:
result = SessionAuthentication().authenticate(request)
if result is None:
return False
(user, _) = result
request.user = user

return bool(user and user.is_authenticated)
1 change: 1 addition & 0 deletions ara/controller/ping/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .ping_router import router
39 changes: 39 additions & 0 deletions ara/controller/ping/ping_router.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from django.http import HttpRequest
from ninja import Router

from ara.controller.authentication import AuthLoggedInUser
from ara.controller.constants import HttpStatusCode
from ara.controller.response import AraResponse

router = Router()


@router.get(
"/",
response={
HttpStatusCode.OK: str,
HttpStatusCode.INTERNAL_SERVER_ERROR: str,
},
)
def ping(request: HttpRequest):
return AraResponse(
status_code=HttpStatusCode.OK,
data="pong",
)


auth_router = Router(auth=AuthLoggedInUser())


@auth_router.get(
"/auth",
response={
HttpStatusCode.OK: str,
HttpStatusCode.BAD_REQUEST: str,
},
)
def auth_ping(request: HttpRequest):
return AraResponse(
status_code=HttpStatusCode.OK,
data="pong",
)
10 changes: 10 additions & 0 deletions ara/controller/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.urls import path

from ara.controller.api import api

urlpatterns = [
path(
"",
api.urls,
)
]
5 changes: 5 additions & 0 deletions ara/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""

from django.conf import settings
from django.contrib import admin
from django.urls import include, path
Expand All @@ -22,6 +23,8 @@
SpectacularSwaggerView,
)

from .controller import urls as v2_urls

urlpatterns = [
path("api/admin/", admin.site.urls),
path("", include(("apps.core.urls", "core"))),
Expand All @@ -41,6 +44,8 @@
),
]

urlpatterns.extend(v2_urls.urlpatterns)

if settings.DEBUG:
urlpatterns += [
path("api/__debug__/", include("debug_toolbar.urls")),
Expand Down
Loading