Coverage for django_napse/api/spaces/views/space_view.py: 28%
95 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 HasFullAccessPermission, HasMasterKey, HasReadPermission
7from django_napse.api.custom_viewset import CustomViewSet
8from django_napse.api.spaces.serializers import SpaceDetailSerializer, SpaceMoneyFlowSerializer, SpaceSerializer
9from django_napse.core.models import NapseSpace
10from django_napse.utils.constants import EXCHANGE_TICKERS
11from django_napse.utils.errors import SpaceError
14class SpaceView(CustomViewSet):
15 permission_classes = [HasFullAccessPermission]
16 serializer_class = SpaceSerializer
18 def get_object(self):
19 return self.get_queryset().get(uuid=self.kwargs["pk"])
21 def get_queryset(self):
22 return NapseSpace.objects.all()
24 def get_serializer_class(self, *args, **kwargs):
25 actions: dict = {
26 "list": SpaceSerializer,
27 "retrieve": SpaceDetailSerializer,
28 "create": SpaceSerializer,
29 "update": SpaceSerializer,
30 "partial_update": SpaceSerializer,
31 "invest": SpaceMoneyFlowSerializer,
32 "withdraw": SpaceMoneyFlowSerializer,
33 }
34 result = actions.get(self.action, None)
35 return result if result else super().get_serializer_class()
37 def get_permissions(self):
38 match self.action:
39 case "retrieve":
40 return [HasReadPermission()]
41 case "list":
42 return [HasAPIKey()]
43 case "create":
44 return [HasMasterKey()]
46 case _:
47 return super().get_permissions()
49 def list(self, request):
50 api_key = self.get_api_key(request)
51 spaces = NapseSpace.objects.all() if api_key.is_master_key else NapseSpace.objects.filter(permissions__in=api_key.permissions.all())
52 serializer = self.get_serializer(spaces, many=True)
53 return Response(serializer.data, status=status.HTTP_200_OK)
55 def retrieve(self, request, pk=None):
56 instance = self.get_object()
57 serializer = self.get_serializer(instance)
58 return Response(serializer.data, status=status.HTTP_200_OK)
60 def create(self, request, *args, **kwargs):
61 serializer = self.serializer_class(data=request.data)
62 serializer.is_valid(raise_exception=True)
63 space = serializer.save()
64 serialized_space = self.get_serializer(space)
65 return Response(serialized_space.data, status=status.HTTP_201_CREATED)
67 def update(self, request, *args, **kwargs):
68 partial = kwargs.pop("partial", False)
69 instance = self.get_object()
71 serializer = self.get_serializer(instance=instance, data=request.data, partial=partial)
72 serializer.is_valid(raise_exception=True)
73 serializer.save()
74 return Response(status=status.HTTP_200_OK)
76 def partial_update(self, request, **kwargs):
77 """Partial update the connected user."""
78 return self.update(request, partial=True, **kwargs)
80 def delete(self, request, *args, **kwargs):
81 instance = self.get_object()
82 try:
83 instance.delete()
84 except SpaceError.DeleteError:
85 return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
86 return Response(status=status.HTTP_204_NO_CONTENT)
88 @action(detail=True, methods=["GET", "POST"])
89 def invest(self, request, pk=None):
90 """Endpoint to invest on space.
92 GET: Return all {ticker: amount} which can be invested in the space.
93 POST: Invest in the space.
94 """
95 space: NapseSpace = self.get_object()
96 if not space.testing:
97 return Response(status=status.HTTP_501_NOT_IMPLEMENTED)
99 exchange_name: str = space.exchange_account.exchange.name
101 match request.method:
102 case "GET":
103 possible_investments = [{"ticker": ticker, "amount": 1_000_000} for ticker in EXCHANGE_TICKERS.get(exchange_name)]
104 return Response(possible_investments, status=status.HTTP_200_OK)
106 case "POST":
107 space = self.get_object()
108 if not space.testing:
109 error_msg: str = "Investing in real is not allowed yet."
110 return Response(error_msg, status=status.HTTP_403_FORBIDDEN)
111 serializer = self.get_serializer(data=request.data, instance=space, side="INVEST")
112 serializer.is_valid(raise_exception=True)
113 serializer.save()
115 case _:
116 return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
118 return Response(status=status.HTTP_200_OK)
120 @action(detail=True, methods=["GET", "POST"])
121 def withdraw(self, request, pk=None):
122 """Endpoint to withdraw on space.
124 GET: Return all {ticker: amount} which can be withdrawn in the space.
125 POST: Withdraw from the space.
126 """
127 space: NapseSpace = self.get_object()
128 if not space.testing:
129 return Response(status=status.HTTP_501_NOT_IMPLEMENTED)
131 match request.method:
132 case "GET":
133 return Response(status=status.HTTP_200_OK)
134 case "POST":
135 return Response(status=status.HTTP_501_NOT_IMPLEMENTED)
136 case _:
137 return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)