master #22

Closed
leonard.montalbano wants to merge 14 commits from leonard.montalbano/DocScoDoc:master into master
4 changed files with 332 additions and 227 deletions
Showing only changes of commit 53e6bbe24b - Show all commits

View File

@ -57,7 +57,7 @@ Le serveur est fréquemment installé sur un réseau protégé ou sur un VPN.
- le serveur doit pouvoir envoyer du mail (serveur postfix en local, à - le serveur doit pouvoir envoyer du mail (serveur postfix en local, à
configurer pour utiliser un relais smtp ou envoyer directement, selon configurer pour utiliser un relais smtp ou envoyer directement, selon
votre politique); votre politique. Au besoin, pour le reconfigurer, lancer `dpkg-reconfigure postfix`);
- Les serveurs de mise à jour de Debian doivent être accessibles (en http, - Les serveurs de mise à jour de Debian doivent être accessibles (en http,
voir `/etc/apt/sources.list`); voir `/etc/apt/sources.list`);
@ -105,6 +105,9 @@ Checklist minimale de votre système Linux Debian:
1. Date et heure: vérifier que les dates et heure sont correctes, même après 1. Date et heure: vérifier que les dates et heure sont correctes, même après
reboot. L'utilisation d'un serveur de temps (ntp) est recommandée ( reboot. L'utilisation d'un serveur de temps (ntp) est recommandée (
`apt-get install ntp`), et éventuellement `dpkg-reconfigure tzdata`). `apt-get install ntp`), et éventuellement `dpkg-reconfigure tzdata`).
1. Si vous avez installé à partir d'un support (DVD, clé USB...), pensez à le
retirer des sources Debian afin de ne pas bloquer les mise à jour (commenter
la ligne `deb cdrom:` dans le fichier `/etc/apt/sources.list`)
1. Cette liste est incomplète... et n'oubliez pas: avant de passer en 1. Cette liste est incomplète... et n'oubliez pas: avant de passer en
production, mettez en place des sauvegardes sérieuses ! production, mettez en place des sauvegardes sérieuses !

View File

@ -45,7 +45,7 @@ tous les types de formation. La notion de "matière" n'est pas utilisée en BUT)
- Formation (ex: "BUT R&T") - Formation (ex: "BUT R&T")
- UniteEns (UE, ex: "Administrer les réseaux") - UniteEns (UE, ex: "Administrer les réseaux")
- Modules (ressources, SAÉs) *<-> ApcAppCritique*, *<-> ApcParcours* - Modules (ressources, SAÉs) *<-> ApcAppCritique*, *<-> ApcAnneeParcours*
On voit que les modules ont toujours une UE de rattachement. Cependant, en BUT, On voit que les modules ont toujours une UE de rattachement. Cependant, en BUT,
un module peut intervenir dans le calcul des notes de plusieurs UE, via une un module peut intervenir dans le calcul des notes de plusieurs UE, via une
@ -63,11 +63,11 @@ Le référentiel de compétences est structuré par les classes suivantes:
- ApcCompetence - ApcCompetence
- ApcSituationPro - ApcSituationPro
- ApcComposanteEssentielle - ApcComposanteEssentielle
- ApcNiveau (année, ordre) - ApcNiveau (année (BUT1, BUT2, ...), ordre (1,2) ou (1,2,3)) *<-> UE*
- ApcAppCritique *<-> Module* - ApcAppCritique *<-> Module*
- ApcParcours - ApcParcours
- ApcAnneeParcours - ApcAnneeParcours (ordre=1,2,3) *<-> Module*
- ApcParcoursNiveauCompetence - *ApcCompetence* <- ApcParcoursNiveauCompetence (niveau 1, 2, 3) -> *ApcAnneeParcours*
Notons le lien entre les apprentissages critiques (ApcAppCritique) et les Notons le lien entre les apprentissages critiques (ApcAppCritique) et les
modules, qui permet d'établir les critères d'évaluation de chaque module. modules, qui permet d'établir les critères d'évaluation de chaque module.
@ -94,15 +94,19 @@ Les étudiants sont inscrits:
Pour la gestion des parcours BUT, il faut introduire les associations suivantes, Pour la gestion des parcours BUT, il faut introduire les associations suivantes,
qui n'existent pas dans ScoDoc 9.2: qui n'existent pas dans ScoDoc 9.2:
- Module ||--o{ ApcAppCritique : choix sur la page `module_edit` - UE <-> ApcNiveau : choix sur la page `ue_edit`
- Module <-> ensemble de ApcParcours - Module <-> ensemble de ApcParcours
- UE <-> ApcParcoursNiveauCompetence : choix sur la page `ue_edit` - Module ||--o{ ApcAppCritique : choix sur la page `module_edit`
- FormSemestre ||--o{ ApcParcours : choix sur la page - FormSemestre ||--o{ ApcParcours : choix sur la page
`formsemestre_editwithmodules` `formsemestre_editwithmodules`
- Identite }o--o{ ApcParcours : inscription au parcours, page à créer. - Identite }o--o{ ApcParcours : inscription au parcours, page à créer.
### Cas d'usage ### Cas d'usage
#### Niveau de compétence d'un formsemestre
Le formsemestre est lié à un ensemble d'ApcParcours.
#### Inscription d'un étudiant aux ModuleImpls #### Inscription d'un étudiant aux ModuleImpls
L'inscription reste libre (chaque individu peut être inscrit à un sous-ensemble L'inscription reste libre (chaque individu peut être inscrit à un sous-ensemble
quelconque des ModuleImpl du FormSemestre), mais il sera commode de pouvoir: quelconque des ModuleImpl du FormSemestre), mais il sera commode de pouvoir:
@ -169,6 +173,7 @@ particuliers (décision de jury manuelle).
- [x] pour le passage en S5, avoir validé toutes les UE du BUT 1 (S1 et S2). - [x] pour le passage en S5, avoir validé toutes les UE du BUT 1 (S1 et S2).
Il faut donc: Il faut donc:
1. Construire les regroupements d'UE et calculer la moyenne des moyennes d'UE 1. Construire les regroupements d'UE et calculer la moyenne des moyennes d'UE
(a priori de même poids, cela n'est pas spécifié dans les textes). (a priori de même poids, cela n'est pas spécifié dans les textes).

View File

@ -57,6 +57,55 @@ 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).
## 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:
```
http -a USER:PASSWORD POST 'http://localhost:5000/ScoDoc/api/tokens'
```
Qui affiche:
```
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:
```
http GET http://localhost:5000/ScoDoc/api/departements "Authorization:Bearer jS7iVlH1234cRDzboAfO5xseE0Ain6Zyz"
```
qui affiche par exemple:
```
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 (work in progress) ## Fonctions d'API ScoDoc 9 (work in progress)
Basé sur le ticket [#149](https://scodoc.org/git/viennet/ScoDoc/issues/149) Basé sur le ticket [#149](https://scodoc.org/git/viennet/ScoDoc/issues/149)
@ -78,9 +127,9 @@ 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. 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 Exemple avec `curl` (un outil en ligne de commande présent sur la plupart des
systèmes): systèmes, voir plus haut pour la ême chose avec la commande `http`):
curl -u user_name:password --request POST https://SERVEUR/ScoDoc/api/tokens curl -u user_name:password --request POST https://SERVEUR/ScoDoc/api/tokens
`SERVEUR` est l'adresse (IP ou nom) de votre serveur. `SERVEUR` est l'adresse (IP ou nom) de votre serveur.
La réponse doit ressembler à ceci: La réponse doit ressembler à ceci:
@ -98,156 +147,152 @@ Chaque appel à l'API donne lieu à une réponse retournant un code spécifique
fonction du résultat obtenu. L'analyse de ce code vous permet de vous assurer 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. 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 nos serveurs. 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. * [200](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/200) : OK.
* [400](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/401) : Paramètre manquant, ou valeur incorrecte. * [400](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/401) : Paramètre manquant, ou valeur incorrecte.
* [401](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/401) : Authentification nécessaire. (jeton non précisé ou invalide) * [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. (crédits épuisés, URL non autorisée, etc) * [403](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/403) : Action
* [404](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/404) : Page inaccessible. (URL inconnue / impossible d'accéder à l'adresse) non autorisée pour l'utilisateur associé au jeton
* [404](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/404) : Page
inaccessible: URL inconnue ou paramètre (id) invalide
* [406](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/406) : Le JSON indiqué en données POST n'est pas valide. * [406](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/406) : Le JSON indiqué en données POST n'est pas valide.
* [408](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/408) : Dépassement du temps maximal autorisé pour laudit.
* [500](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/500) : Erreur inconnue, contactez-nous. * [500](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/500) : Erreur inconnue, contactez-nous.
* [503](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/503) : L'API est momentanément indisponible, réessayez dans quelques minutes.
#### Note sur les identifiants de sessions ## Départements
Le `session_id` peut être utilisé pour identifier de façon prévisible et
(presque) unique une session 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...) (= paramètre `DeptName`, en majuscules) * **`departements_ids`**
* **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) nouveau dans la "formation" (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)
### Départements
* **`departements`**
* **Méthode:** GET * **Méthode:** GET
* **Routes:** `/departements` * **Routes:** `/departements_ids`
* **Exemple d'utilisation:** `/api/departements` * **Résultat:** Liste des id départements (visibles ou non).
* **Résultat:** Liste des départements.
* **Exemple de résultat:** * **Exemple de résultat:**
``` ```
[ [ 1888, 999, 165 ]
{ ```
* **`departement`**
* **Méthode:** GET
* **Routes:** `/departement/<dept_id>`
* **Résultat:** Un département
* **Exemple de résultat:**
```
{
"id": 1, "id": 1,
"acronym": "TAPI", "acronym": "TAPI",
"description": null, "description": null,
"visible": true, "visible": true,
"date_creation": "Fri, 15 Apr 2022 12:19:28 GMT" "date_creation": "Fri, 15 Apr 2022 12:19:28 GMT"
}, },
{ ```
"id": 2,
"acronym": "MMI", * **`departements`**
"description": null, * **Méthode:** GET
"visible": false, * **Routes:** `/departements`
"date_creation": "Fri, 18 Apr 2022 11:20:8 GMT" * **Exemple d'utilisation:** `/api/departements`
}, * **Résultat:** Liste des tous les départements (visibles ou non).
* **Exemple de résultat:**
```
[
{ un département }
... ...
] ]
``` ```
* **`liste_etudiants`** * **Étudiants d'un département**
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `dept`, `formsemestre_id` * **Paramètres:** `dept`, `formsemestre_id`
* **Routes:** `/departements/<string:dept>/etudiants/list` ou `/api/departements/<string:dept>/etudiants/list/<int:formsemestre_id>` * **Routes:** `/departement/<string:dept>/etudiants`
* **Exemple d'utilisation:** `/api/departements/MMI/etudiants/list` * **Exemple d'utilisation:** `/api/departement/MMI/etudiants`
* **Résultat:** liste des étudiants d'un département, par défaut, ou d'un semestre si renseigné. (json) * **Résultat:** liste tous les étudiants d'un département, par défaut, ou d'un
formsemestre si renseigné. 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:** * **Exemple de résultat:**
``` ```
[ [
{ {
"civilite": "X", "civilite": "M", // M, F ou X
"code_ine": null, "ine": "7899X61616",
"code_nip": null, "nip": "F6777H88",
"date_naissance": null, "date_naissance": null,
"email": null, "email": "toto@toto.fr",
"emailperso": null, "emailperso": null,
"etudid": 18, "etudid": 18,
"nom": "MOREL", "nom": "MOREL", // en majuscules
"prenom": "JACQUES" "prenom": "JACQUES"
},
{
"civilite": "X",
"code_ine": null,
"code_nip": null,
"date_naissance": null,
"email": null,
"emailperso": null,
"etudid": 19,
"nom": "FOURNIER",
"prenom": "ANNE"
}, },
... ...
] ]
``` ```
#### Semestres
* **`liste_semestres_courant`** * **Formsemestres**
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `dept` * **Paramètres:** `dept`
* **Routes:** `/departements/<string:dept>/semestres_courants` * **Routes:** `/departement/<string:dept>/formsemestres_ids`
* **Exemple d'utilisation:** `/api/departements/MMI/semestres_courants` * **Exemple d'utilisation:** `/api/departements/MMI/formsemestres_ids`
* **Résultat:** Liste des semestres actifs d'un département donné. (_réponse sous format json_) * **Résultat:** Liste des id des formsemestres d'un département donné.
* **Exemple de résultat:**
```[ 28, 99, 3 ]```
* **Formsemestres en cours**
* **Méthode:** GET
* **Paramètres:** `dept`
* **Routes:** `/departement/<string:dept>/formsemestres_courants`
* **Exemple d'utilisation:** `/api/departements/MMI/formsemestres_courants`
* **Résultat:** Liste des formsemestres en cours d'un département donné.
* **Exemple de résultat:** * **Exemple de résultat:**
``` ```
[ [
{ {
"block_moyennes": false,
"bul_bgcolor": "white",
"bul_hide_xml": false,
"date_debut_iso": "2021-09-01",
"date_debut": "01/09/2021",
"date_fin_iso": "2022-08-31",
"date_fin": "31/08/2022", "date_fin": "31/08/2022",
"resp_can_edit": false,
"dept_id": 1, "dept_id": 1,
"elt_annee_apo": "V7HU",
"elt_sem_apo": null,
"ens_can_edit_eval": false,
"etat": true, "etat": true,
"resp_can_change_ens": true, "formation_id": 1,
"formsemestre_id": 1,
"gestion_compensation": false,
"gestion_semestrielle": false,
"id": 1, "id": 1,
"modalite": "FI", "modalite": "FI",
"ens_can_edit_eval": false, "resp_can_change_ens": true,
"formation_id": 1, "resp_can_edit": false,
"gestion_compensation": false,
"elt_sem_apo": null,
"semestre_id": 1,
"bul_hide_xml": false,
"elt_annee_apo": null,
"titre": "Semestre test",
"block_moyennes": false,
"scodoc7_id": null,
"date_debut": "01/09/2021",
"gestion_semestrielle": false,
"bul_bgcolor": "white",
"formsemestre_id": 1,
"titre_num": "Semestre test semestre 1",
"date_debut_iso": "2021-09-01",
"date_fin_iso": "2022-08-31",
"responsables": [ "responsables": [
12, 12,
42 42
], ],
"titre_court": "BUT MMI" "scodoc7_id": null,
"semestre_id": 1,
"titre_num": "BUT MMI semestre 1",
"titre": "BUT MMI",
"titre_formation": "BUT MMI"
}, },
... ...
] ]
``` ```
Le `titre`est celui donné par l'utilisateur dans le formsemestre, tandis que le
`titre_formation` est l'acronyme de la formation (défini dans son programme pédagogique).
### Etudiants ## Étudiants
* **`etudiants_courant`** * **`etudiants_courant`**
* **Méthode:** GET * **Méthode:** GET
* **Routes:** `/etudiants/courant` ou `/etudiants/courant/long` * **Routes:** `/etudiants/courant` ou `/etudiants/courant/long`
* **Exemple d'utilisation:** `/api/etudiants/courant` * **Exemple d'utilisation:** `/api/etudiants/courant`
* **Résultat:** Retourne la liste des étudiants courant (json). * **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:** * **Exemple de résultat:**
``` ```
[ [
@ -304,7 +349,7 @@ informations suivantes:
} }
``` ```
#### Cursus
* **`etudiant_formsemestres`** * **`etudiant_formsemestres`**
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `etudid`, `nip`, `ine` * **Paramètres:** `etudid`, `nip`, `ine`
@ -349,13 +394,16 @@ informations suivantes:
] ]
``` ```
#### Bulletin
* **`etudiant_bulletin_semestre`** * **`etudiant_bulletin_semestre`**
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `formsemestre_id`, `etudid`, `nip`, `ine` * **Paramètres:** `formsemestre_id`, `etudid`, `nip`, `ine`
* **Routes:** `/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin` ou `/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin` ou `/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin` * **Routes:**
`/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/bulletin`
ou `/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin`
ou `/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin`
* **Exemple d'utilisation:** `/etudiant/nip/1/formsemestre/1/bulletin` * **Exemple d'utilisation:** `/etudiant/nip/1/formsemestre/1/bulletin`
* **Résultat:** Retourne le bulletin d'un étudiant en fonction de son id et d'un semestre donné. (json) * **Résultat:** Bulletin de l'étudiant dans le formsemestre.
* **Exemple de résultat:** * **Exemple de résultat:**
``` ```
{ {
@ -571,15 +619,15 @@ informations suivantes:
* **Méthode:** GET * **Méthode:** GET
* **Routes:** `/ScoDoc/api/formations_ids` * **Routes:** `/ScoDoc/api/formations_ids`
* **Exemple d'utilisation:** `/ScoDoc/api/formations_ids` * **Exemple d'utilisation:** `/ScoDoc/api/formations_ids`
* **Résultat:** Retourne la liste de toutes les id de formations (tous départements) * **Résultat:** Retourne la liste des ids de toutes les formations (tous départements)
* **Exemple de résultat:** `[17, 99, 32]` * **Exemple de résultat:** `[17, 99, 32]`
* **`formations_by_id`** * **`formations_by_id`**
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `formation_id` * **Paramètres:** `formation_id`
* **Routes:** `/formations/<int:formation_id>` * **Routes:** `/formation/<int:formation_id>`
* **Exemple d'utilisation:** `/ScoDoc/api/formations/1` * **Exemple d'utilisation:** `/ScoDoc/api/formation/1`
* **Résultat:** Retourne une formation en fonction d'un id donné * **Résultat:** Retourne une formation en fonction d'un id donné
* **Exemple de résultat:** * **Exemple de résultat:**
``` ```
@ -597,11 +645,12 @@ informations suivantes:
"formation_id": 1 "formation_id": 1
} }
``` ```
#### Export programme
* **`formation_export_by_formation_id`** * **`formation_export_by_formation_id`**
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `formation_id`, `export_ids` (False par défaut. Ajouter `/with_ids` pour le passer à True) * **Paramètres:** `formation_id`, `export_ids` (False par défaut. Ajouter `/with_ids` pour le passer à True)
* **Routes:** `/formations/formation_export/<int:formation_id>` * **Routes:** `/formation/formation_export/<int:formation_id>`
* **Exemple d'utilisation:** `/ScoDoc/api/formations/formation_export/1` * **Exemple d'utilisation:** `/ScoDoc/api/formation/formation_export/1`
* **Résultat:** Retourne la formation, avec UE, matières, modules * **Résultat:** Retourne la formation, avec UE, matières, modules
* **Exemple de résultat:** * **Exemple de résultat:**
``` ```
@ -691,17 +740,18 @@ informations suivantes:
] ]
} }
``` ```
#### Référentiel de compétences
* **`referentiel_competences`** * **`referentiel_competences`**
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `formation_id` * **Paramètres:** `formation_id`
* **Routes:** `/formations/<int:formation_id>/referentiel_competences` * **Routes:** `/formation/<int:formation_id>/referentiel_competences`
* **Exemple d'utilisation:** `api/formations/1/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_) * **Résultat:** Le référentiel de compétences d'une formation donnée (json). (_pas toujours présent_)
* XXX obtenir la liste des référentiels * XXX obtenir la liste des référentiels
### Semestres de formation ## Formsemestres
Les sessions de formation (dénommées "semestres" même si elles durent une année ou un mois) sont représentées par les `formsemestre`. Les sessions de formation (qu'elles durent une année ou un mois) sont représentées par les `formsemestre`.
* **`formsemestre`** * **`formsemestre`**
* **Méthode:** GET * **Méthode:** GET
@ -753,47 +803,76 @@ Les sessions de formation (dénommées "semestres" même si elles durent une ann
``` ```
[ [
{ {
"block_moyennes": false,
"bul_bgcolor": "white",
"bul_hide_xml": false,
"date_debut_iso": "2021-09-01",
"date_debut": "01/09/2021",
"date_fin_iso": "2022-08-31",
"date_fin": "31/08/2022", "date_fin": "31/08/2022",
"resp_can_edit": false,
"dept_id": 1, "dept_id": 1,
"elt_annee_apo": null,
"elt_sem_apo": null,
"ens_can_edit_eval": false,
"etat": true, "etat": true,
"resp_can_change_ens": true, "formation_id": 1,
"formsemestre_id": 1,
"gestion_compensation": false,
"gestion_semestrielle": false,
"id": 1, "id": 1,
"modalite": "FI", "modalite": "FI",
"ens_can_edit_eval": false, "resp_can_change_ens": true,
"formation_id": 1, "resp_can_edit": false,
"gestion_compensation": false,
"elt_sem_apo": null,
"semestre_id": 1,
"bul_hide_xml": false,
"elt_annee_apo": null,
"titre": "Semestre test",
"block_moyennes": false,
"scodoc7_id": null,
"date_debut": "01/09/2021",
"gestion_semestrielle": false,
"bul_bgcolor": "white",
"formsemestre_id": 1,
"titre_num": "Semestre test semestre 1",
"date_debut_iso": "2021-09-01",
"date_fin_iso": "2022-08-31",
"responsables": [ "responsables": [
12, 12,
42 42
], ],
"titre_court": "BUT MMI" "scodoc7_id": null,
"semestre_id": 1,
"titre_court": "BUT MMI",
"titre_num": "Semestre test semestre 1",
"titre": "Semestre test",
"session_id": "MMI-BUT-FI-S1-2021",
}, },
... ...
] ]
``` ```
#### Note sur les identifiants de formsemestre
Le `session_id` peut être utilisé pour identifier de façon prévisible et
(presque) unique un 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)
#### Étudiants inscrits
* **etudiants**
* **Méthode:** GET
* **Routes:** `/formsemestre/<int:formsemestre_id>/etudiants`
* **Résultat:** les étudiants inscrits à ce semestres XXX préciser état
(DEM, DEF))
#### Bulletins
* **`bulletins`** * **`bulletins`**
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `formsemestre_id` * **Paramètres:** `formsemestre_id`
* **Routes:** `/formsemestre/<int:formsemestre_id>/bulletins` * **Routes:** `/formsemestre/<int:formsemestre_id>/bulletins`
* **Exemple d'utilisation:** `/ScoDoc/api/formsemestre/1/bulletins` * **Exemple d'utilisation:** `/ScoDoc/api/formsemestre/1/bulletins`
* **Résultat:** Retourne les bulletins d'un formsemestre donné * **Résultat:** tous les bulletins d'un formsemestre.
* **Exemple de résultat:** * **Exemple de résultat:**
``` ```
[ [
@ -970,7 +1049,7 @@ Les sessions de formation (dénommées "semestres" même si elles durent une ann
* **`jury`** * **`jury`** (**non implémentée**)
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `formsemestre_id` * **Paramètres:** `formsemestre_id`
* **Routes:** `/formsemestre/<int:formsemestre_id>/jury` * **Routes:** `/formsemestre/<int:formsemestre_id>/jury`
@ -980,13 +1059,14 @@ Les sessions de formation (dénommées "semestres" même si elles durent une ann
``` ```
XXX A COMPLETER XXX A COMPLETER
``` ```
* **`programme`** #### Programme d'un formsemestre
* **UE et modules**
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `dept`, `formsemestre_id` * **Paramètres:** `dept`, `formsemestre_id`
* **Routes:** `/formsemestre/<int:formsemestre_id>/programme` * **Routes:** `/formsemestre/<int:formsemestre_id>/programme`
* **Exemple d'utilisation:** `api/formsemestre/1/programme` * **Exemple d'utilisation:** `api/formsemestre/1/programme`
* **Résultat:** Retourne la liste des Ues, ressources et SAE d'un semestre (json). * **Résultat:** Retourne la liste des UEs, modules, ressources et SAE d'un semestre.
* **Exemple de résultat:** * **Exemple de résultat:**
``` ```
{ {
@ -996,13 +1076,13 @@ Les sessions de formation (dénommées "semestres" même si elles durent une ann
"formation_id": 1, "formation_id": 1,
"ue_code": "UCOD11", "ue_code": "UCOD11",
"id": 1, "id": 1,
"ects": 12, "ects": 12.0,
"acronyme": "RT1.1", "acronyme": "RT1.1",
"is_external": false, "is_external": false,
"numero": 1, "numero": 1,
"code_apogee": "", "code_apogee": "",
"titre": "Administrer les réseaux et lInternet", "titre": "Administrer les r\u00e9seaux et l\u2019Internet",
"coefficient": 0, "coefficient": 0.0,
"semestre_idx": 1, "semestre_idx": 1,
"color": "#B80004", "color": "#B80004",
"ue_id": 1 "ue_id": 1
@ -1011,61 +1091,54 @@ Les sessions de formation (dénommées "semestres" même si elles durent une ann
], ],
"ressources": [ "ressources": [
{ {
"titre": "Fondamentaux de la programmation", "ens": [ 10, 18 ],
"coefficient": 1, "formsemestre_id": 1,
"module_type": 2, "id": 15,
"id": 17, "module": {
"ects": null, "abbrev": "Programmer",
"abbrev": null, "code": "SAE15",
"ue_id": 3, "code_apogee": "V7GOP",
"code": "R107", "coefficient": 1.0,
"formation_id": 1, "formation_id": 1,
"heures_cours": 0, "heures_cours": 0.0,
"matiere_id": 3, "heures_td": 0.0,
"heures_td": 0, "heures_tp": 0.0,
"semestre_id": 1, "id": 15,
"heures_tp": 0, "matiere_id": 3,
"numero": 70, "module_id": 15,
"code_apogee": "", "module_type": 3,
"module_id": 17 "numero": 50,
"semestre_id": 1,
"titre": "Programmer en Python",
"ue_id": 3
}, },
"module_id": 15,
"moduleimpl_id": 15,
"responsable_id": 2
},
... ...
], ],
"saes": [ "saes": [
{ {
"titre": "Se présenter sur Internet", ...
"coefficient": 1,
"module_type": 3,
"id": 14,
"ects": null,
"abbrev": null,
"ue_id": 3,
"code": "SAE14",
"formation_id": 1,
"heures_cours": 0,
"matiere_id": 3,
"heures_td": 0,
"semestre_id": 1,
"heures_tp": 0,
"numero": 40,
"code_apogee": "",
"module_id": 14
}, },
... ...
] ],
"modules" : [ ... les modules qui ne sont ni des SAEs ni des ressources ... ]
} }
``` ```
### Modules de formation #### Module d'un formsemestre
Les moduleimpl sont les modules d'un semestre, ou les ressources, ou les SAÉs.
On peut récupérer soit un module par son id, soit la listes des modules d'un semestre. Le moduleimpl est la mise en place d'un module dans un formsemestre (avec son
responsable et ses enseignants).
* **`moduleimpl`** * **`moduleimpl`**
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `moduleimpl_id` * **Paramètres:** `moduleimpl_id`
* **Routes:** `/formations/moduleimpl/<int:moduleimpl_id>` * **Routes:** `/formation/moduleimpl/<int:moduleimpl_id>`
* **Exemple d'utilisation:** `/ScoDoc/api/formations/moduleimpl/1` * **Exemple d'utilisation:** `/ScoDoc/api/formation/moduleimpl/1`
* **Résultat:** Retourne la liste des moduleimpl * **Résultat:** Retourne la liste des moduleimpl
* **Exemple de résultat:** * **Exemple de résultat:**
``` ```
@ -1098,47 +1171,7 @@ On peut récupérer soit un module par son id, soit la listes des modules d'un s
} }
} }
``` ```
* **`moduleimpls_sem`**
* **Méthode:** GET
* **Paramètres:** `moduleimpl_id`
* **Routes:** `/formations/moduleimpl/formsemestre/<int:formsemestre_id>/list`
* **Exemple d'utilisation:** `/ScoDoc/api/formations/moduleimpl/formsemestre/1/list`
* **Résultat:** Retourne la liste des moduleimpl d'un semestre
* **Exemple de résultat:**
```
[
{
"id": 1,
"formsemestre_id": 1,
"computation_expr": null,
"module_id": 1,
"responsable_id": 2,
"module": {
"heures_tp": 0,
"code_apogee": "",
"titre": "Initiation aux réseaux informatiques",
"coefficient": 1,
"module_type": 2,
"id": 1,
"ects": null,
"abbrev": "Init aux réseaux informatiques",
"ue_id": 1,
"code": "R101",
"formation_id": 1,
"heures_cours": 0,
"matiere_id": 1,
"heures_td": 0,
"semestre_id": 1,
"numero": 10,
"module_id": 1
},
"moduleimpl_id": 1,
"ens": []
}
]
```
### Groupes et partitions ### Groupes et partitions
L'ensemble des étudiants d'un semestre peut être réparti selon une ou L'ensemble des étudiants d'un semestre peut être réparti selon une ou
@ -1225,7 +1258,7 @@ d'un nombre quelconque de groupes d'étudiants.
``` ```
* **`set_groups`** * **`set_groups`** **NON IMPLEMENTE**
* **Méthode:** POST * **Méthode:** POST
* **Paramètres:** `partition_id`, `groups_lists`, `groups_to_delete`, `groups_to_create` * **Paramètres:** `partition_id`, `groups_lists`, `groups_to_delete`, `groups_to_create`
* **Routes:** `/partitions/set_groups/partition/<int:partition_id>/groups/<string:groups_id>/delete/<string:groups_to_delete>/create/<string:groups_to_create>` * **Routes:** `/partitions/set_groups/partition/<int:partition_id>/groups/<string:groups_id>/delete/<string:groups_to_delete>/create/<string:groups_to_create>`
@ -1233,7 +1266,7 @@ d'un nombre quelconque de groupes d'étudiants.
* **Résultat:** Set les groups. * **Résultat:** Set les groups.
### Bulletins de notes ### Résultats des évaluations
* **`evaluations`** * **`evaluations`**
* **Méthode:** GET * **Méthode:** GET
* **Paramètres:** `moduleimpl_id` * **Paramètres:** `moduleimpl_id`

View File

@ -28,7 +28,7 @@ lance l'ensemble des tests unitaires.
## Tests Selenium (web) ## Tests Selenium (web)
TODO (Aurélien, JMP) TODO (Aurélien, JMP) *ce projet est abandonné pour l'instant*.
## Portail pour tests ## Portail pour tests
@ -42,6 +42,70 @@ Lancement:
/opt/scodoc/tools/fakeportal/fakeportal.py /opt/scodoc/tools/fakeportal/fakeportal.py
## Tests de l'API ScoDoc9
L'API est [documentée ici](ScoDoc9API.md).
Des tests sont disponibles sous `scodoc/tests/api`. Le mécanisme de test est un
peu différent de celui des tests unitaire: on test un *client* de l'API. Il faut
donc un serveur, tournant sur la même machine ou sur une machine distante. Ce
serveur doit avoir été configuré avec des données de test.
### Configuration du serveur pour tester l'API
1. modifier /opt/scodoc/.env pour indiquer
```
FLASK_ENV=test_api
FLASK_DEBUG=1
```
2. En tant qu'utilisateur scodoc, lancer:
```
tools/create_database.sh --drop SCODOC_TEST_API
flask db upgrade
flask sco-db-init --erase
flask init-test-database
```
Ces commandes vont effacer la base `SCODOC_TEST_API` si elle existe, la
recréer, mettre à jour le schéma pour la dernière version de ScoDoc installée,
l'initialiser et la peupler de données fictives pour les tests.
3. Relancer ScoDoc:
```
flask run --host 0.0.0.0
```
### Configuration du client de test API
1. Copier le fichier `scodoc/tests/api/dotenv_exemple` dans
`scodoc/tests/api/.env`, et éditer ce fichier `.env`pour y configurer votre
*client* de test (ne pas confondre avec `scodoc/.env` qui est la config de
votre serveur).
Normalement, il est suffisant d'indiquer l'URL de votre serveur. Si le
client de test est sur la même machine que le serveur ScoDoc, c'est simplement:
```
SCODOC_URL = "http://localhost:5000/"
```
### Lancement des tests de l'API
Le serveur scodoc étant lancé comme expliqué ci-dessus, on utilise `pytest`sur
le client (qui peut être un autre shell de la même machine, bien sûr).
```
cd /opt/scodoc/
pytest tests/api/test_api_xxx.py # remplacer xxx par votre test
```
Rappelons quelques options utiles de `pytest`: `-x` permet de s'arrêter sur la
première erreur, et `--pdb` lance directement le débuggueur sur l'erreur.
Ainsi,
```
pytest --pdb -x tests/api/test_api_departements.py
```
lancera un test en mode "interactif", utile pour les mises au point.