diff --git a/peeringdb_api/serializer.py b/peeringdb_api/serializer.py new file mode 100644 index 0000000..e0f9081 --- /dev/null +++ b/peeringdb_api/serializer.py @@ -0,0 +1,32 @@ +from typing import Union + +from django.core.serializers.python import Serializer as PythonSerializer +from django.db.models import Model, QuerySet + + +class Serializer(PythonSerializer): + internal_use_only = False + + def start_serialization(self): + self._result = [] + + def get_dump_object(self, obj): + self._current['id'] = self._value_from_field(obj, obj._meta.pk) + return self._current + + def end_object(self, obj): + self._result.append(self.get_dump_object(obj)) + self._current = None + + def getvalue(self): + return self._result + + +def serialize_many(objects: Union[QuerySet, list[Model]]) -> list[dict]: + serializer = Serializer() + serializer.serialize(objects, many=True) + return serializer.getvalue() + + +def serialize(obj: Model) -> dict: + return serialize_many([obj])[0] diff --git a/peeringdb_api/views.py b/peeringdb_api/views.py index 91ea44a..8134edf 100644 --- a/peeringdb_api/views.py +++ b/peeringdb_api/views.py @@ -1,3 +1,32 @@ -from django.shortcuts import render +from django.db.models import IntegerField, QuerySet +from django.http import JsonResponse +from django.views.generic.list import BaseListView -# Create your views here. +from peeringdb_api.serializer import serialize_many + + +def format_for_field(field, value): + if isinstance(field, IntegerField): + return int(value) + + return value + + +class PeeringDBListView(BaseListView): + def get(self, request, *args, **kwargs): + queryset: QuerySet = self.model.objects.all() + + for k, v in self.request.GET.items(): + _, final_field, _, _ = queryset.query.names_to_path(k.split('__'), self.model._meta) + + try: + if k.endswith('__in'): + value = [format_for_field(final_field, i) for i in v.split(',')] + else: + value = format_for_field(final_field, v) + except ValueError: + return JsonResponse({'data': [], 'meta': {'error': 'Entity not found'}}, status=404) + + queryset = queryset.filter(**{k: value}) + + return JsonResponse({'data': serialize_many(queryset)}) diff --git a/peeringdb_mirror/settings/base.py b/peeringdb_mirror/settings/base.py index 1a1bbc8..2de4dba 100644 --- a/peeringdb_mirror/settings/base.py +++ b/peeringdb_mirror/settings/base.py @@ -20,12 +20,8 @@ BASE_DIR = Path(__file__).resolve().parent.parent # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', 'django_peeringdb', 'peeringdb_api', ] diff --git a/peeringdb_mirror/urls.py b/peeringdb_mirror/urls.py index 3f8d646..0e871ac 100644 --- a/peeringdb_mirror/urls.py +++ b/peeringdb_mirror/urls.py @@ -1,22 +1,20 @@ -""" -URL configuration for peeringdb_mirror project. - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/5.0/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: path('', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.urls import include, path - 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) -""" -from django.contrib import admin from django.urls import path +from django_peeringdb import models + +from peeringdb_api.views import PeeringDBListView urlpatterns = [ - path('admin/', admin.site.urls), + path('api/org', PeeringDBListView.as_view(model=models.Organization)), + path('api/fac', PeeringDBListView.as_view(model=models.Facility)), + path('api/net', PeeringDBListView.as_view(model=models.Network)), + path('api/ix', PeeringDBListView.as_view(model=models.InternetExchange)), + path('api/campus', PeeringDBListView.as_view(model=models.Campus)), + path('api/carrier', PeeringDBListView.as_view(model=models.Carrier)), + path('api/carrierfac', PeeringDBListView.as_view(model=models.CarrierFacility)), + path('api/ixfac', PeeringDBListView.as_view(model=models.InternetExchangeFacility)), + path('api/ixlan', PeeringDBListView.as_view(model=models.IXLan)), + path('api/ixpfx', PeeringDBListView.as_view(model=models.IXLanPrefix)), + path('api/netfac', PeeringDBListView.as_view(model=models.NetworkFacility)), + path('api/netixlan', PeeringDBListView.as_view(model=models.NetworkIXLan)), + path('api/poc', PeeringDBListView.as_view(model=models.NetworkContact)), ]