Blame view

pyros_api.py 6.38 KB
4b904014   Alexis Koralewski   Add view to get s...
1
#!/usr/bin/env python3
0318e3c9   Alexis Koralewski   Add tests for F05...
2
import os
0e621584   Alexis Koralewski   adding host optio...
3
4
from urllib3.exceptions import ProtocolError
from requests.exceptions import ConnectionError
0318e3c9   Alexis Koralewski   Add tests for F05...
5
6
7
8
9
10
import requests
import sys
import yaml
import click
import getpass

98621b46   Alexis Koralewski   add DRF, pyros ap...
11
12
13
14
15

class PyrosAPI:
    """
    Request Pyros API with an PyrosUser account linked to the username and password
    """
0e621584   Alexis Koralewski   adding host optio...
16
    #host = "http://pyros.irap.omp.eu/api/"
4b904014   Alexis Koralewski   Add view to get s...
17

0e621584   Alexis Koralewski   adding host optio...
18
    def __init__(self, host) -> None:
98621b46   Alexis Koralewski   add DRF, pyros ap...
19
20
21
22
23
24
25
        """
        Initialize PyrosAPI class by getting the authentification token required to use the API

        Args:
            username : Username of the user (mail adress)
            password : Password of the user
        """
0e621584   Alexis Koralewski   adding host optio...
26
27
28
29
30
        if host == None:
            self.host = "http://localhost:8000"
        else:
            self.host = host
        self.host = self.host+"/api/"
0318e3c9   Alexis Koralewski   Add tests for F05...
31
        self.get_token()
98621b46   Alexis Koralewski   add DRF, pyros ap...
32

0318e3c9   Alexis Koralewski   Add tests for F05...
33
    def get_token(self):
98621b46   Alexis Koralewski   add DRF, pyros ap...
34
35
36
37
38
39
40
        """
        get the authentification token linked to the user account

        Args:
            username : Username of the user (mail adress)
            password : Password of the user
        """
0318e3c9   Alexis Koralewski   Add tests for F05...
41
42
43
44
45
        if os.path.exists("TOKEN"):
            with open("TOKEN", "r") as token_file:
                self.token = token_file.read()
                return
        else:
0e621584   Alexis Koralewski   adding host optio...
46
            url = f"{self.host}api-token-auth/"
0318e3c9   Alexis Koralewski   Add tests for F05...
47
48
            print("Token needs to be generated, you need to authentificate to PyROS :")
            username = input("Enter your username: ")
0318e3c9   Alexis Koralewski   Add tests for F05...
49
50
51
52
            try:
                password = getpass.getpass()
            except Exception as error:
                print('ERROR', error)
0e621584   Alexis Koralewski   adding host optio...
53
54
55
56
57
58
59
60
61
62
63
64
65
66
            try:
                request = requests.post(
                    url, data={"username": username, "password": password})
            except (ConnectionError, ConnectionResetError, ProtocolError):
                print(
                    f"Server {self.host} doesn't respond. The website might be down.")
                exit(1)
            if request.status_code != 200:
                print("Authentification failed, please retry")
                exit(1)
            json_response = request.json()
            self.token = json_response["token"]
            with open("TOKEN", "w+") as token_file:
                token_file.write(self.token)
98621b46   Alexis Koralewski   add DRF, pyros ap...
67

4b904014   Alexis Koralewski   Add view to get s...
68
    def get_url(self, url: str) -> dict:
98621b46   Alexis Koralewski   add DRF, pyros ap...
69
70
71
72
73
74
75
76
77
        """
        Query the url and return the response as json

        Args:
            url : Url to be requested without the base url of the website 

        Returns:
            dict : Json object that represents the response of the API
        """
0318e3c9   Alexis Koralewski   Add tests for F05...
78
        headers = {"Authorization": f"Token {self.token}"}
0e621584   Alexis Koralewski   adding host optio...
79
80
81
82
83
84
        try:
            request = requests.get(self.host+url, headers=headers)
        except (ConnectionError, ConnectionResetError, ProtocolError):
            print(
                f"Server {self.host} doesn't respond. The website might be down.")
            exit(1)
98621b46   Alexis Koralewski   add DRF, pyros ap...
85
86
        return request.json()

4b904014   Alexis Koralewski   Add view to get s...
87
    def submit_sequence_file(self, file: str) -> dict:
98621b46   Alexis Koralewski   add DRF, pyros ap...
88
89
90
91
92
93
94
95
96
97
        """
        Submit sequence file by querying the API via PUT method

        Args:
            file : File path to the sequence file to be uploaded

        Returns:
            dict : Json object that represents the response of the API
        """
        headers = {
0318e3c9   Alexis Koralewski   Add tests for F05...
98
            "Authorization": f"Token {self.token}",
98621b46   Alexis Koralewski   add DRF, pyros ap...
99
100
            'Content-type': 'application/json',
        }
0e621584   Alexis Koralewski   adding host optio...
101
        url = f"{self.host}submit_sequence"
4b904014   Alexis Koralewski   Add view to get s...
102
        yaml_file = open(file, "r")
98621b46   Alexis Koralewski   add DRF, pyros ap...
103
104
        sequence_file_as_dict = yaml.safe_load(yaml_file)
        print(f"File content : {sequence_file_as_dict}")
0e621584   Alexis Koralewski   adding host optio...
105
106
107
108
109
110
111
        try:
            request = requests.put(url, headers=headers,
                                   json=sequence_file_as_dict)
        except (ConnectionError, ConnectionResetError, ProtocolError):
            print(
                f"Server {self.host} doesn't respond. The website might be down.")
            exit(1)
98621b46   Alexis Koralewski   add DRF, pyros ap...
112
113
114
        print(f"Request status code {request.status_code}")
        return request.json()

0318e3c9   Alexis Koralewski   Add tests for F05...
115
    def get_sequences_for_period(self, start_date: str, end_date: str) -> dict:
4b904014   Alexis Koralewski   Add view to get s...
116
117
118
119
120
121
122
123
        """
        Return all the sequence between two dates
        Args:
            start_date : start date of the period we want to retrieve (format : day/month/year, example : 13/02/2022)
            end_date : end date of the period we want to retrieve (same format as start_date)
        Returns:
            dict : Json object that represents the response of the API
        """
0e621584   Alexis Koralewski   adding host optio...
124
        url = f"{self.host}full_sequences/get_sequences_for_period/"
4b904014   Alexis Koralewski   Add view to get s...
125
        headers = {"Authorization": f"Token {self.token}"}
0e621584   Alexis Koralewski   adding host optio...
126
127
128
129
130
131
132
        try:
            response = requests.get(
                url, params={"start_date": start_date, "end_date": end_date}, headers=headers)
        except (ConnectionError, ConnectionResetError, ProtocolError):
            print(
                f"Server {self.host} doesn't respond. The website might be down.")
            exit(1)
4b904014   Alexis Koralewski   Add view to get s...
133
134
        return response.json()

0318e3c9   Alexis Koralewski   Add tests for F05...
135
    def logout(self):
0e621584   Alexis Koralewski   adding host optio...
136
        url = f"{self.host}logout/"
0318e3c9   Alexis Koralewski   Add tests for F05...
137
        header = {"Authorization": f"Token {self.token}"}
0e621584   Alexis Koralewski   adding host optio...
138
139
140
141
142
143
        try:
            response = requests.get(url, headers=header)
        except (ConnectionError, ConnectionResetError, ProtocolError):
            print(
                f"Server {self.host} doesn't respond. The website might be down.")
            exit(1)
0318e3c9   Alexis Koralewski   Add tests for F05...
144
145
146
        return response.content.decode("utf-8")


4b904014   Alexis Koralewski   Add view to get s...
147
@click.group()
0e621584   Alexis Koralewski   adding host optio...
148
@click.option('--host', '-h', help='host name (example: http://localhost:8000 or http://pyros.omp.eu) without last slash')
4b904014   Alexis Koralewski   Add view to get s...
149
@click.pass_context
0e621584   Alexis Koralewski   adding host optio...
150
151
152
153
def cli(ctx, host):
    if not host:
        host = None
    ctx.obj = PyrosAPI(host)
4b904014   Alexis Koralewski   Add view to get s...
154
155


c658ec80   Alexis Koralewski   Rename command fo...
156
@cli.command("get_sequences_for_period", help="Get sequences for a period of date (start/end)")
4b904014   Alexis Koralewski   Add view to get s...
157
158
159
160
161
162
163
164
@click.argument("start_date")
@click.argument("end_date")
@click.pass_obj
def get_sequences_for_period(api, start_date: str, end_date: str):
    response = api.get_sequences_for_period(start_date, end_date)
    print(response)


0318e3c9   Alexis Koralewski   Add tests for F05...
165
166
167
168
169
170
171
172
173
174
175
@cli.command("logout", help="Logout")
@click.pass_obj
def logout(api):
    response = api.logout()
    if os.path.exists("TOKEN"):
        os.remove("TOKEN")
    print("Token deleted")
    print(response)


@cli.command("submit_sequence", help="Submit a sequence file")
4b904014   Alexis Koralewski   Add view to get s...
176
177
178
179
180
181
@click.argument("file_path")
@click.pass_obj
def submit_sequence(api, file_path):
    response = api.submit_sequence_file(file_path)
    print(response)

0318e3c9   Alexis Koralewski   Add tests for F05...
182
183

@cli.command("query_url", help="Query an url to retrieve data")
4b904014   Alexis Koralewski   Add view to get s...
184
185
186
187
188
189
@click.argument("url")
@click.pass_obj
def query_url(api, url):
    response = api.get_url(url)
    print(response)

0318e3c9   Alexis Koralewski   Add tests for F05...
190

4b904014   Alexis Koralewski   Add view to get s...
191
192
if __name__ == '__main__':
    cli(obj={})