api.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import json
  2. import uuid
  3. from urllib.parse import urlparse
  4. from django.conf import settings
  5. from django.http import HttpRequest
  6. from ninja import NinjaAPI, Schema
  7. from ninja.errors import AuthenticationError, HttpError, ValidationError
  8. from projects.models import Project
  9. from .authentication import event_auth, get_project
  10. from .data_models import EnvelopeSchema, EventIngestSchema
  11. from .exceptions import ThrottleException
  12. from .parsers import EnvelopeParser
  13. from .renderers import ORJSONRenderer
  14. from .tasks import ingest_event
  15. api = NinjaAPI(parser=EnvelopeParser(), renderer=ORJSONRenderer())
  16. @api.exception_handler(ThrottleException)
  17. def throttled(request: HttpRequest, exc: ThrottleException):
  18. response = api.create_response(
  19. request,
  20. {"message": "Please retry later"},
  21. status=429,
  22. )
  23. if retry_after := exc.retry_after:
  24. if isinstance(retry_after, int):
  25. response["Retry-After"] = retry_after
  26. else:
  27. response["Retry-After"] = retry_after.strftime("%a, %d %b %Y %H:%M:%S GMT")
  28. return response
  29. class EventIngestOut(Schema):
  30. event_id: str
  31. def check_status():
  32. if settings.EVENT_STORE_DEBUG:
  33. print(json.dumps(self.request.data))
  34. @api.post("/{project_id}/store/", response=EventIngestOut)
  35. async def event_store(
  36. request: HttpRequest,
  37. payload: EventIngestSchema,
  38. project_id: int,
  39. ):
  40. check_status()
  41. project = await get_project(request)
  42. res = ingest_event.delay(project.id, payload.dict())
  43. return {"event_id": payload.event_id.hex}
  44. @api.post("/{project_id}/envelope/", response=EventIngestOut, auth=event_auth)
  45. async def event_envelope(
  46. request: HttpRequest,
  47. payload: EnvelopeSchema,
  48. project_id: int,
  49. ):
  50. header = payload[0]
  51. if not hasattr(header, "event_id"):
  52. raise ValidationError([])
  53. event_id = header.event_id
  54. return {"event_id": event_id.hex}
  55. @api.post("/{project_id}/security/", response=EventIngestOut)
  56. async def event_security(
  57. request: HttpRequest,
  58. payload: EventIngestSchema,
  59. project_id: int,
  60. ):
  61. check_status()