api.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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 Router, 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 .schema import (
  11. EnvelopeEventIngestSchema,
  12. EnvelopeHeaderSchema,
  13. EnvelopeSchema,
  14. EventIngestSchema,
  15. ItemHeaderSchema,
  16. )
  17. from .tasks import ingest_event, ingest_transaction
  18. router = Router()
  19. class EventIngestOut(Schema):
  20. event_id: str
  21. class EnvelopeIngestOut(Schema):
  22. id: str
  23. def check_status():
  24. if settings.EVENT_STORE_DEBUG:
  25. print(json.dumps(self.request.data))
  26. @router.post("/{project_id}/store/", response=EventIngestOut)
  27. async def event_store(
  28. request: HttpRequest,
  29. payload: EventIngestSchema,
  30. project_id: int,
  31. ):
  32. check_status()
  33. project = await get_project(request)
  34. ingest_event.delay(project.id, payload.dict())
  35. return {"event_id": payload.event_id.hex}
  36. @router.post("/{project_id}/envelope/", response=EnvelopeIngestOut, auth=event_auth)
  37. async def event_envelope(
  38. request: HttpRequest,
  39. payload: EnvelopeSchema,
  40. project_id: int,
  41. ):
  42. # GlitchTip supports only envelopes with a header, item header, event|transaction
  43. # Validate this and reject anything else
  44. if not len(payload) >= 3:
  45. raise ValidationError([{"message": "Envelope too small"}])
  46. header = payload[0] if isinstance(payload[0], EnvelopeHeaderSchema) else None
  47. item_header = payload[1] if isinstance(payload[1], ItemHeaderSchema) else None
  48. if not header or not item_header:
  49. raise ValidationError([{"message": "Envelope contains no usable data"}])
  50. event_id = header.event_id
  51. if item_header.type == "event":
  52. event = (
  53. payload[2] if isinstance(payload[2], EnvelopeEventIngestSchema) else None
  54. )
  55. if not event:
  56. raise ValidationError([{"message": "Envelope not valid"}])
  57. ingest_event.delay(project_id, event.dict())
  58. else: # transaction
  59. ingest_transaction.delay(project_id, {})
  60. if not hasattr(header, "event_id"):
  61. raise ValidationError([])
  62. return {"id": event_id.hex}
  63. @router.post("/{project_id}/security/", response=EventIngestOut)
  64. async def event_security(
  65. request: HttpRequest,
  66. payload: EventIngestSchema,
  67. project_id: int,
  68. ):
  69. check_status()