Actually save something to the DB

This commit is contained in:
Klaas van Schelven
2023-11-03 19:56:36 +01:00
parent a0177a1f26
commit 1e7ec4c1f4
15 changed files with 131 additions and 10 deletions

View File

@@ -1,3 +1,8 @@
from django.contrib import admin
# Register your models here.
from .models import DecompressedEvent
@admin.register(DecompressedEvent)
class DecompressedEventAdmin(admin.ModelAdmin):
list_display = ["timestamp", "project"]

View File

@@ -0,0 +1,21 @@
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='DecompressedEvent',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('data', models.TextField()),
('timestamp', models.DateTimeField(auto_now_add=True, help_text='Server-side timestamp')),
],
),
]

View File

@@ -0,0 +1,18 @@
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('projects', '0001_initial'),
('ingest', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='decompressedevent',
name='project',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='projects.project'),
),
]

View File

@@ -1,3 +1,13 @@
import uuid
from django.db import models
# Create your models here.
from projects.models import Project
class DecompressedEvent(models.Model):
"""Ingested Event, no processing"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
project = models.ForeignKey(Project, blank=False, null=True, on_delete=models.SET_NULL) # SET_NULL: cleanup 'later'
data = models.TextField(blank=False, null=False)
timestamp = models.DateTimeField(null=False, auto_now_add=True, help_text="Server-side timestamp")

View File

@@ -9,10 +9,12 @@ class IgnoreClientContentNegotiation(BaseContentNegotiation):
"""
Select the first parser in the `.parser_classes` list.
"""
# TODO double-check and write down why this is the correct thing
return parsers[0]
def select_renderer(self, request, renderers, format_suffix):
"""
Select the first renderer in the `.renderer_classes` list.
"""
# TODO double-check and write down why this is the correct thing
return (renderers[0], renderers[0].media_type)

View File

@@ -1,12 +1,15 @@
from rest_framework import permissions
from rest_framework import permissions, status
from rest_framework.response import Response
from rest_framework.views import APIView
# from projects.models import Project
# from sentry.utils.auth import parse_auth_header
from projects.models import Project
from .negotiation import IgnoreClientContentNegotiation
from .parsers import EnvelopeParser
from .models import DecompressedEvent
class BaseIngestAPIView(APIView):
@@ -15,15 +18,31 @@ class BaseIngestAPIView(APIView):
content_negotiation_class = IgnoreClientContentNegotiation
http_method_names = ["post"]
def post(self, request, *args, **kwargs):
import pdb; pdb.set_trace()
# return self.process_event(request.data, request, project)
return Response()
def process_event(self, event_data, request, project):
DecompressedEvent.objects.create(project=project, data=event_data)
class IngestEventAPIView(BaseIngestAPIView):
pass
def post(self, request, *args, **kwargs):
project = Project.objects.first() # TODO actually parse project header
self.process_event(request.data, request, project)
return Response()
class IngestEnvelopeAPIView(BaseIngestAPIView):
parser_classes = [EnvelopeParser]
def post(self, request, *args, **kwargs):
project = Project.objects.first() # TODO actually parse project header
if len(request.data) != 3:
# multi-part envelopes trigger an error too
return Response({"message": "Missing headers / unsupported type"}, status=status.HTTP_501_NOT_IMPLEMENTED)
if request.data[1].get("type") != "event":
return Response({"message": "Only events are supported"}, status=status.HTTP_501_NOT_IMPLEMENTED)
event = request.data[2]
self.process_event(event, request, project)
return Response()

View File

@@ -15,7 +15,7 @@ SECRET_KEY = 'django-insecure-$@clhhieazwnxnha-_zah&(bieq%yux7#^07&xsvhn58t)8@xw
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
ALLOWED_HOSTS = ["*"] # SECURITY WARNING: also make production-worthy
# Application definition
@@ -28,6 +28,7 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'projects',
'ingest',
]
@@ -113,7 +114,7 @@ STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
# no support for uuid in this setting yet (https://code.djangoproject.com/ticket/32577) so we leave it as-is
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

0
projects/__init__.py Normal file
View File

8
projects/admin.py Normal file
View File

@@ -0,0 +1,8 @@
from django.contrib import admin
from .models import Project
@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
pass

6
projects/apps.py Normal file
View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class ProjectsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'projects'

View File

@@ -0,0 +1,19 @@
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Project',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
],
),
]

View File

6
projects/models.py Normal file
View File

@@ -0,0 +1,6 @@
import uuid
from django.db import models
class Project(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

3
projects/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
projects/views.py Normal file
View File

@@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.