|
| 1 | +"""Sponsor API.""" |
| 2 | + |
| 3 | +from http import HTTPStatus |
| 4 | +from typing import Literal |
| 5 | + |
| 6 | +from django.conf import settings |
| 7 | +from django.http import HttpRequest |
| 8 | +from django.views.decorators.cache import cache_page |
| 9 | +from ninja import Field, FilterSchema, Path, Query, Router, Schema |
| 10 | +from ninja.decorators import decorate_view |
| 11 | +from ninja.pagination import PageNumberPagination, paginate |
| 12 | +from ninja.responses import Response |
| 13 | + |
| 14 | +from apps.owasp.models.sponsor import Sponsor |
| 15 | + |
| 16 | +router = Router() |
| 17 | + |
| 18 | + |
| 19 | +class SponsorErrorResponse(Schema): |
| 20 | + """Sponsor error response schema.""" |
| 21 | + |
| 22 | + message: str |
| 23 | + |
| 24 | + |
| 25 | +class SponsorFilterSchema(FilterSchema): |
| 26 | + """Filter schema for Sponsor.""" |
| 27 | + |
| 28 | + is_member: bool | None = Field( |
| 29 | + None, |
| 30 | + description="Member status of the sponsor", |
| 31 | + ) |
| 32 | + member_type: Sponsor.MemberType | None = Field( |
| 33 | + None, |
| 34 | + description="Member type of the sponsor", |
| 35 | + ) |
| 36 | + |
| 37 | + sponsor_type: str | None = Field( |
| 38 | + None, |
| 39 | + description="Filter by the type of sponsorship (e.g., Gold, Silver, Platinum).", |
| 40 | + example="Silver", |
| 41 | + ) |
| 42 | + |
| 43 | + |
| 44 | +class SponsorSchema(Schema): |
| 45 | + """Schema for Sponsor.""" |
| 46 | + |
| 47 | + description: str |
| 48 | + image_url: str |
| 49 | + is_member: bool |
| 50 | + job_url: str |
| 51 | + key: str |
| 52 | + member_type: str |
| 53 | + name: str |
| 54 | + sponsor_type: str |
| 55 | + url: str |
| 56 | + |
| 57 | + |
| 58 | +@router.get( |
| 59 | + "/", |
| 60 | + description="Retrieve a paginated list of OWASP sponsors.", |
| 61 | + operation_id="list_sponsors", |
| 62 | + response={HTTPStatus.OK: list[SponsorSchema]}, |
| 63 | + summary="List sponsors", |
| 64 | + tags=["Sponsors"], |
| 65 | +) |
| 66 | +@decorate_view(cache_page(settings.API_CACHE_TIME_SECONDS)) |
| 67 | +@paginate(PageNumberPagination, page_size=settings.API_PAGE_SIZE) |
| 68 | +def list_sponsors( |
| 69 | + request: HttpRequest, |
| 70 | + filters: SponsorFilterSchema = Query(...), |
| 71 | + ordering: Literal["name", "-name"] | None = Query( |
| 72 | + None, |
| 73 | + description="Ordering field", |
| 74 | + ), |
| 75 | +) -> list[SponsorSchema]: |
| 76 | + """Get sponsors.""" |
| 77 | + return filters.filter(Sponsor.objects.order_by(ordering or "name")) |
| 78 | + |
| 79 | + |
| 80 | +@router.get( |
| 81 | + "/{str:sponsor_key}", |
| 82 | + description="Retrieve a sponsor details.", |
| 83 | + operation_id="get_sponsor", |
| 84 | + response={ |
| 85 | + HTTPStatus.NOT_FOUND: SponsorErrorResponse, |
| 86 | + HTTPStatus.OK: SponsorSchema, |
| 87 | + }, |
| 88 | + summary="Get sponsor", |
| 89 | + tags=["Sponsors"], |
| 90 | +) |
| 91 | +def get_sponsor( |
| 92 | + request: HttpRequest, |
| 93 | + sponsor_key: str = Path(..., example="adobe"), |
| 94 | +) -> SponsorSchema | SponsorErrorResponse: |
| 95 | + """Get sponsor.""" |
| 96 | + if sponsor := Sponsor.objects.filter(key__iexact=sponsor_key).first(): |
| 97 | + return sponsor |
| 98 | + |
| 99 | + return Response({"message": "Sponsor not found"}, status=HTTPStatus.NOT_FOUND) |
0 commit comments