Commit 4b90401445f9dddaf044fba9f95dc89a1360bdcd

Authored by Alexis Koralewski
1 parent c2589779
Exists in dev

Add view to get sequences for a period and improving pyros_api.py

  1 +21-02-2022 (AKo): v0.3.8.0
  2 + - Improve pyros_api with (click) commands
  3 + - Add view to get all sequences within a date period (start_date and end_date)
  4 +
1 18-02-2022 (AKo): v0.3.7.0 5 18-02-2022 (AKo): v0.3.7.0
2 - Add API url to get a full sequence (i.e. with albums and plans) 6 - Add API url to get a full sequence (i.e. with albums and plans)
3 - Add API urls for querying Plan and Album models 7 - Add API urls for querying Plan and Album models
1 -0.3.7.0  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +0.3.8.0
3 \ No newline at end of file 3 \ No newline at end of file
pyros_api.py 100644 → 100755
1 -import requests, sys, yaml 1 +#!/usr/bin/env python3
  2 +import requests, sys, yaml, click
2 3
3 class PyrosAPI: 4 class PyrosAPI:
4 """ 5 """
5 Request Pyros API with an PyrosUser account linked to the username and password 6 Request Pyros API with an PyrosUser account linked to the username and password
6 """ 7 """
7 BASE_PYROS_URL = "http://localhost:8000/api/" 8 BASE_PYROS_URL = "http://localhost:8000/api/"
8 - def __init__(self, username : str, password : str ) -> None: 9 +
  10 + def __init__(self, username: str, password: str) -> None:
9 """ 11 """
10 Initialize PyrosAPI class by getting the authentification token required to use the API 12 Initialize PyrosAPI class by getting the authentification token required to use the API
11 13
@@ -15,8 +17,7 @@ class PyrosAPI: @@ -15,8 +17,7 @@ class PyrosAPI:
15 """ 17 """
16 self.get_token(username, password) 18 self.get_token(username, password)
17 19
18 -  
19 - def get_token(self,username : str,password : str): 20 + def get_token(self, username: str, password: str):
20 """ 21 """
21 get the authentification token linked to the user account 22 get the authentification token linked to the user account
22 23
@@ -25,12 +26,12 @@ class PyrosAPI: @@ -25,12 +26,12 @@ class PyrosAPI:
25 password : Password of the user 26 password : Password of the user
26 """ 27 """
27 url = f"{self.BASE_PYROS_URL}api-token-auth/" 28 url = f"{self.BASE_PYROS_URL}api-token-auth/"
28 - request = requests.post(url, data={"username":username,"password":password}) 29 + request = requests.post(url, data={"username": username, "password": password})
29 json_response = request.json() 30 json_response = request.json()
30 self.token = json_response["token"] 31 self.token = json_response["token"]
31 print(f"Token is {self.token}") 32 print(f"Token is {self.token}")
32 33
33 - def get_url(self,url : str) -> dict: 34 + def get_url(self, url: str) -> dict:
34 """ 35 """
35 Query the url and return the response as json 36 Query the url and return the response as json
36 37
@@ -45,7 +46,7 @@ class PyrosAPI: @@ -45,7 +46,7 @@ class PyrosAPI:
45 request = requests.get(self.BASE_PYROS_URL+url, headers=headers) 46 request = requests.get(self.BASE_PYROS_URL+url, headers=headers)
46 return request.json() 47 return request.json()
47 48
48 - def submit_sequence_file(self,file : str) -> dict: 49 + def submit_sequence_file(self, file: str) -> dict:
49 """ 50 """
50 Submit sequence file by querying the API via PUT method 51 Submit sequence file by querying the API via PUT method
51 52
@@ -60,27 +61,57 @@ class PyrosAPI: @@ -60,27 +61,57 @@ class PyrosAPI:
60 'Content-type': 'application/json', 61 'Content-type': 'application/json',
61 } 62 }
62 url = f"{self.BASE_PYROS_URL}submit_sequence" 63 url = f"{self.BASE_PYROS_URL}submit_sequence"
63 - yaml_file = open(file,"r") 64 + yaml_file = open(file, "r")
64 sequence_file_as_dict = yaml.safe_load(yaml_file) 65 sequence_file_as_dict = yaml.safe_load(yaml_file)
65 print(f"File content : {sequence_file_as_dict}") 66 print(f"File content : {sequence_file_as_dict}")
66 request = requests.put(url, headers=headers, json=sequence_file_as_dict) 67 request = requests.put(url, headers=headers, json=sequence_file_as_dict)
67 print(f"Request status code {request.status_code}") 68 print(f"Request status code {request.status_code}")
68 return request.json() 69 return request.json()
69 70
70 -  
71 -def main():  
72 - username = sys.argv[1]  
73 - password = sys.argv[2]  
74 - url = sys.argv[3]  
75 - yaml_file = None  
76 - api = PyrosAPI(username,password)  
77 - if len(sys.argv) > 4 and sys.argv[4]:  
78 - yaml_file = sys.argv[4]  
79 - print(api.submit_sequence_file(yaml_file))  
80 - else:  
81 - print(username,password,url)  
82 - print(api.get_url(url))  
83 -  
84 -  
85 -if __name__ == "__main__":  
86 - main() 71 + def get_sequences_for_period(self, start_date:str, end_date:str) -> dict:
  72 + """
  73 + Return all the sequence between two dates
  74 + Args:
  75 + start_date : start date of the period we want to retrieve (format : day/month/year, example : 13/02/2022)
  76 + end_date : end date of the period we want to retrieve (same format as start_date)
  77 + Returns:
  78 + dict : Json object that represents the response of the API
  79 + """
  80 + url = f"{self.BASE_PYROS_URL}full_sequences/get_sequences_for_period/"
  81 + headers = {"Authorization": f"Token {self.token}"}
  82 + response = requests.get(url, params={"start_date": start_date, "end_date": end_date}, headers=headers)
  83 + return response.json()
  84 +
  85 +@click.group()
  86 +@click.argument("username")
  87 +@click.argument("password")
  88 +@click.pass_context
  89 +def cli(ctx, username, password):
  90 + ctx.obj = PyrosAPI(username, password)
  91 +
  92 +
  93 +@cli.command("get_sequences")
  94 +@click.argument("start_date")
  95 +@click.argument("end_date")
  96 +@click.pass_obj
  97 +def get_sequences_for_period(api, start_date: str, end_date: str):
  98 + response = api.get_sequences_for_period(start_date, end_date)
  99 + print(response)
  100 +
  101 +
  102 +@cli.command("submit_sequence")
  103 +@click.argument("file_path")
  104 +@click.pass_obj
  105 +def submit_sequence(api, file_path):
  106 + response = api.submit_sequence_file(file_path)
  107 + print(response)
  108 +
  109 +@cli.command("query_url")
  110 +@click.argument("url")
  111 +@click.pass_obj
  112 +def query_url(api, url):
  113 + response = api.get_url(url)
  114 + print(response)
  115 +
  116 +if __name__ == '__main__':
  117 + cli(obj={})
src/core/pyros_django/api/urls.py
1 from django.urls import path, include 1 from django.urls import path, include
2 from . import views 2 from . import views
3 from rest_framework.authtoken.views import obtain_auth_token 3 from rest_framework.authtoken.views import obtain_auth_token
4 -from rest_framework import routers 4 +from rest_framework import routers, renderers
5 5
6 router = routers.DefaultRouter() 6 router = routers.DefaultRouter()
7 router.register(r'users', views.UserViewSet) 7 router.register(r'users', views.UserViewSet)
src/core/pyros_django/api/views.py
1 from django.shortcuts import render 1 from django.shortcuts import render
2 from rest_framework.views import APIView 2 from rest_framework.views import APIView
3 from rest_framework.response import Response 3 from rest_framework.response import Response
4 -from rest_framework import viewsets 4 +from rest_framework import viewsets, renderers
5 from rest_framework.permissions import IsAuthenticated, AllowAny 5 from rest_framework.permissions import IsAuthenticated, AllowAny
6 -from rest_framework.decorators import api_view, permission_classes 6 +from rest_framework.decorators import api_view, permission_classes, action
7 from django.core.validators import ValidationError 7 from django.core.validators import ValidationError
8 from src.core.pyros_django.user_manager import views as user_views 8 from src.core.pyros_django.user_manager import views as user_views
9 from api.serializers import AlbumSerializer, FullSequenceSerializer, PlanSerializer, SequenceSerializer, UserSerializer 9 from api.serializers import AlbumSerializer, FullSequenceSerializer, PlanSerializer, SequenceSerializer, UserSerializer
10 from common.models import PyrosUser, Sequence, Album, Plan, UserLevel, SP_Period_User 10 from common.models import PyrosUser, Sequence, Album, Plan, UserLevel, SP_Period_User
11 from routine_manager.functions import check_sequence_file_validity 11 from routine_manager.functions import check_sequence_file_validity
12 from rest_framework.request import Request 12 from rest_framework.request import Request
  13 +from django.db.models import Q
  14 +from datetime import datetime
13 15
14 # Create your views here. 16 # Create your views here.
15 17
@@ -104,6 +106,18 @@ class FullSequenceViewSet(viewsets.ModelViewSet): @@ -104,6 +106,18 @@ class FullSequenceViewSet(viewsets.ModelViewSet):
104 else: 106 else:
105 return Sequence.objects.filter(pyros_user=user).order_by("-updated") 107 return Sequence.objects.filter(pyros_user=user).order_by("-updated")
106 108
  109 + @action(detail=False, methods=["get"])
  110 + def get_sequences_for_period(self, request):
  111 + """
  112 + Return the list of sequences corresponding to the requested period
  113 + """
  114 + params = request.query_params
  115 + start_date = datetime.strptime(params.get("start_date"),"%d/%m/%Y")
  116 + end_date = datetime.strptime(params.get("end_date"),"%d/%m/%Y")
  117 + queryset = Sequence.objects.filter(Q(start_date__gte=start_date) | Q(start_date__lte=end_date))
  118 + serializer = self.get_serializer(queryset,many=True)
  119 + response = Response(serializer.data)
  120 + return response
107 121
108 class AlbumViewSet(viewsets.ModelViewSet): 122 class AlbumViewSet(viewsets.ModelViewSet):
109 """ 123 """