<!-- markdownlint-disable MD041 MD040 MD033 MD051 -->
# API pour ScoDoc 9

L'API ScoDoc permet à des applications tierces d'interroger ScoDoc. Elle offre
un accès aux informations aux formats XML et JSON.

Les composants internes de ScoDoc, et notamment le schéma de la base de données,
sont susceptibles d'évoluer à tout moment sans préavis: il est vivement
déconseillé d'écrire une extension ne passant pas par l'API. Vous ne devez même
pas supposer qu'il existe une base de données SQL.

La version ScoDoc 9 a introduit une nouvelle API avec un nouveau mécanisme d'authentification.
**Les clients de l'ancienne API ScoDoc 7 doivent être adaptés pour fonctionner avec ScoDoc 9.**

Cette API est encore incomplète: n'hésitez pas à demander de nouveaux accès ([contacts](Contact.md))
(et canal `#API` du Discord développeurs si vous y avez accès).

L'API fournit des données JSON, sauf exception (bulletins PDF par exemple).

Les objets ScoDoc manipulables sont identifiés par des id numériques.

* `etudid` : étudiant
* `formation_id` : un programme de formation (page "programmes");
* `ue_id` : une UE dans un programme;
* `matiere_id` : une matière dans un programme;
* `module_id` : un module dans un programme;
* `moduleimpl_id` : un module réalisé dans un semestre;
* `formsemestre_id` : un "semestre" de formation.

(pour plus de précisions, voir le [guide développeurs](GuideDeveloppeurs.md))

L'URL complète est de la forme:
`https://scodoc.example.com/ScoDoc/api/<fonction>`.
(<fonction> à choisir dans [Référence](#reference))

## Configuration de ScoDoc pour utiliser l'API

Il est nécessaire de disposer d'un compte utilisateur avec les droits adéquats.

Les droits à accorder dépendent des fonctionnalités nécessaires. la permission
`ScoView` est généralement suffisante car elle permet toutes les consultations.
Cependant si, par l'API, on veut effectuer des opérations de modification ou
encore consulter les comptes utilisateurs, d'autres droits (`ScoChangeGroups`,
`ScoUsersView`, `ScoSuperAdmin`, ...) peuvent être requis. La consultation du
[tableau récapitulatif](#tableau-recapitulatif-des-entrees-de-lapi) ou la ligne
`permission`de chaque entrée vous donnera la permission requise pour chaque
opération.

En général, il est recommandé de créer un rôle, de lui attribuer les permissions
que l'on veut utiliser, puis de créer un utilisateur ayant ce rôle.

En ligne de commande, cela peut se faire comme suit (voir détail des commandes
[sur le guide de configuration](GuideConfig.md)).

```bash
# se connecter comme utilisateur scodoc
su - scodoc

# Créer un rôle
flask create-role LecteurAPI
# Lui donner les droits nécessaires: ici ScoView
flask edit-role LecteurAPI -a ScoView

# Créer un nouvel utilisateur avec ce rôle:
flask user-create lecteur_api LecteurAPI @all

# Ou bien, si on veut utiliser un compte existant:
#   associer notre rôle à un utilisateur
flask user-role lecteur_api -a LecteurAPI


# Au besoin, changer le mot de passe de l'utilisateur
# (on aura besoin de ce mot de passe dans la configuration du client d'API)
flask user-password lecteur_api
...
```

Si vous êtes intéressé par le développement, voir

* [la section sur les tests unitaires de l'API](TestsScoDoc.md#tests-de-lapi-scodoc9);
* [la documentation développeurs](GuideDeveloppeurs.md) et sur les [vues de l'API](DevInternals.md#vues-de-lapi-et-permissions).

!!! note

    * Si vous utilisez le CAS, pensez à laisser les comptes utilisateurs API se
    connecter via ScoDoc sans CAS. Pour cela, cocher l'option
    *Autorise connexion via CAS si CAS est activé*
    dans leur formulaire de configuration.

    * Si l'utilisateur est associé à un département (cas des comptes créés via l'interface Web), 
    il ne pourra accéder à l'API que via une *route départementale*, c'est à dire une route comprenant
    l'acronyme de son département, de la forme `https://...//ScoDoc/DEPARTEMENT/api/...`.

## Essais avec HTTPie

[HTTPie](https://httpie.io/) est un client universel livre et gratuit très commode, disponible
pour Windows, Linux, en ligne de commande ou interface graphique.

Exemple d'utilisation en ligne de commande et interroger votre ScoDoc pour
obtenir la liste des départements:

```bash
http -a USER:PASSWORD POST  'http://localhost:5000/ScoDoc/api/tokens'
```

Qui affiche:

```text
HTTP/1.1 200 OK
Content-Length: 50
Content-Type: application/json
Date: Thu, 05 May 2022 04:29:33 GMT

{
    "token": "jS7iVl1234cRDzboAfO5xseE0Ain6Zyz"
}
```

(remplacer `USER:PASSWORD` par les identifiants de votre utilisateur et adapter
l'URL qui est ici celle d'un client local sur le serveur de test).

Avec ce jeton (*token*), on peut interroger le serveur:

```bash
http GET http://localhost:5000/ScoDoc/api/departements "Authorization:Bearer jS7iVlH1234cRDzboAfO5xseE0Ain6Zyz"
```

qui affiche par exemple:

```text
HTTP/1.1 200 OK
Content-Length: 151
Content-Type: application/json
Date: Thu, 05 May 2022 05:21:33 GMT

[
    {
        "acronym": "TAPI",
        "date_creation": "Wed, 04 May 2022 21:09:25 GMT",
        "description": null,
        "id": 1,
        "visible": true
    }
]
```

## Fonctions d'API ScoDoc 9

La documentation ci-dessous concerne la nouvelle API, disponible à partir de la
version de ScoDoc 9.3.25.

### Accès à l'API REST

L'API est accessible à l'adresse:
`https://scodoc.monsite.tld/ScoDoc/api/<fonction>`, et aussi via les *routes
départementales* de la forme
`https://scodoc.monsite.tld/ScoDoc/<dept_acronyme>/api/<fonction>` pour un accès
avec des droits restreints au département indiqué. La liste des `<fonctions>` est
donnée ci-dessous dans [Référence](#reference).

#### Authentification

Lors de votre authentification (*connexion avec login et mot de passe*) à Scodoc, il
vous sera attribué un jeton (token jwt *généré automatiquement*) vous permettant
d'utiliser l'api suivant les droits correspondant à votre session.

Pour obtenir le jeton, il faut un compte sur ScoDoc (`user_name`et `password`).
Les autorisations et rôles sont gérés exactement comme pour l'application.

Exemple avec `curl` (un outil en ligne de commande présent sur la plupart des
systèmes, voir plus haut pour la même chose avec la commande `http`):

```bash
curl -u user_name:password --request POST  https://SERVEUR/ScoDoc/api/tokens 
```

où `SERVEUR` est l'adresse (IP ou nom) de votre serveur.
La réponse doit ressembler à ceci:

```json
{
  "token": "LuXXxk+i74TXYZZl8MulgbiCGmVHXXX"
}
```

Vous trouverez dans `/opt/scodoc/tests/api/exemple-api-basic.py` un exemple
complet en python d'interrogation de l'API.

#### Codes HTTP

Chaque appel à l'API donne lieu à une réponse retournant un code spécifique en
fonction du résultat obtenu. L'analyse de ce code vous permet de vous assurer
que la requête a été traitée avec succès.

Tous les codes >= 400 indiquent que la requête n'a pas été traitée avec succès
par le serveur ScoDoc.

* [200](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/200) : OK.
* [401](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/401) : Authentification nécessaire. (jeton non précisé ou invalide)
* [403](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/403) : Action
  non autorisée pour l'utilisateur associé au jeton.
* [404](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/401) : Adresse
  incorrecte, paramètre manquant ou invalide, ou objet inexistant.
* [500](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/500) : Erreur
  inconnue côté serveur.

## Règles générales

* une route s'écrit comme une suite de noms et d'identifiants;
* les noms token, département, formation, formsemestre, groupe, etudiant,
  bulletin, absence, logo, programme, évaluation, résultat, décision désignent
  des types d'objets;
* les noms (verbes ou groupes verbaux): set_etudiant, remove_etudiant, query,
  create, delete, edit, order sont des actions;
* les noms restants (ids, courants, long, ...) sont des options, les autres noms
  sont des options ou des actions;
* le dernier nom apparaissant sur une route donne le type d'objet renvoyé. Ce
  nom peut apparaître au singulier ou au pluriel.
  * au singulier un seul objet est renvoyé, si aucun objet n'est trouvé, retourne un 404;
  * au pluriel une collection d'objets est renvoyée, si aucun objet n'est
    trouvé, retourne une collection vide.
* un type d'objet au singulier est généralement suivi immédiatement de son
  identifiant (unique). Exception: pour un étudiant, on peut également utiliser
  le NIP ou l'INE (qui ne sont pas uniques dans la base car un étudiant de même
  INE/NIP peut passer par plusieurs départements).

## Référence

La [carte syntaxique](#carte-syntaxique) vous permet de retrouver une entrée à
partir de sa syntaxe (le `?` amène sur la documentation associée).

Le [tableau récapitulatif](#tableau-recapitulatif-des-entrees-de-lapi) vous
permet de rechercher une entrée à partir du résultat attendu.

### Carte syntaxique

![carte_syntaxique](img/API_Chart.svg)

### Tableau récapitulatif des entrées de l'API

Ce tableau est trié selon le type des informations renvoyées:

* un nom simple représente un seul objet de ce type;
* suivi de `+`désigne une forme 'longue' d'objet de ce type;
* suivi de `*` désigne une liste de 0, 1 ou plusieurs objets du type;
* suivi de `#` désigne une liste d'entiers (les ids des objets du type);
* suivi de `:` puis d'un nom en majuscule indique une requête (POST) qui modifie
  les données de ScoDoc.

| Retour                  | Remarque                                | Méthode | Navigation                                                                | Permission          |
|:------------------------|:----------------------------------------|---------|---------------------------------------------------------------------------|---------------------|
| assiduite               | une assiduité                           | GET     | [assiduité](#assiduite)                                                   | ScoView             |
| assiduite**`*`**        | liste d'assiduités d'un étudiant        | GET     | [assiduités](#assiduites)                                                 | ScoView             |
| assiduite**`*`**        | liste d'assiduités d'un formsemestre    | GET     | [assiduités-formsemestre](#assiduites-formsemestre)                       | ScoView             |
| assiduite**`#`**        | liste d'id d'assiduités justifiées      | GET     | [justificatif-justifies](#justificatif-justifies)                         | ScoView             |
| assiduite:CREATE        | création d'assiduité                    | POST    | [assiduite-create](#assiduite-create)                                     | ScoAssiduiteChange  |
| assiduite:EDIT          | édition d'assiduité                     | POST    | [assiduite-edit](#assiduite-edit)                                         | ScoAssiduiteChange  |
| assiduite:DELETE        | suppression d'assiduité                 | POST    | [assiduite-delete](#assiduite-delete)                                     | ScoAssiduiteChange  |
| justificatif            | un justificatif                         | GET     | [justificatif](#justificatif)                                             | ScoView             |
| justificatif**`*`**     | liste de justificatif d'un étudiant     | GET     | [justificatifs](#justificatifs)                                           | ScoView             |
| justificatif:CREATE     | création de justificatif                | POST    | [justificatif-create](#justificatif-create)                               | ScoJustifChange     |
| justificatif:EDIT       | édition de justificatif                 | POST    | [justificatif-edit](#justificatif-edit)                                   | ScoJustifChange     |
| justificatif:DELETE     | suppression de justificatif             | POST    | [justificatif-delete](#justificatif-delete)                               | ScoJustifChange     |
| justificatif:IMPORT     | importation de fichier justificatif     | POST    | [justificatif-import](#justificatif-import)                               | ScoJustifChange     |
| justificatif:EXPORT     | exportation de fichier justificatif     | POST    | [justificatif-export](#justificatif-export)                               | ScoJustifChange     |
| justificatif:REMOVE     | suppression de fichier justificatif     | POST    | [justificatif-remove](#justificatif-remove)                               | ScoJustifChange     |
| departement**`*`**      | tous les depts                          | GET     | [departements](#departements)                                             |                     |
| departement**`#`**      | tous les ids des depts                  | GET     | [departements-ids](#departements-ids)                                     | ScoView             |
| departement             | recherche par id                        | GET     | [departement](#departement)                                               | ScoView             |
| departement             | recherche par acronyme                  | GET     | [departement](#departement)                                               | ScoView             |
| departement:CREATE      | création d'un département               | POST    | [departement-create](#departement-create)                                 | ScoSuperAdmin       |
| departement:EDIT        | modification d'un département           | POST    | [departement-edit](#departement-edit)                                     | ScoSuperAdmin       |
| departement:DELETE      | suppression d'un département            | POST    | [departement-delete](#departement-delete)                                 | ScoSuperAdmin       |
| evaluation              | une évaluation                          | GET     | [evaluation](#evaluation)                                                 | ScoView             |
| evaluation:CREATE       | création d'une évaluation               | POST    | [evaluation-create](#evaluation-create)                                   | -                   |
| evaluation:DELETE       | suppression d'une évaluation            | POST    | [evaluation-delete](#evaluation-delete)                                   | -                   |
| formation**`*`**        | toutes les formations accessibles       | GET     |  [formations](#formations)                                                | ScoView             |
| formation**`#`**        | ids des formations accessibles          | GET     | [formations-ids](#formations-ids)                                         | ScoView             |
| formation               | une formation                           | GET     | [formation](#formation)                                                   | ScoView             |
| export                  |                                         | GET     | [formation-export](#formation-export)                                     | ScoView             |
| export**`+`**           |                                         | GET     | [formation-export_with_ids](#formation-export_with_ids)                   | ScoView             |
| referentiel_competences |                                         | GET     | [formation-referenciel_competences](#formation-referenciel_competences)   | ScoView             |
| formsemestre**`#`**     |                                         | GET     | [departement-formsemestres_ids](#departement-formsemestres_ids)           | ScoView             |
| formsemestre**`*`**     |                                         | GET     | [departement-formsemestres_courants](#departement-formsemestres_courants) | ScoView             |
| formsemestre**`*`**     |                                         | GET     | [formsemestre-query](#formsemestre-query)                                 | ScoView             |
| formsemestre**`*`**     |                                         | GET     | [etudiant-formsemestres](#etudiant-formsemestres)                         | ScoView             |
| formsemestre            |                                         | GET     | [formsemestre](#formsemestre)                                             | ScoView             |
| moduleimpl              |                                         | GET     | [moduleimpl](#moduleimpl)                                                 | ScoView             |
| partition**`*`**        |                                         | GET     | [formsemestre-partitions](#formsemestre-partitions)                       | ScoView             |
| partition               |                                         | GET     | [partition](#partition)                                                   | ScoView             |
| partition:CREATE        |                                         | POST    | [formsemestre-partition-create](#formsemestre-partition-create)           | ScoEtudChangeGroups |
| partition:EDIT          |                                         | POST    | [partition-edit](#partition-edit)                                         | ScoEtudChangeGroups |
| partition:ACTION        |                                         | POST    | [formsemestre-partitions-order](#formsemestre-partitions-order)           | ScoEtudChangeGroups |
| partition:DELETE        |                                         | POST    | [partition-delete](#partition-delete)                                     | ScoEtudChangeGroups |
| partition:ACTION        |                                         | POST    | [partition-remove_etudiant](#partition-remove_etudiant)                   | ScoEtudChangeGroups |
| group:CREATE            |                                         | POST    | [partition-group-create](#partition-group-create)                         | ScoEtudChangeGroups |
| group:EDIT              |                                         | POST    | [group-edit](#group-edit)                                                 | ScoEtudChangeGroups |
| group:ACTION            |                                         | POST    | [partition-groups-order](#partition-groups-order)                         | ScoEtudChangeGroups |
| group:DELETE            |                                         | POST    | [group-delete](#group-delete)                                             | ScoEtudChangeGroups |
| group*                  |                                         | GET     | [etudiant-formsemestre-groups](#etudiant-formsemestre-groups)             | ScoView             |
| group:ACTION            |                                         | POST    | [group-set_etudiant](#group-set_etudiant)                                 | ScoEtudChangeGroups |
| group:ACTION            |                                         | POST    | [group-remove_etudiant](#group-remove_etudiant)                           | ScoEtudChangeGroups |
| etudiant**`*`**         | recherche par etudid, nip ou ine        | GET     | [etudiants-clef](#etudiants-clef)                                         | ScoView             |
| etudiant**`*`**         | les étudiants actuels                   | GET     | [etudiants-courant](#etudiants-courant)                                   | ScoView             |
| etudiant**`*`**         | étudiants dont le nom commence par      | GET     | [etudiants-name](#etudiants-name)                                         | ScoView             |
| etudiant**`*`**         |                                         | GET     | [departement-etudiants](#departement-etudiants)                           | ScoView             |
| etudiant**`*`**         |                                         | GET     | [formsemestre-etudiants](#formsemestre-etudiants)                         | ScoView             |
| etudiant**`*`**         |                                         | GET     | [formsemestre-etudiants-query](#formsemestre-etudiants-query)             | ScoView             |
| etudiant**`*`**         |                                         | GET     | [group-etudiants-query](#group-etudiants)                                 | ScoView             |
| etudiant**`*`**         |                                         | GET     | [group-etudiants-query](#group-etudiants-query)                           |
| etudiant                |                                         | GET     | [etudiant](#etudiant)                                                     | ScoView             |
| bulletin**`*`**         |                                         | GET     | [formsemestre-bulletin](#formsemestre-bulletin)                           | ScoView             |
| bulletin                |                                         | GET     | [etudiant-formsemestre-bulletin](#etudiant-formsemestre-bulletin)         | ScoView             |
| programme               |                                         | GET     | [formsemestre-programme](#formsemestre-programme)                         | ScoView             |
|                         |                                         | GET     | [formsemestre-etat_evals](#formsemestre-etat_evals)                       | ScoView             |
|                         |                                         | GET     | [formsemestre-resultats](#formsemestre-resultats)                         | ScoView             |
| jury                    |                                         | GET     | [formsemestre-decisions_jury](#formsemestre-decisions_jury)               | ScoView             |
| note*                   |                                         | GET     | [evaluation-notes](#evaluation-notes)                                     | ScoView             |
|                         |                                         | GET     | [evaluation-notes-set](#evaluation-notes-set)                             | (contextuelle)      |
| logo**`*`**             |                                         | GET     | [logos](#logos)                                                           | ScoSuperAdmin       |
| logo**`*`**             |                                         | GET     | [departement-logos](#departement-logos)                                   | ScoSuperAdmin       |
| logo                    |                                         | GET     | [logo](#logo)                                                             | ScoSuperAdmin       |
| logo                    |                                         | GET     | [departement-logo](#departement-logo)                                     | ScoSuperAdmin       |
| user                    |                                         | GET     | [user](#user)                                                             | ScoUsView           |
| user**`*`**             |                                         | GET     | [users-query](#users-query)                                               | ScoUsView           |
| user:CREATE             |                                         | POST    | [user-create](#user-create)                                               | ScoUserAdmin        |
| user:EDIT               |                                         | POST    | [user-edit](#user-edit)                                                   | ScoUserAdmin        |
| user:PASSWORD           | change le mot de passe d'un utilisateur | POST    | [user-password](#user-password)                                           | ScoUserAdmin        |
| user:ACTION             |                                         | POST    | [user-role-add](#user-role-add)                                           | ScoUserAdmin        |
| user:ACTION             |                                         | POST    | [user-role-remove](#user-role-remove)                                     | ScoUserAdmin        |
| permission**`*`**       |                                         | GET     | [permissions](#permissions)                                               | ScoUsView           |
| role**`*`**             |                                         | GET     | [roles](#roles)                                                           | ScoUsView           |
| role**`*`**             |                                         | GET     | [role](#role)                                                             | ScoUsView           |
| role:ACTION             |                                         | POST    | [role-add_permission](#role-add_permission)                               | ScoUserAdmin        |
| role:ACTION             |                                         | POST    | [role-remove_permission](#role-remove_permission)                         | ScoUserAdmin        |
| role:CREATE             |                                         | POST    | [role-create](#role-create)                                               | ScoUserAdmin        |
| role:EDIT               |                                         | POST    | [role-edit](#role-edit)                                                   | ScoUserAdmin        |
| role:DELETE             |                                         | POST    | [role-delete](#role-delete)                                               | ScoUserAdmin        |

#### Note sur les exemples d'utilisation

Pour uniformiser les résultats des exemples, ceux sont soumis à quelques post-traitements non réalisés par l'API. Il n'est par exemple pas garanti que les clés des objets json sont triées:

- les clés sont triées
- les listes de plus de 2 éléments sont tronquées à 2 éléments, la fin de la liste étant représentée par la notation en json '...'
- les dates (au format ISO) sont systématiquement remplacées par une date fixe (la date de modification d'un mot de passe peut évidement être différente de sa date de création)

### **API Départements**

#### Structure Département

| attribut        | type    | commentaire                              |
|:----------------|:--------|:-----------------------------------------|
| _acronym_       | string  | acronyme du département (fixe et unique) |
| _date_creation_ | string  | date ISO                                 |
| _dept_name_     | string  | Nom complet du département               |
| _descripton_    | string  |                                          |
| _id_            | int     | identifiant unique                       |
| _visible_       | bool    | affiché ou non dans la page d'accueil    |

#### **departements**

- **Méthode:** GET
- **Routes:** `/departements`
- **Exemple d'utilisation:** `/api/departements`
- **Résultat:** Liste de tous les départements (visibles ou non).
- **Exemple de résultat:**  [departements.json](samples/sample_departements.json.md)
  
#### **departements-ids**

- **Méthode:** GET
- **Permission: `ScoView`**
- **Routes:** `/departements_ids`
- **Résultat:** Liste des id départements (visibles ou non).
- **Exemple de résultat:**
- **Exemple de résultat:**  [departements-ids.json](samples/sample_departements-ids.json.md)

#### **departement**

- **Méthode:** GET
- **Permission: `ScoView`**
- **Routes:**
  - `/departement/id/<int:dept_id>`
  - `/departement/<string:dept>`
- **Résultat:** Un département
- **Exemple de résultat:**  [departement.json](samples/sample_departement.json.md)

#### **`departement-create`**

- **Méthode: POST**
- **Permission: `ScoSuperAdmin`**
- **Paramètres:** aucun
- **Data:** `{ "acronym": str, "visible":bool }`
- **Routes:** `/departement/create`
- **Exemple d'utilisation:** `/departement/create`

>`{ "acronym": "QLIO", "visible": true }`

- **Résultat:** Crée un nouveau département. L'acronyme du département (RT,
  GEII, ...) doit être unique (il est d'usage de le mettre en majuscules, mais
  ce n'est pas obligatoire). Le paramètre optionnel `visible`indique si le
  département est affiché sur la page d'accueil de ScoDoc. Notez qu'un
  département "invisible" peut quand même être utilisé si l'on connait son
  adresse (URL). Renvoie le département créé.
- **Exemple de résultat:**  [departements-create.json](samples/sample_departement-create.json.md)

#### **`departement-edit`**

- **Méthode: POST**
- **Permission: `ScoSuperAdmin`**
- **Paramètres:** `dept_acronym`
- **Data:** `{ "visible":bool }`
- **Routes:** `/departement/<string:dept_acronym>/edit`
- **Exemple d'utilisation:** `/departement/edit`

>`{ "visible": false }`

- **Résultat:** Modifie un département. Seul le champs `visible` peut être
  modifié. L'acronyme ne peut pas être changé car il peut être mentionné dans de
  nombreux objets et documents, y compris à l'extérieur de ScoDoc.
- **Exemple de résultat:**  [departements-edit.json](samples/sample_departement-edit.json.md)

#### **`departement-delete`**

- **Méthode: POST**
- **Permission: `ScoSuperAdmin`**
- **Paramètres:** `dept_acronym`
- **Routes:** `/departement/<string:dept_acronym>/delete`
- **Exemple d'utilisation:** `/departement/delete/EARTH`
- **Résultat:** supprime définitivement un département. *Toutes les données sont effacées*
  (étudiants, formations, ...).
- **Exemple de résultat:**  [departements-delete.json](samples/sample_departement-delete.json.md)

### **API Etudiant**

#### Structure Etudiant

| attribut              | type                          | commentaire                                                 |
|:----------------------|:------------------------------|:------------------------------------------------------------|
| _civilite_            | string                        | '`M`', '`F`' ou '`X`' [[1]](DonneesEtudiant.md)             |
| _civilite_etat_civil_ | string                        | '`M`', '`F`' ou '`X`' [[1]](DonneesEtudiant.md)             |
| _code_ine_            | string                        | non unique!                                                 |
| _code_nip_            | string                        | non unique!                                                 |
| _dept_id_             | string                        | id du département scodoc                                    |
| _id_                  | int                           | id unique                                                   |
| _nom_                 | string                        | en majuscule    [[1]](DonneesEtudiant.md)                   |
| _nom_usuel_           | string                        | null si absent  [[1]](DonneesEtudiant.md)                   |
| _prenom_              | string                        | [[1]](DonneesEtudiant.md)                                   |
| _prenom_etat_civil_   | string                        | (si prenom d'usage <> etat_civil [[1]](DonneesEtudiant.md)) |
| _sort_key_            | [ string, string ]            | nom-prenom pour trier                                       |
|                       |                               | **Format long**                                             |
| _admission_           | admission                     |                                                             |
| _adresses_            | [adresse](#structure-adresse) |                                                             |
| _boursier_            | bool                          |                                                             |
| _date_naissance_      | string                        | date ISO (yyyy-mm-dd)                                       |
| _dept_acronym_        | string                        |                                                             |
| _dept_naissance_      | string                        | département du lieu de naissance                            |
| _lieu_naissance_      | string                        | lieu de naissance (ville)                                   |
| _nationalite_         | string                        |                                                             |
| _photo_filename_      | string                        |                                                             |
| _scodoc7_id_          | string                        | de la forme 'EID9999'                                       |
| _statut_              | string                        | '`I`', '`D`' ou '`X`'                                       |


##### Structure adresse

| attribut                    | type   | commentaire |
|:----------------------------|:-------|:------------|
| codepostaldomicile          | string |             |
| description                 | string |             |
| domicile                    | string |             |
| email                       | string |             |
| emailperso                  | string |             |
| etudid                      | string |             |
| fax                         | string |             |
| id                          | string |             |
| paysdomicile                | string |             |
| telephone                   | string |             |
| telephonemobile             | string |             |
| typeadresse                 | string |             |
| villedomicile               | string |             |



#### **`etudiants-courants`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Routes:**
  * `/etudiants/courants`
  * `/etudiants/courants/long`
* **Exemple d'utilisation:** `/api/etudiants/courants`
* **Résultat:** Liste des étudiants inscrits dans un formsemestre
  actuellement en cours. Avec `/long`, donne tous les attributs de
  l'étudiants (plus lent).
* **Exemple de résultat:** [etudiants-courants.json](samples/sample_etudiants-courants.json.md)

#### **`etudiants-clef`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:**  `etudid`, `nip`, `ine`
* **Routes:** `/etudiants/etudid/<int:etudid>` ou `/etudiants/nip/<string:nip>` ou `/etudiants/ine/<string:ine>`
* **Exemple d'utilisation:** `/api/etudiants/nip/1`
* **Résultat:** Infos sur le ou les étudiants correspondants.
  Comme [`/etudiant`](ScoDoc9API.md#etudiant) mais renvoie toujours une liste.
  Si non trouvé, liste vide, pas d'erreur.
  Dans 99% des cas, la liste contient un seul étudiant, mais si l'étudiant a
  été inscrit dans plusieurs départements, on a plusieurs objets (1 par
  dept.).
* **Exemple de résultat:** [etudiants-clef.json](samples/sample_etudiants-clef.json.md)

#### **`etudiants-name`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:**  `name`
* **Routes:** `/etudiants/name/<string:name>`
* **Exemple d'utilisation:** `/api/etudiants/name/dup`
* **Résultat:** Liste ordonnée par nom d'étudiants dont le nom commence par
  `name`. Si `name`est trop court (2 caractères), liste vide. La casse et les
  accents ne sont pas pris en compte dans la recherche.
* **Note:** Cette fonction est utilisée pour la complétion des champs de formulaire
  (choix d'un étudiant).

#### **departement-etudiants**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `dept`, `dept_id`
* **Routes:**
  * `/departement/id/<int:dept_id>/etudiants`
  * `/departement/<string:dept>/etudiants`
* **Exemple d'utilisation:** `/api/departement/MMI/etudiants`
* **Résultat:** liste tous les étudiants (passés ou présents) d'un département.
  On peut spécifier l'acronyme du département ("MMI") ou son id (un entier).
  Attention, la liste peut être longue: requête coûteuse à éviter.
* **Exemple de résultat:** [departement-etudiants.json](samples/sample_departement-etudiants.json.md)

#### **`formsemestre-etudiants[-long][-query]`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `formsemestre_id`
* **Query string:** `etat` ('I', 'D' ou 'DEF')
* **Routes:**
  * `/formsemestre/<int:formsemestre_id>/etudiants`
  * `/formsemestre/<int:formsemestre_id>/etudiants/query?etat=I,D,DEF`
  * `/formsemestre/<int:formsemestre_id>/etudiants/long`
  * `/formsemestre/<int:formsemestre_id>/etudiants/long/query?etat=I,D,DEF`
* **Exemple d'utilisation:**
  * `/api/formsemestre/1/etudiants/long`
  * `/api/formsemestre/1/etudiants/query?etat=D`
* **Résultat:** Etudiants d'un formsemestre spécifié par son id.
    Une clé (`sort_key`) reproduit [ nom, prenom ] sous forme ASCII, permettant le tri des étudiants.
    Avec `query`, La liste est restreinte aux étudiants inscrits (`I`), démissionnaires (`D`) ou défaillants  (`DEF`) si l'état est indiqué.
    Avec `long`, ajoute la date de naissance entre autre
* **Exemple de résultat:**
  * [formsemestre-etudiants.json](samples/sample_formsemestre-etudiants.json.md)
  * [formsemestre-etudiants-query.json](samples/sample_formsemestre-etudiants-query.json.md)

#### **`group-etudiants[-query]`**

* **Méthode: GET**
* **Permission: `ScoView`**
* **Paramètres:** `group_id`
* **Query string:** `etat` ('I', 'D' ou 'DEF')
* **Routes:**
  * `/group/<int:group_id>/etudiants`
  * `/group/<int:group_id>/etudiants/query`
* **Exemple d'utilisation:**
  * `/ScoDoc/api/group/1/etudiants`
  * `/ScoDoc/api/group/1/etudiants/query?etat=I`
* **Résultat:** Etudiants d'un groupe spécifié par son id. Liste
  restreinte aux étudiants inscrits (I), démissionnaires (D) ou défaillants
  (DEF) si l'état est indiqué.
* **Exemple de résultat:**
  * [group-etudiants.json](samples/sample_group-etudiants.json.md)
  * [group-etudiants-query.json](samples/sample_group-etudiants-query.json.md)

#### **`etudiant`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:**  `etudid`, `nip`, `ine`
* **Routes:**
  * `/etudiant/etudid/<int:etudid>` ou
  * `/etudiant/nip/<string:nip>` ou
  * `/etudiant/ine/<string:ine>`
* **Exemple d'utilisation:** `/api/etudiant/nip/1`
* **Résultat:** Retourne les informations sur l'étudiant correspondant à
  l'id passé en paramètres.
  Les codes INE et NIP sont uniques au sein d'un département.
  Si plusieurs objets étudiant ont le même code, on renvoie le plus récemment inscrit.
* Pour obtenir tous les étudiants répondant au critère, utiliser [etudiant-clefs](#etudiants-clef)
* **Exemple de résultat:**  [etudiant.json](samples/sample_etudiant.json.md)

### **API Evaluation**

#### Structure évaluation

| attribut                    | type                                           | commentaire                                       |
|:----------------------------|:-----------------------------------------------|:--------------------------------------------------|
| coefficient                 | float                                          | coefficient pour moyenne (1.)                     |
| date_debut                  | datetime (iso)                                 | date et heure de début (tous groupes)             |
| date_fin                    | datetime (iso)                                 | date et heure de fin (tous groupes)               |
| description                 | string                                         | texte libre                                       |
| evaluation_type             | int                                            | 0 normale, 1 rattrapage, 2 "2eme session"         |
| moduleimpl_id               | int                                            | moduleimpl                                        |
| note_max                    | float                                          | barème (20 points)                                |
| numero                      | int                                            | ordre présentation                                |
| poids                       | { int : float }                                | poids APC (BUT): { ue_id : poids }                |
| publish_incomplete          | int                                            | si vrai, prend en compte même si notes incomplètes|
| visibulletin                | int                                            | affiche sur bulletins intermédiaires (non BUT)    |

Note: les poids ne sont utilisés que dans les formations APC (BUT).

#### **`evaluation`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Routes:** `/evaluation`
* **Exemple d'utilisation:** `/ScoDoc/api/evaluation/123`
* **Résultat:** Liste une évaluation
* **Exemple de résultat:**  [evaluation.json](samples/sample_evaluation.json.md)

#### **`evaluation-create`**

* **Méthode: POST**
* **Permission:** dépend du contexte
* **Data:**
```json
{
  "description" : str,
  "evaluation_type" : int, // {0,1,2} default 0 (normale)
  "date_debut" : date_iso, // optionnel
  "date_fin" : date_iso,   // optionnel
  "note_max" : float, // si non spécifié, 20.0
  "numero" : int,  // ordre de présentation, default tri sur date
  "visibulletin" : boolean ,  //default true
  "publish_incomplete" : boolean ,  //default false
  "coefficient" : float, // si non spécifié, 1.0
  "poids" : { ue_id : poids } // optionnel
}
```
* **Routes:** `/moduleimpl/<int:moduleimpl_id>/evaluation/create`
* **Résultat:** Crée une évaluation dans le moduleimpl indiqué. Tous les paramètres passés dans sont optionnels. Renvoie l'évaluation.

#### **`evaluation-delete`**

* **Méthode: POST**
* **Permission:** dépend du contexte
* **Paramètres:** `evaluation_id`
* **Routes:** `/evaluation/<int:evaluation_id>/delete`
* **Exemple d'utilisation:** `/ScoDoc/api/evaluation/123/delete`
* **Résultat:** Supprime une évaluation (et toutes ses notes s'il y en a)

### **API Formation**

#### Structure Formation

| attribut                    | type                                           | commentaire                                       |
|:----------------------------|:-----------------------------------------------|:--------------------------------------------------|
| _acronyme_                  | string                                         |                                                   |
| _code_specialité_           | string                                         |                                                   |
| _departement_               | [Département](#structure-departement)          | _pour `/formations` mais pas pour `/formation` ?_ |
| _dept_id_                   | int                                            | _redondant avec departement.id ?_                 |
| _formation_code_            | string                                         | défini la compatibilité avec d'autres formations  |
| _formation_id_              |                                                | _redondant avec id ?_                             |
| _id_                        | int                                            | id unique de formation                            |
| _referentiel_competence_id_ | int                                            | null si pas de référentiel associé                |
| _titre_                     | string                                         | _URL encoded ?_                                   |
| _titre_officiel_            | string                                         |                                                   |
| _type_parcours_             | int                                            |                                                   |
| _version_                   | int                                            |                                                   |

#### **`formations`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Routes:** `/formations`
* **Exemple d'utilisation:** `/ScoDoc/api/formations`
* **Résultat:** Liste de toutes les formations (tous départements accessibles).
* **Exemple de résultat:**  [formations.json](samples/sample_formations.json.md)

#### **`formations_ids`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Routes:** `/formations_ids`
* **Exemple d'utilisation:** `/ScoDoc/api/formations_ids`
* **Résultat:** Liste des ids de toutes les formations (tous départements
  accessibles).
* **Exemple de résultat:**  [formations_ids.json](samples/sample_formations_ids.json.md)

#### **`formation`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `formation_id`
* **Routes:** `/formation/<int:formation_id>`
* **Exemple d'utilisation:** `/ScoDoc/api/formation/1`
* **Résultat:** Description de la formation.
* **Exemple de résultat:**  [formation.json](samples/sample_formation.json.md)

### **API Formsemestre**

Les sessions de formation (qu'elles durent une année ou un mois) sont représentées par les `formsemestre`.

#### Note sur les identifiants de formsemestre

Le `session_id` peut être utilisé pour identifier de façon prévisible et
(presque) unique un formsemestre dans un établissement, ce qui est utile
notamment pour interfacer ScoDoc à d'autres logiciels (par exemple gestion
d'emplois du temps ou de services d'enseignement). Cet identifiant est constitué
des informations suivantes:

* **Département** (RT, GEII, INFO...) (acronyme en majuscules)
* **Nom parcours:** BUT, LP, ... (défini au niveau du parcours dans ScoDoc = NAME)
* **Modalité:** FI, FC, FA
* **"Spécialité":** S1 (ou S1D pour les semestres décalés), ou le
  `code_specialite` si pas de semestres. Le code spécialité est un champ
  (libre) dans la "formation" (le programme pédagogique).
* **Année:** année de début de l'année scolaire correspondante (2014 pour
  une session appartenant à l'année scolaire 2014-2015, même si elle
  commence en mars 2015).

**Exemple:** `INFO-DUT-FI-S1-2014` équivaut à un semestre S1 d'un DUT
informatique de 2014 en formation initiale (FI).

#### Structure Formsemestre

| attribut                      | type        | commentaire                                    |
|:------------------------------|:------------|:-----------------------------------------------|
| _**annee_scolaire**_          | int         |                                                |
| _**block_moyenne_generale**_  | bool        |                                                |
| _**block_moyennes**_          | bool        | inhibe le calcul des moyennes                  |
| _**bul_bgcolor**_             | string      | Couleur (CSS) de fond du bulletin              |
| _**bul_hide_xml**_            | bool        |                                                |
| _**date_debut**_              | date        |                                                |
| _**date_debut_iso**_          | string      |                                                |
| _**date_fin**_                | date        |                                                |
| _**date_fin_iso**_            | string      |                                                |
| _**departement**_             | Département |                                                |
| _**dept_id**_                 | int         |                                                |
| _**elt_annee_apo**_           | ???         |                                                |
| _**elt_sem_apo**_             | string      |                                                |
| _**ens_can_edit_eval**_       | bool        |                                                |
| _**etape_apo**_               | string      |                                                |
| _**etat**_                    | bool        |                                                |
| _**formation**_               | Formation   |                                                |
| _**formation_id**_            | int         |                                                |
| _**formsemestre_id**_         | int         | identification unique                          |
| _**gestion_compensation**_    | bool        |                                                |
| _**gestion_semestrielles**_   | bool        |                                                |
| _**id**_                      | int         | id unique                                      |
| _**modalite**_                | string      | "FI", "FA", ...                                |
| _**parcours**_                | ????        |                                                |
| _**resp_can_change_ens**_     | bool        |                                                |
| _**resp_can_edit**_           | bool        |                                                |
| _**responsables**_            | int*        | liste des ids des enseignants responsables     |
| _**scodoc7_id**_              | int         |                                                |
| _**semestre_id**_             | int         | rang du semestre 1, ...                        |
| _**session_id**_              | string      | cf. Note sur les identifiants de formsemestre  |
| _**titre**_                   | string      |                                                |
| _**titre_court**_             | string      |                                                |
| _**titre_num**_               | string      |                                                |

#### **departement-formsemestres_ids**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `dept`
* **Routes:**
  * `/departement/id/<int:dept_id>/formsemestres_ids`
  * `/departement/<string:dept>/formsemestres_ids`
* **Exemple d'utilisation:** `/api/departement/MMI/formsemestres_ids`
* **Résultat:** Liste des id des formsemestres (passés ou présents) d'un
  département donné.
* **Exemple de résultat:** [departement-formsemestres_ids.json](samples/sample_departement-formsemestres_ids.json.md)

#### **departement-formsemestres_courants**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `dept_id`
* **Routes:**
  * `/departement/id/<int:dept_id>/formsemestres_courants`
  * `/departement/<string:dept>/formsemestres_courants`
* **Exemple d'utilisation:** `/api/departement/MMI/formsemestres_courants`
* **Résultat:** Liste des formsemestres en cours d'un département donné.
* **Exemple de résultat:** [departement-formsemestres-courants.json](samples/sample_departement-formsemestres-courants.json.md)

#### **formsemestres-query**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** aucun
* **Query string:** `annee_scolaire`, `dept_acronym`, `dept_id`, `etape_apo`, `ine`, `nip`
* **Route:** `/formsemestres/query`
* **Exemple d'utilisation:** `/api/formsemestres/query?etape_apo=V7HU1&annee_scolaire=2021`
* **Résultat:** Description de formsemestres. Si plusieurs
  paramètres sont donnés, c'est la conjonction (ET) des critères qui est
  recherchée. Si aucun formsemestre ne satisfait la requête, une liste vide est
  retournée. Si `ine`ou `nip`sont spécifiés, cherche les formsemestres dans
  lesquels un étudiant de ce code est inscrit.
* **Exemple de résultat:** [formsemestres-query.json](samples/sample_formsemestres-query.json.md)

#### **etudiant-formsemestres**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `etudid`, `nip`, `ine`
* **Routes:**
  * `/etudiant/etudid/<int:etudid>/formsemestres` ou
  * `/etudiant/nip/<string:nip>/formsemestres` ou
  * `/etudiant/ine/<string:ine>/formsemestres`
* **Exemple d'utilisation:** `/etudiant/ine/1/formsemestres`
* **Résultat:** Liste des semestres qu'un étudiant a suivi, triés
  par ordre chronologique.
* **Exemple de résultat:**  [etudiant-formsemestres.json](samples/sample_etudiant-formsemestres.json.md)

#### **formsemestre**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `formsemestre_id`
* **Route:** `/formsemestre/<int:formsemestre_id>`
* **Exemple d'utilisation:** `/api/formsemestre/1`
* **Résultat:** Description du formsemestre.
* **Exemple de résultat:**  [formsemestre.json](samples/sample_formsemestre.json.md)

### **API Groupe**

#### **`partition-group-create`**

* **Méthode: POST**
* **Permission: `ScoEtudChangeGroups`**
* **Paramètres:** `partition_id`
* **Data:** `{ group_name : <string> }`
* **Routes:** `/partition/<int:partition_id>/group/create`
* **Exemple d'utilisation:** `/ScoDoc/api/partition/1962/group/create`

>`{ "group_name" : "A" }`

* **Résultat:** Crée un groupe dans une partition.
* **Exemple de résultat:**  [group-create.json](samples/sample_partition-group-create.json.md)

#### **`group-edit`**

* **Méthode: POST**
* **Permission: `ScoEtudChangeGroups`**
* **Paramètres:** `group_id`
* **Data:** `{ group_name : <string> }`
* **Routes:** `/group/<int:group_id>/edit`
* **Exemple d'utilisation:** `/ScoDoc/api/group/4581/edit`

>`{ "group_name" : "nouveau" }`

* **Résultat:** Renomme un groupe.
* **Exemple de résultat:**  [group-edit.json](samples/sample_group-edit.json.md)

#### **`partition-groups-order`**

* **Méthode: POST**
* **Permission: `ScoEtudChangeGroups`**
* **Paramètres:** `partition_id`
* **Data:** `[ <int:group_id1>, <int:group_id2>, ... ]`
* **Routes:** `/partition/<int:partition_id>/groups/order`
* **Exemple d'utilisation:** `/ScoDoc/api/partition/1962/groups/order`

>`[ 4383, 4379, 4380, 4381, 4382, 4384 ]`

* **Résultat:** Spécifie l'ordre des groupes d'une partition.
* **Exemple de résultat:**  [partition-groups-order.json](samples/sample_partition-groups-order.json.md)

#### **`group-delete`**

* **Méthode: POST**
* **Permission: `ScoEtudChangeGroups`**
* **Paramètres:** `group_id`
* **Routes:** `/group/<int:group_id>/delete`
* **Exemple d'utilisation:** `/ScoDoc/api/group/4581/delete`
* **Résultat:** Supprime un groupe.
* **Exemple de résultat:**  [group-delete.json](samples/sample_group-delete.json.md)

#### **etudiant-formsemestre-groups**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:**  `formsemestre_id`, `etudid`, `nip`, `ine`
* **Routes:**
  `/etudiant/etudid/<int:etudid>/semestre/<int:formsemestre_id>/groups` ou
  `/etudiant/nip/<string:nip>/semestre/<int:formsemestre_id>/groups` ou
  `/etudiant/ine/<string:ine>/semestre/<int:formsemestre_id>/groups`
* **Exemple d'utilisation:** `/etudiant/nip/1/semestre/1/groups`
* **Résultat:** Retourne la liste des groupes auxquels appartient l'étudiant dans le semestre indiqué. (json)
* **Exemple de résultat:**  [etudiant-formsemestres-groups.json](samples/sample_etudiant-formsemestre-groups.json.md)

#### **`group-set_etudiant`**

* **Méthode: POST**
* **Permission: `ScoEtudChangeGroups`**
* **Paramètres:** `group_id`, `etudid`
* **Routes:** `/group/<int:group_id>/set_etudiant/<int:etudid>`
* **Exemple d'utilisation:** `/ScoDoc/api/group/4085/set_etudiant/12108`
* **Résultat:** Affecte un étudiant dans un groupe.
* **Exemple de résultat:**  [groupes-set_etudiant.json](samples/sample_group-set_etudiant.json.md)

#### **`group-remove_etudiant`**

* **Méthode: POST**
* **Permission: `ScoEtudChangeGroups`**
* **Paramètres:** `group_id`, `etudid`
* **Routes:** `/group/<int:group_id>/remove_etudiant/<int:etudid>`
* **Exemple d'utilisation:** `/ScoDoc/api/group/4085/remove_etudiant/12108`
* **Résultat:** Retire un étudiant d'un groupe.
* **Exemple de résultat:**  [groupes-remove_etudiant.json](samples/sample_group-remove_etudiant.json.md)

### **API Jury**

#### **`formsemestre-decisions_jury`**

* **Permission: `ScoView`**
* **Méthode:** GET
* **Paramètres:** `formsemestre_id`
* **Routes:** `/formsemestre/<int:formsemestre_id>/decisions_jury`
* **Exemple d'utilisation:** `/ScoDoc/api/formsemestre/1/jury`
* **Résultat:** Retourne le récapitulatif des décisions jury
* **Exemple de résultat:**  [formsemestre-decisions_jury.json](samples/sample_formsemestre-decisions_jury.json.md)
`

### **API Moduleimpl**

#### Structure ModuleImpl

Le moduleimpl est la mise en place d'un module dans un formsemestre (avec son
responsable et ses enseignants). La liste des moduleimpl d'un formsemestre peut être obtenu par l'entrée [formsemestre-programme](#formsemestre-programme)

| attribut               | type   | commentaire                                      |
|:-----------------------|:-------|:-------------------------------------------------|
| _**computation_expr**_ | string | unused                                           |
| _**ens**_              | User#  | liste des ids des enseignants du moduleimpl      |
| _**formsemestre_id**_  | int    | id du formsemestre                               |
| _**id**_               | int    | identifiant unique                               |
| _**module**_           | Module |                                                  |
| _**module_id**_        | int    | id du module                                     |
| _**moduleimpl_id**_    | int    | _**redondance id_?                               |
| _**responsable_id**_   | int    | id du responsable de module                      |

#### **`moduleimpl`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `moduleimpl_id`
* **Routes:** `/moduleimpl/<int:moduleimpl_id>`
* **Exemple d'utilisation:** `/ScoDoc/api/moduleimpl/1`
* **Résultat:** Description du moduleimpl.
* **Exemple de résultat:** [moduleimpl.json](samples/sample_moduleimpl.json.md)

### **API Partition**

#### Structure Partition

L'ensemble des étudiants d'un semestre peut être réparti selon une ou
plusieurs partitions (types de groupes). Chaque partition est constituée
d'un nombre quelconque de groupes d'étudiants.

| attribut              | type   | commentaire                        |
|:----------------------|:-------|:-----------------------------------|
| _**bul_show_rank**_   |        | affichage sur bulletin             |
| _**formsemestre_id**_ | int    | formsemestre hôte                  |
| _**groups**_          | Group* | liste des groupes de la partition  |
| _**groups_editable**_ | bool   | verrou (liste des groupes)         |
| _**id**_              | int    | identifiant unique                 |
| _**numero**_          | int    |                                    |
| _**partition_name**_  | string | nom de la partition                |
| _**show_in_lists**_   | bool   |                                    |

#### **`formsemestre-partitions`**

* **Méthode: GET**
* **Permission: `ScoView`**
* **Paramètres:** `formsemestre_id`
* **Routes:** `/formsemestre/<int:formsemestre_id>/partitions`
* **Exemple d'utilisation:** `/ScoDoc/api/formsemestre/911/partitions`
* **Résultat:** Liste de toutes les partitions d'un formsemestre.
* **Exemple de résultat:** [formsemestre-partitions.json](samples/sample_formsemestre-partitions.json.md)

#### **`partition`**

* **Méthode: GET**
* **Permission: `ScoView`**
* **Paramètres:** `partition_id`
* **Routes:** `/partition/<int:partition_id>`
* **Exemple d'utilisation:** `/ScoDoc/api/partition/1963`
* **Résultat:** Description d'une partition (y compris la liste de ses groupes).
* **Exemple de résultat:** [partition.json](samples/sample_partition.json.md)

#### **`formsemestre-partition-create`**

* **Méthode: POST**
* **Permission: `ScoEtudsChangeGroups`**
* **Paramètres:** `formsemestre_id`
* **Data:** `{ "partition_name" : <string> }`
* **Routes:** `/formsemestre/<int:formsemestre_id>/partition/create`

>`{ "partition_name" : "PART" }`

* **Exemple d'utilisation:** `/ScoDoc/api/formsemestre/944/partition/create`
* **Résultat:** Crée une nouvelle partition dans un formsemestre.
* **Exemple de résultat:** [formsemestre-partition-create.json](samples/sample_formsemestre-partition-create.json.md)

#### **`partition-edit`**

* **Méthode: POST**
* **Permission: `ScoEtudsChangeGroups`**
* **Paramètres:** `partition_id`
* **Data:** `{ partition_name : <string> }`
* **Routes:** `/partition/<int:partition_id>/edit`
* **Exemple d'utilisation:** `/ScoDoc/api/partition/2047/edit`

>`{ "partition_name" : "PART4" }`

* **Résultat:** Renomme une partition
* **Exemple de résultat:** [partition-edit.json](samples/sample_partition-edit.json.md)

#### **`formsemestre-partitions-order`**

* **Méthode: POST**
* **Permission: `ScoEtudsChangeGroups`**
* **Paramètres:** `formsemestre_id`
* **Data:** `[ <int:partition_id1>, <int:partition_id2>, ... ]`
* **Routes:** `/formsemestre/<int:formsemestre_id>/partitions/order`
* **Exemple d'utilisation:** `/ScoDoc/api/formsemestre/944/partitions/order`

>`[ 2048, 2054 ]`

* **Résultat:** Spécifie l'ordre des partitions d'un formsemestre.
* **Exemple de résultat:** [formsemestre-partitions-order.json](samples/sample_formsemestre-partitions-order.json.md)

#### **`partition-delete`**

* **Méthode: POST**
* **Permission: `ScoEtudsChangeGroups`**
* **Paramètres:** `partition_id`
* **Routes:** `/partition/<int:partition_id>/delete`
* **Exemple d'utilisation:** `/ScoDoc/api/partition/2047/delete`
* **Résultat:** Supprime une partition.
* **Exemple de résultat:** [partition-delete.json](samples/sample_partition-delete.json.md)

#### **`partition-remove_etudiant`**

* **Méthode: POST**
* **Permission: `ScoEtudsChangeGroups`**
* **Permission: `ScoEtudChangeGroups`**
* **Paramètres:** `partition_id`
* **Routes:** `/partition/<int:partition_id>/remove_etudiant/<int:etudid>`
* **Exemple d'utilisation:** `/ScoDoc/api/partition/1962/remove_etudiant/12107`
* **Résultat:** Retire un étudiant des groupes de la partition.
* **Exemple de résultat:**  [partition-remove_etudiant.json](samples/sample_partition-remove_etudiant.json.md)

### **API Role**

Les rôles ont un nom et sont associés à un ensemble de permissions. Un
utilisateur pourra être associé à un ou plusieurs rôles dans chaque département
(ainsi, il ou elle peut enseigner dans un département et être administrateur
d'un autre).

#### **roles**

* **Méthode:** GET
* **Permission: `ScoUsersView`**
* **Routes:** `/roles`
* **Exemple d'utilisation:** `/roles`
* **Résultat:** Liste de tous les rôles.
* **Exemple de résultat:** [roles.json](samples/sample_roles.json.md)

#### **role**

* **Méthode:** GET
* **Permission: `ScoUsersView`**
* **Routes:** `/role/<str:role_name>`
* **Exemple d'utilisation:** `/role/Ens`
* **Résultat:** Liste le rôle indiqué. 404 si inexistant.
* **Exemple de résultat:** [role.json](samples/sample_role.json.md)

#### **role-add_permission**

* **Méthode: POST**
* **Permission: `ScoSuperAdmin`**
* **Routes:** `/role/<str:role_name>/add_permission/<str:perm_name>`
* **Exemple d'utilisation:** `/role/Ens/add_permission/ScoView`
* **Résultat:** Ajoute la permission au rôle. 404 si l'un des deux n'existe pas.
  Note: la liste des permissions est donnée sur [ConfigPermissions](ConfigPermissions.md).
* **Exemple de résultat:** [role-add_permission.json](samples/sample_role-add_permission.json.md)

#### **role-remove_permission**

* **Méthode: POST**
* **Permission: `ScoSuperAdmin`**
* **Routes:** `/role/<str:role_name>/remove_permission/<str:perm_name>`
* **Exemple d'utilisation:** `/role/Ens/remove_permission/ScoView`
* **Résultat:** Retire la permission au rôle. 404 si l'un des deux n'existe pas.
  Si le rôle n'a pas la permission, ne fait rien.
* **Exemple de résultat:** [role-remove_permission.json](samples/sample_role-remove_permission.json.md)

#### **role-create**

* **Méthode: POST**
* **Permission: `ScoSuperAdmin`**
* **Data:** `{ "permissions" : [ permission, ... ] }`
* **Routes:** `/role/create/<str:role_name>`
* **Exemple d'utilisation:** `/role/create/LaveurDecarreaux`
  
> `{ "permissions" : [ 'ScoView', 'ScoUsersView' ] }`

* **Résultat:** Crée un nouveau rôle, avec les permissions indiquées.
* **Exemple de résultat:** [role-create.json](samples/sample_role-create.json.md)

#### **role-delete**

* **Méthode: POST**
* **Permission: `ScoSuperAdmin`**
* **Routes:** `/role/<str:role_name>/delete`
* **Exemple d'utilisation:** `/role/LaveurDeCarreaux/delete`
* **Résultat:** Supprime ce rôle.
* **Exemple de résultat:** [role-delete.json](samples/sample_role-delete.json.md)

#### **role-edit**

* **Méthode: POST**
* **Permission: `ScoSuperAdmin`**
* **Data:** `{ "permissions" : [ permission, ... ] }`
* **Routes:** `/role/edit/<str:role_name>`
* **Exemple d'utilisation:** `/role/create/LaveurDecarreaux`
  
> `{ "name" : "LaveurDeVitres", "permissions" : [ 'ScoView' ] }`

* **Résultat:** Modifie le rôle: son nom et/ou ses permissions.
* **Exemple de résultat:** [role-edit.json](samples/sample_role-edit.json.md)

### **API User, Permissions**

#### **user**

* **Méthode:** GET
* **Permission: `ScoUsersView`**
* **Paramètres:** `user_id`
* **Route:** `/user/<int:user_id>`
* **Exemple d'utilisation:** `/api/user/1`
* **Résultat:** Retourne la description d'un utilisateur.
* **Exemple de résultat:** [user.json](samples/sample_user.json.md)

#### **`user-create`**

* **Méthode: POST**
* **Permission: `ScoUsersAdmin`**
* **Data:**

```json
{
        "user_name": str,
        "dept": str or null,
        "nom": str,
        "prenom": str,
        "active":bool (default True)
}
```

* **Routes:** `/user/create`
* **Résultat:** Crée un nouvel utilisateur. `user_name`est le login, unique et
  non modifiable. L'utilisateur est normalement rattaché à un département, sauf
  si est "super-administrateur".
* **Exemple de résultat:** [user-create.json](samples/sample_user-create.json.md)

#### **`users-query`**

* **Méthode:** GET
* **Permission: `ScoUsersView`**
* **Routes:**

  * `/users/query?departement=dept_acronym&active=1&starts_with=<str:nom>`

* **Résultat:** Liste d'utilisateurs, filtrés par département, statut, début de
  nom (paramètres tous optionnels). Seuls les utilisateurs que l'on a la
  permission de voir sont listés.
* **Exemple de résultat:**  [users-query.json](samples/sample_users-query.json.md)

#### **`user-edit`**

* **Méthode: POST**
* **Permission: `ScoUsersAdmin`**
* **Data:**

```json
{
        "dept": str or null,
        "nom": str,
        "prenom": str,
        "active":bool (default True)
}
```

* **Routes:** `/user/<int:uid>/edit`
* **Résultat:** Modifie l'utilisateur d'UID indiqué.
* **Exemple de résultat:** [user-edit.json](samples/sample_user-edit.json.md)

#### **`user-password`**

* **Méthode: POST**
* **Permission: `ScoUsersAdmin`**
* **Data:** `{ "password": str }`
* **Routes:** `/user/<int:uid>/password`
* **Exemple d'utilisation:** `/user/3/password`

>`{ "password": "averycomplicatedpassaword" }

* **Résultat:** Modifie le mot de passe de l'utilisateur désigné par son UID.
    L'opération peut être rejetée si le mot de passe ne satisfait pas les conditions requises (trop  simple par exemple), avec le retour suivant:

>   ```json
>
    {
        "error": "Bad Request",
        "status": 400,
        "message": "user_password: invalid password"
    }
    ```

* **Exemple de résultat:** [user-password.json](samples/sample_user-password.json.md)

#### **`user-role-add`**

* **Méthode: POST**
* **Permission: `ScoSuperAdmin`**
* **Routes:** `/user/<int:uid>/role/<str:role_name>/add[/departement/<string:dept_acronym>]`
* **Résultat:** Attribue le rôle à l'utilisateur, dans le département indiqué
  (ou tous si le département n'est pas spécifié).)
* **Exemple de résultat:** [user-role-add.json](samples/sample_user-role-add.json.md)

#### **`user-role-remove`**

* **Méthode: POST**
* **Permission: `ScoUsersAdmin`**
* **Routes:** `/user/<int:uid>/role/<str:role_name>/remove[/departement/<string:dept_acronym>]`
* **Résultat:** Retire le rôle à l'utilisateur.
* **Exemple de résultat:** [user-role-remove.json](samples/sample_user-role-remove.json.md)

#### **`permissions`**

* **Méthode:** GET
* **Permission: `ScoUsersView`**
* **Routes:** `/permissions`
* **Résultat:** Liste des noms des permissions. Ces permissions ne sont pas
  modifiables, mais de nouvelles peuvent apparaitre lors des mises à jour du
  logiciel. Voir [ConfigPermissions](ConfigPermissions.md).
* **Exemple de résultat:**  [permissions.json](samples/sample_permissions.json.md)

### **API Bulletin, Évaluations, Notes**

Attention, les bulletins ne sont publiés sur l'API que si l'option "*publier le
bulletin sur le portail étudiant*" est cochée dans le semestre concerné.

#### **formsemestre-bulletins**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `formsemestre_id`
* **Route:** `/formsemestre/<int:formsemestre_id>/bulletins[/<string:version>]`
* **Exemple d'utilisation:** `/api/formsemestre/1/bulletins`
* **Résultat:** Bulletins d'un formsemestre spécifié par son id.
* **Exemple de résultat:** [formsemestre-bulletins.json](samples/sample_formsemestre-bulletins.json.md)

Pour les formations classiques (toutes sauf BUT), les bulletins JSON peut ou non
indiquer les matières. Par défaut (version `long`), il est structuré en `UEs / modules`. Si la
version est `short_mat`ou `long_mat`, il sera structuré en
`UEs / matieres / modules`.

#### **etudiant-formsemestre-bulletin**

Récapitulatif par étudiant (état, groupe(s), moyennes d'UEs et de modules)
pour un formsemestre spécifié par son id.
Par défaut les valeurs numériques sont formatées en chaînes. Si format=raw, valeurs numériques
mais pas JSON compliant à cause des `NaN`.

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:**  `formsemestre_id`, `etudid`, `nip`, `ine`
* **Query string:** `format`
* **Routes:**
  `/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin[/<string:version>][/pdf][/pdf/nosig]`
  ou `/etudiant/nip/<string:nip>/formsemestre/<int:formsemestre_id>/bulletin[/<string:version>][/pdf][/pdf/nosig]`
  ou
  `/etudiant/ine/<string:ine>/formsemestre/<int:formsemestre_id>/bulletin[/<string:version>][/pdf][/pdf/nosig]`

* **Exemple d'utilisation:** `/etudiant/nip/1/formsemestre/1/bulletin`
* **Résultat:** Bulletin de l'étudiant dans le formsemestre.
  Deux variantes possibles:

  * versions `long` et `short` (`long` par défaut, ajoutez `/short` pour la version plus courte).
  * version `json` et `pdf` (`json` par défaut, ajoutez `/pdf` pour la version
    pdf)
  
  Pour les formations classiques (toutes sauf BUT), les bulletins JSON peut ou
  non indiquer les matières. Par défaut (version `long`), il est structuré en
  `UEs / modules`.
  Si la version est `short_mat`ou `long_mat`, il sera structuré en
  `UEs / matieres / modules`.
  Les notes moyennes de matières ne sont calculées que si l'option
  "*Afficher les matières sur les bulletins*" est activée pour le formsemestre
  considéré (sinon, la note vaut toujours "*nd*"). `
  
  Les versions PDF sont par défaut identiques à celles servies dans ScoDoc. Avec
  l'option `/pdf/nosig`, les signatures en fin de bulletin sont omises.

  Attention, les bulletins ne sont publiés sur l'API que si l'option "*publier le
  bulletin sur le portail étudiant*" est cochée dans le semestre concerné.


* **Exemple de résultat:**  [etudiant-formsemestre-bulletin.json](samples/sample_etudiant-formsemestre-bulletin.json.md)

#### **formsemestre-programme**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `dept`, `formsemestre_id`
* **Routes:** `/formsemestre/<int:formsemestre_id>/programme`
* **Exemple d'utilisation:** `/ScoDoc/api/formsemestre/1/programme`
* **Résultat:** Retourne la structure d'un formsemestre sous 5 entrées d'un dictionnaire:
  
  * **`ues`**: liste des UEs
  * **`ressources`**: liste des ressources (BUT)
  * **`saes`**: liste des SAÉs (BUT)
  * **`modules`**:  liste des modules classiques (DUT ou sport/culture)
  * **`malus`**: listes des modules de type bonus/malus.
  
* **Exemple de résultat:** [formsemestre-programme.json](samples/sample_formsemestre-programme.json.md)

#### **formsemestre-resultats**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `formsemestre_id`
* **Query string**: `format`
* **Route:** `/formsemestres/resultats`
* **Exemple d'utilisation:** `/api/formsemestre/1/resultats`
* **Résultat:**  [formsemestre-resultats.json](samples/sample_formsemestre-resultats.json.md)

Récapitulatif par étudiant (état, groupe(s), moyennes d'UEs et de modules)
pour un formsemestre spécifié par son id.
Par défaut les valeurs numériques sont formatées en chaînes. Si format=raw,
valeurs numériques mais pas JSON compliant à cause des `NaN`.

* **Exemple de résultat:**

#### **`moduleimpl-evaluations`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `moduleimpl_id`
* **Routes:** `/moduleimpl/<int:moduleimpl_id>/evaluations`
* **Exemple d'utilisation:** `/ScoDoc/api/moduleimpl/1/evaluations`
* **Résultat:** Retourne la liste des évaluations à partir de l'id d'un
  moduleimpl (quel que soit leur statut).
* **Exemple de résultat:** [moduleimpl-evaluations.json](samples/sample_moduleimpl-evaluations.json.md)

#### **`evaluation-notes`**

* **Méthode**: GET
* **Permission: `ScoView`**
* **Paramètres**: `evaluation_id`
* **Routes:** `/evaluation/<int:evaluation_id>/notes`
* **Exemple d'utilisation:** `/evaluation/1491/notes`
* **Résultat:** Retourne la liste des notes d'une évaluation. Les valeurs sont
  non normalisées (le champ `note_max` indique le barème), et peuvent contenir
  des chaînes de caractères: ABS, EXC, DEM, ...
* **Exemple de résultat:**  [evaluation-notes.json](samples/sample_evaluation-notes.json.md)

#### **`evaluation-notes-set`**

* **Méthode**: POST
* **Permission**: droit de saisir des notes dans cette évaluation
* **Paramètres**: `evaluation_id`
* **Routes:** `/evaluation/<int:evaluation_id>/notes/set`
* **Contenu:** les notes à enregistrer dans l'évaluation. Les valeurs sont
  "brutes", entre 0 et `note_max`(barème de l'évaluation), EXC, ABS, SUPR...

  ```json
  {
      'notes' : [ [etudid, value], ... ],
      'comment' : optional string
  }
  ```

* **Résultat:** json avec

  ```json
  {
            "etudids_changed": [ etudids dont la note a été modifiée ],
            "etudids_with_decision": [ etudids ayant une décision de jury à vérifier ],
            "history_menu": [ html utilisé par la page de saisie ],
  }
  ```

#### **formsemestre-etat_evals**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `formsemestre_id`
* **Routes:** `/formsemestre/<int:formsemestre_id>/etat_evals`
* **Exemple d'utilisation:** `/ScoDoc/api/formsemestre/1/etat_evals`
* **Résultat:** Retourne les informations sur l'état des évaluations d'un semestre donné
* **Exemple de résultat:** [formsemestre-etat_evals.json](samples/sample_formsemestre-etat_evals.json.md)

### **API Export, Référentiel**

#### **`formation-export`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `formation_id`, `export_ids` (False par défaut. Ajouter `/with_ids` pour le passer à True)
* **Routes:**
  * `/formation/<int:formation_id>/export`
  * `/formation/<int:formation_id>/export_with_ids`
* **Exemple d'utilisation:** `/ScoDoc/api/formation/formation_export/1`
* **Résultat:** Retourne la formation, avec UE, matières, modules
* **Exemple de résultat:** [formation-export.json](samples/sample_formation-export.json.md)

#### **`formation-referentiel_competences`**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `formation_id`
* **Routes:** `/formation/<int:formation_id>/referentiel_competences`
* **Exemple d'utilisation:** `api/formation/1/referentiel_competences`
* **Résultat:** Le référentiel de compétences d'une formation donnée (json). (*pas toujours présent*)
* **Exemple de résultat:** [formation-referentiel_competences.json](samples/sample_formation-referentiel_competences.json.md)

### **API Logos**

#### **`logos`**

* **Méthode:** GET
* **Permission: `ScoSuperAdmin`**
* **Paramètres :** Aucun
* **Route :** `/logos`
* **Exemple d'utilisation :** `/ScoDoc/api/logos`
* **Résultat :** Liste des noms des logos définis pour le site scodoc.
* **Exemple de résultat:** [logos.json](samples/sample_logos.json.md)

#### **`logo`**

* **Méthode:** GET
* **Permission: `ScoSuperAdmin`**
* **Paramètres :** Aucun
* **Route:** `/logo/<string:nom>`
* **Exemple d'utilisation :** `/ScoDoc/api/logo/header`
* **Résultat :** l'image (format png ou jpg; le format retourné dépend du format sous lequel l'image a été initialement enregistrée)
* **Exemple de résultat:** [logo.json](samples/sample_logo.json.md)

#### **`departement-logos`**

* **Méthode:** GET
* **Permission: `ScoSuperAdmin`**
* **Paramètres:** Aucun
* **Route :**
  
  * `/departement/<string:dept>/logos`
  * `/departement/id/<int:departement_id>/logos`
  
* **Exemple d'utilisation :**
  
  * `/departement/<string:dept>/logos`
  * `/departement/id/<int:departement_id>/logos`
  
* **Résultat :** Liste des noms des logos définis pour le département visé qui peut être désigné par son id ou par son acronyme (selon la forme de la route).
* **Exemple de résultat:** [departement-logos.json](samples/sample_departement-logos.json.md)

#### **`departement-logo`**

* **Méthode:** GET
* **Permission: `ScoSuperAdmin`**
* **Paramètres :** Aucun
* **Route :**
  * `/departement/<string:dept>/logo/<string:nom>`
  * `/departement/id/<int:departement_id>/logo/<string:nom>`
* **Exemple d'utilisation:**
  
  * `/ScoDoc/api/departement/MMI/logo/header`
  * `/ScoDoc/api/departement/id/3/logo/header`
  
* **Résultat :** l'image (format png ou jpg)
* **Exemple de résultat:** [departement-logo.json](samples/sample_departement-logo.json.md)

### **API Assiduités**

Cette API est disponible à partir de ScoDoc 9.6 et remplace les absences.

#### Structure Assiduité

| attribut        | type           | commentaire                                                      |
| :-------------- | :------------- | :--------------------------------------------------------------- |
| *assiduite_id*  | int            | identifiant unique                                               |
| *etudid*        | int            | identifiant unique de l'étudiant concerné par l'assiduité        |
| *moduleimpl_id* | int ou null    | identifiant unique du module concerné par l'assiduité si indiqué |
| *date_debut*    | string         | date ISO du début de la période d'assiduité                      |
| *date_fin*      | string         | date ISO de la fin de la période d'assiduité                     |
| *etat*          | string         | état de l'assiduité (présent, absent, retard)                    |
| *desc*          | string ou null | description de l'assiduité                                       |
| *user_id*       | int ou null    | utilisateur ayant créé l'assiduité                               |
| *est_just*      | boolean        | l'assiduité est-elle justifiée                                   |
| *entry_date*    | string         | la date d'entrée de l'assiduité                                  |

> Rappel du format de date ISO : yyyy-mm-jjTHH:MM:SS
> Vous pouvez aussi spécifier le temps UTC en ajoutant '+HH:MM' à la fin

#### **assiduite**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `assiduite_id`
* **Routes:** `/assiduite/<int:assiduite_id>`
* **Exemple d'utilisation:** `/api/assiduite/1`
* **Résultat:** Retourne un objet assiduité ou une erreur si l'id n'est pas connu
* **Exemple de résultat:**  [assiduite.json](samples/sample_assiduite.json.md)

#### **assiduites[-query]**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** 
  * `etudid`
  * `nip`
  * `ine`
* **Query string:**
  * `etat` ('present','retard','absent)
  * `moduleimpl_id` (X : id du moduleimpl concerné)
  * `date_debut` (X : date format iso)
  * `date_fin` (X : date format iso)
  * `formsemestre_id` (X : id du formsemestre)
  * `est_just` (v,t,f,vrai,faux,true,false)
  * `user_id` (X : id de l'utilisateur)
* **Routes:**
  * `/assiduites/<int:etudid>`
  * `/assiduites/<int:etudid>/query?`
  * `/assiduites/etudid/<int:etudid>`
  * `/assiduites/etudid/<int:etudid>/query?`
  * `/assiduites/nip/<nip>`
  * `/assiduites/nip/<nip>/query?`
  * `/assiduites/ine/<ine>`
  * `/assiduites/ine/<ine>/query?`
* **Exemple d'utilisation:**
  * `/api/assiduites/1`
  * `/api/assiduites/1/query?etat=retard`
  * `/api/assiduites/1/query?moduleimpl_id=1`
* **Résultat:** Liste de toutes les objets assiduité qui correspondent aux critères sélectionnés
* **Exemple de résultat:**  [assiduites.json](samples/sample_assiduites.json.md)

#### **assiduites-count[-query]**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** 
  * `etudid`
  * `nip`
  * `ine`
* **Query string:**
  * `etat` ('present','retard','absent')
  * `moduleimpl_id` (X : id du moduleimpl concerné)
  * `date_debut` (X : date format ISO)
  * `date_fin` (X : date format ISO)
  * `formsemestre_id` (X : id du formsemestre)
  * `est_just` (v,t,f,vrai,faux,true,false)
  * `user_id` (X : id de l'utilisateur)
  * `metric` ('compte', 'demi', 'journee', 'heure')
* **Routes:**
  * `/assiduites/<int:etudid>/count`
  * `/assiduites/<int:etudid>/count/query?`
  * `/assiduites/etudid/<int:etudid>/count`
  * `/assiduites/etudid/<int:etudid>/count/query?`
  * `/assiduites/nip/<nip>/count`
  * `/assiduites/nip/<nip>/count/query?`
  * `/assiduites/ine/<ine>/count`
  * `/assiduites/ine/<ine>/count/query?`
* **Exemple d'utilisation:**
  * `/api/assiduites/1`
  * `/api/assiduites/1/count/query?etat=retard`
  * `/api/assiduites/1/count/query?moduleimpl_id=1`
  * `/api/assiduites/1/count/query?etat=present,retard&metric=compte,heure`
* **Résultat:** les métriques obtenu à partir des assiduitées correspondant aux critères sélectionnés
* **Exemple de résultat:**  [assiduites-count.json](samples/sample_assiduites_count.json.md)

#### **assiduites-formsemestre[-query]**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `formsemestre_id`
* **Query string:**
  * `etat` ('present','retard','absent')
  * `moduleimpl_id` (X : id du moduleimpl concerné)
  * `date_debut` (X : date format ISO)
  * `date_fin` (X : date format ISO)
  * `est_just` (v,t,f,vrai,faux,true,false)
  * `user_id` (X : id de l'utilisateur)
* **Routes:**
  * `/assiduites/formsemestre/<int:formsemestre_id>`
  * `/assiduites/formsemestre/<int:formsemestre_id>/query?`
* **Exemple d'utilisation:**
  * `/api/assiduites/formsemestre/1`
  * `/api/assiduites/formsemestre/1/query?etat=retard`
  * `/api/assiduites/formsemestre/1/query?moduleimpl=1`
* **Résultat:** Liste de toutes les objets assiduité des étudiants du formsemestre qui correspondent aux critères sélectionnés
* **Exemple de résultat:**  [assiduites_formsemestre.json](samples/sample_assiduites_formsemestre.json.md)

#### **assiduites-formsemestre-count[-query]**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `formsemestre_id`
* **Query string:**
  * `etat` ('present','retard','absent')
  * `moduleimpl_id` (X : id du moduleimpl concerné)
  * `date_debut` (X : date format ISO)
  * `date_fin` (X : date format ISO)
  * `est_just` (v,t,f,vrai,faux,true,false)
  * `user_id` (X : id de l'utilisateur)
* **Routes:**
  * `/assiduites/formsemestre/<int:formsemestre_id>/count`
  * `/assiduites/formsemestre/<int:formsemestre_id>/count/query?`
* **Exemple d'utilisation:**
  * `/api/assiduites/formsemestre/1/count`
  * `/api/assiduites/formsemestre/1/count/query?etat=retard`
  * `/api/assiduites/formsemestre/1/count/query?moduleimpl=1&metric=demi,journee`
* **Résultat:** les métriques obtenu à partir des assiduités de tous les étudiants du formsemestre correspondant aux critères sélectionnés
* **Exemple de résultat:**  [assiduites_formsemestre-count.json](samples/sample_assiduites_formsemestre_count.json.md)

#### **assiduites-group[-query]**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Query string:**
  * `etudids` **Obligatoire** (liste des etudids sous la forme `x,y,z,...`)
  * `etat` ('present','retard','absent')
  * `moduleimpl_id` (X : id du moduleimpl concerné)
  * `date_debut` (X : date format ISO)
  * `date_fin` (X : date format ISO)
  * `est_just` (v,t,f,vrai,faux,true,false)
  * `user_id` (X : id de l'utilisateur)
* **Routes:**
  * `/assiduites/group/query?etudids=`
* **Exemple d'utilisation:**
  * `/assiduites/group/query?etudids=1,2,3`
  * `/assiduites/group/query?etudids=1,2,3&etat=retard`
  * `/assiduites/group/query?etudids=1,2,3&moduleimpl=1`
* **Résultat:**
  ```json
  {
    etudid1 : [{assiduité...}],
    etudid2 : [{assiduité...}],
    etudid3 : [{assiduité...}],
  }
  ```

#### **assiduites-create**

* **Méthode:** POST
* **Permission: `ScoAbsChange`**
* **Data:**

```json
[
  { 
    "etudid":<int>,

    "date_debut": <string>,
    "date_fin": <string>,
    "etat": <string>,
    "moduleimpl_id"?: <int>,
    "desc"?:<string>,
  },
  ...
]
```

* **Routes:**
  * `/assiduites/create`
* **Exemple d'utilisation:** `/api/assiduites/create`

> `[{"date_debut": "2022-10-27T08:00","date_fin": "2022-10-27T10:00","etat": "absent","etudid":1}]`

* **Résultat:** Retourne un objet en deux parties (errors et success) contenant le retour de chaque objet donné dans la requête POST.


#### **assiduite-create**

* **Méthode:** POST
* **Permission: `ScoAbsChange`**
* **Paramètres:** 
  * `etudid`
  * `nip`
  * `ine`
* **Data:**

```json
[
  {
    "date_debut": <string>,
    "date_fin": <string>,
    "etat": <string>,
    "moduleimpl_id"?: <int>,
    "desc"?:<string>
  },
  ...
]
```

* **Routes:**
  * `/assiduite/<int:etudid>/create`
  * `/assiduites/etudid/<int:etudid>/create`
  * `/assiduites/nip/<nip>/create`
  * `/assiduites/ine/<ine>/create`
* **Exemple d'utilisation:** `/api/assiduite/1/create`

> `[{"date_debut": "2022-10-27T08:00","date_fin": "2022-10-27T10:00","etat": "absent"}]`

* **Résultat:** Retourne un objet en deux parties (errors et success) contenant le retour de chaque objet donné dans la requête POST.
* **Exemple de résultat:**  [assiduite_create.json](samples/sample_assiduite_create.json.md)

#### **assiduite-edit**

* **Méthode:** POST
* **Permission: `ScoAbsChange`**
* **Paramètres:** `assiduite_id`
* **Data:**

```json
{
    "etat": <string>,
    "moduleimpl_id": <int>,
    "desc" : <string>,
}
```

* **Routes:** `/assiduite/<int:assiduite_id>/edit`
* **Exemple d'utilisation:** `/api/assiduite/1/edit`

> `{"etat": "absent"}`

* **Résultat:** Modifie l'assiduité désignée. Renvoie une erreur si la
  modification rend incompatible la plage de l'assiduité par rapport aux autres
  assiduités du même étudiant.
* **Exemple de résultat:**  [assiduite_edit.json](samples/sample_assiduite_edit.json.md)

#### **assiduites-edit**

* **Méthode:** POST
* **Permission: `ScoAbsChange`**
* **Data:**

```json
[
  {
    "etudid":<int>,
    "etat"?: <string>,
    "moduleimpl_id"?: <int>,
    "desc"?:<string>,
  },
  ...
]
```

* **Routes:**
  * `/assiduites/edit`
* **Exemple d'utilisation:** `/api/assiduites/edit`

> `[{"etat": "absent","assiduite_id":1},{"etat": "retard","moduleimpl_id":12,"assiduite_id":2}]`

* **Résultat:** Retourne un objet en deux parties (errors et success) contenant le retour de chaque objet donné dans la requête POST.

#### **assiduite-delete**

* **Méthode:** POST
* **Permission: `ScoAbsChange`**
* **Data:**

```json
[
  <int:assiduite_id>,
  ...
]
```

* **Routes:**
  * `/assiduite/delete`
* **Exemple d'utilisation:** `/api/assiduite/delete`

> `[2,3,5,7]`

* **Résultat:** Retourne un objet en deux parties (errors et success) contenant le retour de chaque objet donné dans la requête POST.
* **Exemple de résultat:**  [assiduite_delete.json](samples/sample_assiduite_delete.json.md)

#### Structure Justificatif

| attribut     | type           | commentaire                                                   |
| :----------- | :------------- | :------------------------------------------------------------ |
| *justif_id*  | int            | identifiant unique                                             |
| *etudid*     | int            | identifiant unique de l'étudiant concerné par le justificatif   |
| *date_debut* | string         | date ISO du début de la période du justificatif                |
| *date_fin*    | string         | date ISO de la fin de la période du justificatif                |
| *etat*       | string         | état du justificatif ( attente, valide, non_valide, modifie)    |
| *raison*     | string ou null | explication du justificatif si présente                        |
| *fichier*     | string         | identifiant de l'archivage des fichiers                         |
|*user_id*     | int or null    | identifiant de l'utilisateur ayant créé le justificatif         |
| *entry_date* | string         | date ISO de l'entrée du justificatif                           |

#### **justificatif**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `justif_id`
* **Routes:** `/justificatif/<int:justif_id>`
* **Exemple d'utilisation:** `/api/justificatif/1`
* **Résultat:** Retourne un objet justificatif ou une erreur si l'id n'est pas connu
* **Exemple de résultat:**  [justificatif.json](samples/sample_justificatif.json.md)

#### **justificatifs[-query]**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** 
  * `etudid`
  * `nip`
  * `ine`
* **Query string:**
  * `etat` ( attente, valide, non_valide, modifie)
  * `date_debut` (X : date format ISO)
  * `date_fin` (X : date format ISO)
* **Routes:**
  * `/justificatifs/<int:etudid>`
  * `/justificatifs/<int:etudid>/query`
  * `/justificatifs/etudid/<etudid>`
  * `/justificatifs/etudid/etudid>/query`
  * `/justificatifs/nip/<nip>`
  * `/justificatifs/nip/<nip>/query`
  * `/justificatifs/ine/<ine>`
  * `/justificatifs/ine/<ine>/query`
* **Exemple d'utilisation:**
  * `/api/justificatifs/1`
  * `/api/justificatifs/1/query?etat=modifie`
  * `/api/justificatifs/1/query?date_debut=2022-10-27T08:00`
* **Résultat:** Liste de toutes les objets justificatifs qui correspondent aux critères sélectionnés
* **Exemple de résultat:**  [justificatifs.json](samples/sample_justificatifs.json.md)

#### **justificatif-create**

* **Méthode:** POST
* **Permission: `ScoAbsChange`**
* **Paramètres:** 
  * `etudid`
  * `nip`
  * `ine`
* **Data:**

```json
[
  {
    "etat": <string>,
    "date_debut": <string>,
    "date_fin": <string>,
    "raison"?: <string>,
  },
  ...
]
```

> Un fichier justificatif peut être importé dans scodoc après avoir créer l'objet justificatif voir [importer un justificatif](FichiersJustificatifs.md#importer-un-fichier)

* **Routes:** 
  * `/justificatif/<int:etudid>/create`
  * `/justificatif/etudid/<etudid>/create`
  * `/justificatif/nip/<nip>/create`
  * `/justificatif/ine/<ine>/create`
* **Exemple d'utilisation:** `/api/justificatif/1/create`

```json
[
  {
    "etat": "attente",
    "date_debut": "2022-10-27T08:00",
    "date_fin": "2022-10-27T12:00",
    "raison": "Opération médicale",
  }
]
```

* **Résultat:** Retourne un objet en deux parties (errors et success) contenant
  le retour de chaque objet donné dans la requête POST.
* **Exemple de résultat:**  [justificatif-create.json](samples/sample_justificatif_create.json.md)

#### **justificatif-edit**

* **Méthode:** POST
* **Permission: `ScoAbsChange`**
* **Paramètres:** `justif_id`
* **Data:**

```json
{
    "etat": <string>,
    "raison": <string>,
    "date_debut": <string>,
    "date_fin": <string>,
}
```

* **Routes:** `/justificatif/<int:justif_id>/edit`
* **Exemple d'utilisation:** `/api/justificatif/1/edit`

> `{"etat": "valide"}`

* **Résultat:** Modifie le justificatif désigné.
* **Exemple de résultat:**  [justificatif-edit.json](samples/sample_justificatif_edit.json.md)

#### **justificatif-delete**

* **Méthode:** POST
* **Permission: `ScoAbsChange`**
* **Data:**

```json
[
  <int:justif_id>,
  ...
]
```

* **Routes:** `/justificatif/delete`
* **Exemple d'utilisation:** `/api/justificatif/delete`

```json
[
  2,3,5,7
]
```

* **Résultat:** Retourne un objet en deux partie (errors et success) contenant le retour de chaque objet donné dans la requête POST.
* **Exemple de résultat:**  [justificatif-delete.json](samples/sample_justificatif_delete.json.md)

#### **justificatif-import**

* **Méthode:** POST
* **Permission: `ScoAbsChange`**
* **Paramètres:** `justif_id`

> Procédure d'importation de fichier : [importer un justificatif](FichiersJustificatifs.md#importer-un-fichier)

* **Routes:** `/justificatif/<int:justif_id>/import`

* **Résultat:** Le nom du fichier archivé (nom coté serveur)
* **Exemple de résultat:**  [justificatif-import.json](samples/sample_justificatif_import.json.md)

#### **justificatif-export**

* **Méthode:** POST
* **Permission: `ScoAbsChange`**
* **Paramètres:**
  * `justif_id`
  * `filename`

> Procédure de téléchargement de fichier : [télécharger un justificatif](FichiersJustificatifs.md#télécharger-un-fichier)

* **Routes:** `/justificatif/<int:justif_id>/export/<str:filename>`

* **Résultat:** le fichier (téléchargement direct / renvoie octets)
* **Exemple de résultat:**  [justificatif-export.json](samples/sample_justificatif_export.json.md)

#### **justificatif-remove**

* **Méthode:** POST
* **Permission: `ScoAbsChange`**
* **Paramètres:** `justif_id`

> Procédure de suppression de fichier : [supprimer un justificatif](FichiersJustificatifs.md#supprimer-un-fichier)

* **Routes:** `/justificatif/<int:justif_id>/remove`

* **Résultat:** `{"response":"removed"}` ou une erreur
* **Exemple de résultat:**  [justificatif-remove.json](samples/sample_justificatif_remove.json.md)

#### **justificatif-list**

* **Méthode:** GET
* **Permission: `ScoView` / `ScoJustifView`**
  * Si `ScoView` : retourne uniquement les fichiers fourni par le même utilisateur
  * Si `ScoJustifView` : retourne tous les fichiers
* **Paramètres:** `justif_id`
* **Routes:** `/justificatif/<int:justif_id>/list`
* **Exemple d'utilisation:** `/api/justificatif/1/list`
* **Résultat:** 
  ```json
    {
      "filenames" : [
        <str>,
        ...
      ],

      "total": <int>
    }
  ```
  * Le total indique le nombre total de fichiers (visibles ou non)

* **Exemple de résultat:**  [justificatif-list.json](samples/sample_justificatif_list.json.md)

#### **justificatif-justifies**

* **Méthode:** GET
* **Permission: `ScoView`**
* **Paramètres:** `justif_id`
* **Routes:** `/justificatif/<int:justif_id>/justifies`
* **Exemple d'utilisation:** `/api/justificatif/1/justifies`
* **Résultat:** Retourne la liste des assiduite_id qui sont justifiés par le justificatif ou une erreur si l'id n'est pas connu
* **Exemple de résultat:**  [justificatif-justifies.json](samples/sample_justificatif_justifies.json.md)

---------------------------------------------------------------------------------------------------------------------

### En savoir plus

Voir exemples d'utilisation de l'API en Python, dans `tests/api/`.

## Fonctions de l'API ScoDoc 7 portées en ScoDoc 9

**Février 2023: L'ancienne API ScoDoc 7 n'est plus documentée et plus disponible.**

Afin de garantir l'interopérabilité avec les clients ScoDoc 7 (ENT, etc), les
fonctions suivantes sont disponibles avec le mécanisme d'authentification
basique de ScoDoc 7. Elles sont considérées comme *obsolètes* ("deprecated") et
disparaitront en juillet 2022.

Certaines ont plusieurs "routes" (URl), car ScoDoc 7 tolérait divers accès.

* `Absences/XMLgetBilletsEtud` (deviendra `api/absences/billets/etud/ etudid>`)
* `Absences/AddBilletAbsence` (deviendra `api/absences/billet/add`)
* `Absences/XMLgetAbsEtud` (deviendra `api/absences/ etudid>`, en json)
* `Notes/evaluation_listenotes` (non existante en ScoDoc9, trop complexe)
* `Notes/formsemestre_id` (deviendra `api/formsemestre`)
* `Notes/formsemestre_bulletinetud` (deviendra `api/etud/<etudid>/bul/<formsemestre_id>`)
* `Notes/XMLgetFormsemestres` (non existante en ScoDoc9, redondant avec `api/formsemestre` ?)
* `etud_info` ou `XMLgetEtudInfos` ou `Absences/XMLgetEtudInfos` ou `Notes/XMLgetEtudInfos` (deviendra `/api/etud/<etudid>`)
* `groups_view` (deviendra `groups`)

Les routes ci-dessus s'entendent à partir de l'URL de base de votre ScoDoc, c'est
à dire `https://votre.site.fr/ScoDoc/<dept>/Scolarite/`, et répondent en GET et
en POST.

Note:

 - `Absences/listeBillets` est un formulaire et ne fait pas partie de l'API.

!!! note "Voir aussi"

    - [Guide configuration et ligne de commande](GuideConfig.md)
    - [Guide administrateur ScoDoc](GuideAdminSys.md)
    - [ServicesXml](ServicesXml.md) : anciens web services XML (obsolète)
    - [FAQ](FAQ.md)
    - [Contacts](Contact.md)
