Skip to content

Commit

Permalink
feat: add django ninja base controller
Browse files Browse the repository at this point in the history
  • Loading branch information
hyukychang committed May 1, 2024
1 parent db015c3 commit 34d2084
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 3 deletions.
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

0 comments on commit 34d2084

Please sign in to comment.