Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert server status endpoint to ninja #234

Merged
merged 1 commit into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions django/src/rdwatch/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .views.model_run import router as model_run_router
from .views.performer import router as performer_router
from .views.region import router as region_router
from .views.server_status import router as server_status_router
from .views.site_evaluation import router as site_evaluation_router
from .views.site_image import router as images_router
from .views.site_observation import router as site_observation_router
Expand All @@ -16,6 +17,7 @@
api.add_router('/performers/', performer_router)
api.add_router('/evaluations/images/', images_router)
api.add_router('/regions/', region_router)
api.add_router('/status/', server_status_router)


# useful for getting information back about validation errors
Expand Down
1 change: 0 additions & 1 deletion django/src/rdwatch/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
),
name='openapi-schema',
),
path('status', views.RetrieveServerStatus.as_view()), # type: ignore
path('satellite-image/timestamps', views.satelliteimage_time_list),
path('satellite-image/all-timestamps', views.all_satellite_timestamps),
path(
Expand Down
2 changes: 0 additions & 2 deletions django/src/rdwatch/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@
satelliteimage_visual_tile,
satelliteimage_visual_time_list,
)
from .server_status import RetrieveServerStatus
from .vector_tile import vector_tile

__all__ = [
'RetrieveServerStatus',
'satelliteimage_raster_tile',
'satelliteimage_raster_bbox',
'satelliteimage_time_list',
Expand Down
79 changes: 22 additions & 57 deletions django/src/rdwatch/views/server_status.py
Original file line number Diff line number Diff line change
@@ -1,70 +1,35 @@
import datetime
import socket
from dataclasses import dataclass

from rest_framework import permissions, serializers
from rest_framework.response import Response
from rest_framework.schemas.openapi import AutoSchema
from rest_framework.views import APIView

SERVER_INSTANCE_EPOCH = datetime.datetime.now()


@dataclass
class ServerStatus:
uptime: datetime.timedelta
hostname: str
ip: str
from ninja import Field, Router, Schema

from django.http import HttpRequest

class UptimeSerializer(serializers.Serializer):
iso8601 = serializers.DurationField(source='*')
days = serializers.IntegerField()
seconds = serializers.IntegerField()
useconds = serializers.IntegerField(source='microseconds')
router = Router()

SERVER_INSTANCE_EPOCH = datetime.datetime.now()

class ServerStatusSerializer(serializers.Serializer):
uptime = UptimeSerializer(required=True)
hostname = serializers.CharField(required=True)
ip = serializers.IPAddressField(required=True)

def create(self, validated_data):
instance = ServerStatus(
uptime=validated_data['uptime']['iso8601'],
hostname=validated_data['hostname'],
ip=validated_data['iso8601'],
)
# we'd save it here if this were a Django model
# instance.save()
return instance

def update(self, instance, validated_data):
instance.uptime = validated_data.get('uptime', instance.uptime)
instance.hostname = validated_data.get('hostname', instance.hostname)
instance.ip = validated_data.get('ip', instance.ip)
# we'd save it here if this were a Django model
# instance.save()
return instance

class UptimeSchema(Schema):
iso8601: str
days: int
seconds: int
useconds: int = Field(..., alias='microseconds')

class ServerStatusSchema(AutoSchema):
def get_operation_id(self, *args):
return 'getStatus'
@staticmethod
def resolve_iso8601(obj: datetime.timedelta):
return str(obj)
Comment on lines +19 to +21
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, this returns a slightly different string than the DRF serializer for datetime.timedelta. Previously, the return value would look something like 6 05:04:40.740791, but now it is 6 days, 05:04:40.740791.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In testing, I'm getting back an iso8601 duration format: "iso8601": "P0DT00H03M56.226221S" which I think is fine.


def get_serializer(self, *args):
return ServerStatusSerializer()

class ServerStatusSchema(Schema):
uptime: UptimeSchema
hostname: str
ip: str

class RetrieveServerStatus(APIView):
permission_classes = [permissions.AllowAny]
schema = ServerStatusSchema()
action = 'retrieve'

def get(self, request):
uptime = datetime.datetime.now() - SERVER_INSTANCE_EPOCH
hostname = socket.gethostname()
ip = socket.gethostbyname(hostname)
server_status = ServerStatus(uptime, hostname, ip)
serializer = ServerStatusSerializer(server_status)
return Response(serializer.data)
@router.get('/', response=ServerStatusSchema)
def get_status(request: HttpRequest):
uptime = datetime.datetime.now() - SERVER_INSTANCE_EPOCH
hostname = socket.gethostname()
ip = socket.gethostbyname(hostname)
return ServerStatusSchema(uptime=uptime, hostname=hostname, ip=ip)
Loading