Coverage for django_napse/api/fleets/views/fleet_view.py: 26%
91 statements
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-12 13:49 +0000
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-12 13:49 +0000
1from rest_framework import status
2from rest_framework.decorators import action
3from rest_framework.response import Response
4from rest_framework_api_key.permissions import HasAPIKey
6from django_napse.api.custom_permissions import HasSpace
7from django_napse.api.custom_viewset import CustomViewSet
8from django_napse.api.fleets.serializers import FleetDetailSerializer, FleetMoneyFlowSerializer, FleetSerializer
9from django_napse.core.models import Fleet, NapseSpace
12class FleetView(CustomViewSet):
13 """View of a fleet.
15 Query parameters:
16 space: uuid of the space to filter on.
17 space_containers (bool): If True, list endpoint returns fleets for each space (default = True).
18 """
20 permission_classes = [HasAPIKey, HasSpace]
21 serializer_class = FleetSerializer
23 def get_queryset(self):
24 space_uuid = self.request.query_params.get("space", None)
25 if space_uuid is None:
26 return Fleet.objects.all()
27 self.get_space = NapseSpace.objects.get(uuid=space_uuid)
28 return self.get_space.fleets
30 def get_serializer_class(self, *args, **kwargs):
31 actions: dict = {
32 "list": FleetSerializer,
33 "retrieve": FleetDetailSerializer,
34 "create": FleetSerializer,
35 "invest": FleetMoneyFlowSerializer,
36 "withdraw": FleetMoneyFlowSerializer,
37 }
38 result = actions.get(self.action)
39 return result if result else super().get_serializer_class()
41 def get_permissions(self):
42 match self.action:
43 case "list" | "create":
44 return [HasAPIKey()]
45 case _:
46 return super().get_permissions()
48 def get_object(self):
49 uuid = self.kwargs.get("pk", None)
50 if uuid is None:
51 return super().get_object()
52 return Fleet.objects.get(uuid=uuid)
54 def _get_boolean_query_param(self, param: str) -> bool | None:
55 """Return None if a boolean cannot be found."""
56 if isinstance(param, bool):
57 return param
59 if not isinstance(param, str):
60 return None
62 match param.lower():
63 case "true" | "1":
64 return True
65 case "false" | "0":
66 return False
67 case _:
68 return None
70 def list(self, request):
71 space_containers = self._get_boolean_query_param(request.query_params.get("space_containers", True))
72 space_uuid = request.query_params.get("space", None)
73 api_key = self.get_api_key(request)
75 if not space_containers and api_key.is_master_key:
76 # Not space_containers mode is only available for master key
77 serializer = self.get_serializer(self.get_queryset(), many=True)
78 return Response(serializer.data, status=status.HTTP_200_OK)
80 # Get spaces from API key
81 spaces = NapseSpace.objects.all() if api_key.is_master_key else [permission.space for permission in api_key.permissions.all()]
82 # Filter by specific space
83 if space_uuid is not None:
84 space = NapseSpace.objects.get(uuid=space_uuid)
85 if space not in spaces:
86 return Response(status=status.HTTP_403_FORBIDDEN)
87 spaces = [space]
89 # Fleet list
90 fleets = []
91 for space in spaces:
92 serializer = self.get_serializer(space.fleets, many=True, space=space)
93 if serializer.data != []:
94 fleets += serializer.data
95 return Response(fleets, status=status.HTTP_200_OK)
97 def retrieve(self, request, pk=None):
98 instance = self.get_object()
99 space = self.get_space(request)
100 serializer = self.get_serializer(instance, space=space)
101 return Response(serializer.data, status=status.HTTP_200_OK)
103 def create(self, request, *args, **kwargs):
104 serializer = self.get_serializer(data=request.data)
105 serializer.is_valid(raise_exception=True)
106 fleet = serializer.save()
107 space = serializer.space
108 fleet.invest(space, 0, "USDT")
109 return Response(serializer.data, status=status.HTTP_201_CREATED)
111 def delete(self):
112 return Response(status=status.HTTP_501_NOT_IMPLEMENTED)
114 @action(detail=True, methods=["post"])
115 def invest(self, request, pk=None):
116 fleet = self.get_object()
117 space = self.get_space(request)
119 if not space.testing:
120 error_msg: str = "Investing in real is not allowed yet."
121 return Response(error_msg, status=status.HTTP_403_FORBIDDEN)
123 serializer = self.get_serializer(
124 data=request.data,
125 instance=fleet,
126 space=space,
127 side="INVEST",
128 )
129 serializer.is_valid(raise_exception=True)
130 serializer.save()
132 return Response(status=status.HTTP_200_OK)
134 @action(detail=True, methods=["post"])
135 def withdraw(self, request, pk=None):
136 return Response(status=status.HTTP_501_NOT_IMPLEMENTED)