modify 1st project and rest
This commit is contained in:
parent
559539cc65
commit
3248e48d50
@ -26,23 +26,27 @@ On met un **shebang** en 1ère ligne pour indiquer la version de python.
|
|||||||
|
|
||||||
Dans ce script on déclare deux variables, qu'on nomme `base_url`et `endpoint1`, auxquelles on donne une valeur.
|
Dans ce script on déclare deux variables, qu'on nomme `base_url`et `endpoint1`, auxquelles on donne une valeur.
|
||||||
|
|
||||||
```
|
!!! note "main.py"
|
||||||
#!/usr/bin/env python3
|
```
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
base_url = "https://gitlab.com/api/v4"
|
api_url = "https://gitlab.com/api/v4"
|
||||||
print(base_url)
|
print(api_url)
|
||||||
endpoint1 = base_url + "/groups"
|
dataset = "/groups"
|
||||||
print(endpoint1)
|
print(dataset)
|
||||||
```
|
endpoint = api_url + dataset
|
||||||
|
print(endpoint)
|
||||||
|
```
|
||||||
|
|
||||||
On peut simplement exécuter ce script avec `python poi.py` ou l'exécuter en mode **interactif** (-i) pour continuer à manipuler les variables et les fonctions du programme:
|
On peut simplement exécuter ce script avec `python main.py` ou l'exécuter en mode **interactif** (-i) pour continuer à manipuler les variables et les fonctions du programme:
|
||||||
|
|
||||||
```
|
```
|
||||||
user@host:~$ python -i main.py
|
user@host:~$ python -i main.py
|
||||||
https://gitlab.com/api/v4
|
https://gitlab.com/api/v4
|
||||||
|
/groups
|
||||||
https://gitlab.com/api/v4/groups
|
https://gitlab.com/api/v4/groups
|
||||||
>>>
|
>>>
|
||||||
>>> type(endpoint1)
|
>>> type(endpoint)
|
||||||
<class 'str'>
|
<class 'str'>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@ -15,22 +15,6 @@ L'API utilisée, appellée REST API communique avec le site web par des requête
|
|||||||
Nous allons utiliser l'APi de Gitlab qui contient énormément d'informations sur les projets hébergés.
|
Nous allons utiliser l'APi de Gitlab qui contient énormément d'informations sur les projets hébergés.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Générer un jeton d'authentification
|
|
||||||
|
|
||||||
Pour accéder aux données présentées par l'API (par exemple, la liste des 'issues' qui me sont attribuées),
|
|
||||||
Gitlab a besoin de m'identifier.
|
|
||||||
|
|
||||||
Pour cela, à partir de notre interface web utilisateur de Gitlab, nous allons générer un **jeton d'authentification**.
|
|
||||||
|
|
||||||
Vous pouvez utiliser ce [tutoriel pour générer votre jeton d'API](https://screenful.com/gitlab/gitlab-apikey){target=_blank}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
@ -84,13 +68,260 @@ Dans notre fichier `main.py` nous devons maintenant importer les libraires
|
|||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
|
|
||||||
base_url = "https://gitlab.com/api/v4"
|
api_url = "https://gitlab.com/api/v4"
|
||||||
endpoint1 = base_url + "/groups"
|
dataset = "/groups"
|
||||||
|
endpoint = api_url + dataset
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Accès à l'API
|
## Accès à l'API
|
||||||
|
|
||||||
Nous allons ajouter à notre code une fonction, issue de la bibliothèque requests, pour accéder aux données via l'API REST.
|
Nous allons maintenant éxecuter ce code en mode interactif, et accéder à l'API dans la console python:
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
user@host:~$ python -i main.py
|
||||||
|
>>> r = requests.get(endpoint)
|
||||||
|
```
|
||||||
|
Nous avons placé dans la variable `r`le résultat de la fonction `get`, prise de la bibliothèque `requests`, avec comme 1er argument `endpoint`, c'est à dire `https://gitlab.com/api/v4/groups`
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> print(r)
|
||||||
|
<Response [200]>
|
||||||
|
```
|
||||||
|
Le résultat ne semble pas encourageant, et pourtant ! Le code **200** signifie qu'une URL a bien été trouvée, ce qu'on préfère à une erreur **404**!
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> type(r)
|
||||||
|
<class 'requests.models.Response'>
|
||||||
|
```
|
||||||
|
Le type de `r` est une classe, c'est un **objet Python**, qui contient d'autres données que ce simple `**Status Code 200**`
|
||||||
|
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> help(r)
|
||||||
|
>>> dir(r)
|
||||||
|
['__attrs__', '__bool__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_content', '_content_consumed', '_next', 'apparent_encoding', 'close', 'connection', 'content', 'cookies', 'elapsed', 'encoding', 'headers', 'history', 'is_permanent_redirect', 'is_redirect', 'iter_content', 'iter_lines', 'json', 'links', 'next', 'ok', 'raise_for_status', 'raw', 'reason', 'request', 'status_code', 'text', 'url']
|
||||||
|
```
|
||||||
|
Les fonctions `help()` et `dir()` nous aident à manipuler cet objet.
|
||||||
|
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> r.__attrs__
|
||||||
|
['_content', 'status_code', 'headers', 'url', 'history', 'encoding', 'reason', 'cookies', 'elapsed', 'request']
|
||||||
|
```
|
||||||
|
La **méthode** `__attrs` nous donne une liste d'attributs de notre objet `r`
|
||||||
|
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> r.url
|
||||||
|
'https://gitlab.com/api/v4/groups'
|
||||||
|
```
|
||||||
|
On peut ainsi vérifier l'URL sollicitée.
|
||||||
|
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> r.content
|
||||||
|
```
|
||||||
|
Avant d'accéder au contenu, il va falloir le mettre en forme!
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Formuler un requête à l'API
|
||||||
|
|
||||||
|
Comme il y a beaucoup de données (ici, tous les groupes créés sur Gitlab, il est nécessaire de filtrer notre requête.
|
||||||
|
|
||||||
|
Nous allons pour cela utiliser des paramètres, écrits au format **json** et stockés dans une variable nommée `payload`
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> payload = {"search": "garage"}
|
||||||
|
>>> r = requests.get(endpoint,params=payload)
|
||||||
|
```
|
||||||
|
nous chercherons ainsi les groupes qui contiennent le mot **garage**
|
||||||
|
La fonction get prend comme deuxième argument les données json.
|
||||||
|
On place ces données dans la variable `params` afin de préserver `payload`
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> r.headers
|
||||||
|
{'Date': 'Wed, 05 Aug 2020 18:42:47 GMT', 'Content-Type': 'application/json', 'Transfer-Encoding': 'chunked',
|
||||||
|
'Connection': 'keep-alive', 'Set-Cookie': '__cfduid=dcbe4c6164f5e175674b0abff0fb011c71596652967; expires=Fri, 04-Sep-20 18:42:47 GMT;
|
||||||
|
path=/; domain=.gitlab.com; HttpOnly; SameSite=Lax; Secure', 'Vary': 'Accept-Encoding, Origin', 'Cache-Control': 'max-age=0,
|
||||||
|
private, must-revalidate', 'Etag': 'W/"44cfa1c513193c8d78cdfc584f6dea72"', 'Link': '<https://gitlab.com/api/v4/groups?order_by=name&owned=false&page=2&per_page=20&search=garage&sort=asc&statistics=false&with_custom_attributes=false>;
|
||||||
|
rel="next", <https://gitlab.com/api/v4/groups?order_by=name&owned=false&page=1&per_page=20&search=garage&sort=asc&statistics=false&with_custom_attributes=false>;
|
||||||
|
rel="first", <https://gitlab.com/api/v4/groups?order_by=name&owned=false&page=2&per_page=20&search=garage&sort=asc&statistics=false&with_custom_attributes=false>;
|
||||||
|
rel="last"', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'SAMEORIGIN', 'X-Next-Page': '2', 'X-Page': '1', 'X-Per-Page': '20', 'X-Prev-Page': '',
|
||||||
|
'X-Request-Id': 'wo9iLfsTax', 'X-Runtime': '0.116039', 'X-Total': '37', 'X-Total-Pages': '2', 'Strict-Transport-Security': 'max-age=31536000',
|
||||||
|
'Referrer-Policy': 'strict-origin-when-cross-origin', 'Content-Encoding': 'gzip', 'GitLab-LB': 'fe-12-lb-gprd', 'GitLab-SV': 'api-18-sv-gprd',
|
||||||
|
'CF-Cache-Status': 'DYNAMIC', 'cf-request-id': '046187edf40000edab20af4200000001', 'Expect-CT': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
|
||||||
|
'Server': 'cloudflare', 'CF-RAY': '5be2a8f65905edab-CDG'}
|
||||||
|
>>>
|
||||||
|
>>> r.headers['X-Total']
|
||||||
|
'37'
|
||||||
|
```
|
||||||
|
Les headers nous donnent des informations intéressantes, et notamment ce `X-Total`, qui est le nombre total de résultats obtenus.
|
||||||
|
**Rappel : ** Les headers sont encadrés par des accolades ( `curly brackets : { }` ). C'est donc un objet de la classe `dic`. On accède à ses éléments en mettant entre crochets et guillemets la clé dont on veut voir la valeur, ici ` r.headers['X-Total']`
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Accéder au contenu de la requête
|
||||||
|
|
||||||
|
Il nous faut maintenant accéder aux données contenues dans la requête
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> data = r.json()
|
||||||
|
>>>
|
||||||
|
>>> type(data)
|
||||||
|
<class 'list'>
|
||||||
|
```
|
||||||
|
On créé la variable data, dans lequelle on met le contenu `r` sur lequel on a appliqué la fonction `json()`
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> data[0].keys()
|
||||||
|
dict_keys(['id', 'web_url', 'name', 'path', 'description', 'visibility', 'share_with_group_lock',
|
||||||
|
'require_two_factor_authentication', 'two_factor_grace_period', 'project_creation_level', 'auto_devops_enabled',
|
||||||
|
'subgroup_creation_level', 'emails_disabled', 'mentions_disabled', 'lfs_enabled', 'default_branch_protection',
|
||||||
|
'avatar_url', 'request_access_enabled', 'full_name', 'full_path', 'created_at', 'parent_id', 'ldap_cn', 'ldap_access'])
|
||||||
|
```
|
||||||
|
Prenons le 1er élément de la liste `data` (numéroté 0), et consultons la liste de ses `keys()`.
|
||||||
|
Chaque élément de la liste `data`correspond à un résultat de la recherche, et est constitué d'un dictionnaire dans lequel nous allons pouvoir `itérer`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Itération dans la liste de résultats
|
||||||
|
|
||||||
|
### `for`
|
||||||
|
|
||||||
|
Nous allons utiliser la boucle `for` pour **répéter une action sur chaque élément de la liste** (=itérer)
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> for i in data:
|
||||||
|
... print(i['name']) # Appuyez 2 fois Entrée pour créer un 1ère ligne non indentée
|
||||||
|
... # et marquer la fin des instructions de for
|
||||||
|
AppGarage
|
||||||
|
Atheed-Garage
|
||||||
|
Code Garage
|
||||||
|
[..]
|
||||||
|
Garagenum
|
||||||
|
>>>
|
||||||
|
```
|
||||||
|
Retenez bien la syntaxe simple de la boucle `for`dans Python: les `:` pour marquer le début des instructions, et c'est l'indentation ( `4` ++space++ en début de ligne) seulement qui marque la liste des instructions.
|
||||||
|
|
||||||
|
### `if`
|
||||||
|
|
||||||
|
Nous pouvons maintenant utiliser if pour afficher les détails d'un des résultats obtenus, que nous stockerons dans une variable nommée result:
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> for i in data:
|
||||||
|
... if i['name'] == "Garagenum":
|
||||||
|
... result = i
|
||||||
|
...
|
||||||
|
>>> print(result)
|
||||||
|
{'id': 4160307, 'web_url': 'https://gitlab.com/groups/garagenum', 'name': 'Garagenum', 'path': 'garagenum', 'description': '', 'visibility': 'public', 'share_with_group_lock': False, 'require_two_factor_authentication': False, 'two_factor_grace_period': 48, 'project_creation_level': 'developer', 'auto_devops_enabled': None, 'subgroup_creation_level': 'owner', 'emails_disabled': None, 'mentions_disabled': None, 'lfs_enabled': True, 'default_branch_protection': 2, 'avatar_url': None, 'request_access_enabled': False, 'full_name': 'Garagenum', 'full_path': 'garagenum', 'created_at': '2018-11-30T14:35:23.504Z', 'parent_id': None, 'ldap_cn': None, 'ldap_access': None}
|
||||||
|
```
|
||||||
|
Syntaxe similaire que pour le `for`, ici le `if`est imbriqué dans le `for`
|
||||||
|
|
||||||
|
### Affichage
|
||||||
|
|
||||||
|
Nous utiliserons aussi la boucle `for`pour afficher les résultats de manière lisible:
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> for i in result:
|
||||||
|
... print(i + " : " + str(result[i]))
|
||||||
|
...
|
||||||
|
id : 4160307
|
||||||
|
web_url : https://gitlab.com/groups/garagenum
|
||||||
|
name : Garagenum
|
||||||
|
[...]
|
||||||
|
```
|
||||||
|
|
||||||
|
Le `str(result[i])`permet de transformer chaque valeur de `result`en **chaîne de caractères (str)**, pour permettre l'affichage par `print()`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Authentification
|
||||||
|
|
||||||
|
Certaines données peuvent demander une authentification pour en autoriser l'accès.
|
||||||
|
|
||||||
|
Cherchons par exemple, dans les sous-groupes du garage, un groupe privé nommé `interventions`:
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> r = requests.get(endpoint,{"search":"garage"})
|
||||||
|
>>>
|
||||||
|
>>> for i in r.json():
|
||||||
|
... if i['name'] == "Garagenum":
|
||||||
|
... gn_id = i['id']
|
||||||
|
...
|
||||||
|
>>> print("L'ID du groupe Garagenum est " + gn_id)
|
||||||
|
L'ID du groupe Garagenum est 4160307
|
||||||
|
>>>
|
||||||
|
>>>
|
||||||
|
>>> gn_endpoint = "https://gitlab.com/api/v4/groups/gn_id/subgroups"
|
||||||
|
>>>
|
||||||
|
>>> payload = {'search': 'interventions'}
|
||||||
|
>>>
|
||||||
|
>>> r = requests.get(gn_endpoint, params = payload)
|
||||||
|
>>> for i in r.json():
|
||||||
|
... print(i['name'])
|
||||||
|
...
|
||||||
|
>>>
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun résultat, et pourtant, ce groupe existe!
|
||||||
|
|
||||||
|
Pour vous authentifier, il vous faut d'abord créer un jeton d'authentification dans gitlab
|
||||||
|
|
||||||
|
## Générer un jeton d'authentification
|
||||||
|
|
||||||
|
Pour accéder aux données présentées par l'API (par exemple, la liste des 'issues' qui me sont attribuées),
|
||||||
|
Gitlab a besoin de m'identifier.
|
||||||
|
|
||||||
|
Pour cela, à partir de notre interface web utilisateur de Gitlab, nous allons générer un **jeton d'authentification**.
|
||||||
|
|
||||||
|
Vous pouvez utiliser ce [tutoriel pour générer votre jeton d'API](https://screenful.com/gitlab/gitlab-apikey){target=_blank}
|
||||||
|
|
||||||
|
|
||||||
|
### Accès authentifié
|
||||||
|
|
||||||
|
Il vous suffit maintenant de modifier la variable `payload` , qui contient la liste des options pour la requête.
|
||||||
|
|
||||||
|
!!! bug ""
|
||||||
|
```
|
||||||
|
>>> payload['private_token'] = "p4zggV-SY1rB4s"
|
||||||
|
>>>
|
||||||
|
>>> r = requests.get(gn_endpoint, payload)
|
||||||
|
>>>
|
||||||
|
>>> for i in r.json():
|
||||||
|
... print(i['name'])
|
||||||
|
...
|
||||||
|
interventions
|
||||||
|
```
|
||||||
|
**Notez bien** la manière dont une nouvelle clé `private-token` a été ajoutée au dictonnaire `payload`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pour les étudiants
|
||||||
|
|
||||||
|
??? important "Conditions de validation"
|
||||||
|
Pour valider cette unité, il faut que vous fassiez une merge-request vers la branche `start`
|
||||||
|
Votre code doit permettre d'obtenir le résultat
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user