# Code de ScoDoc 9 Quelques informations pour les développeurs. - le code est écrit en Python 3.9 (passage à 3.10 prévu en 2022). - le code doit être formatté par [black](https://pypi.org/project/black/) qui est normalement intégré à votre éditeur (VSCode et PyCharm sont deux choix judicieux). - outre Python, les principaux composants logiciels sont: - [Flask](https://flask-sqlalchemy.palletsprojects.com/en/2.x/): le framework Web, dont on utilise notamment: - l'ORM [SQLAlchemy](https://www.sqlalchemy.org/) - les templates [Jinja2](https://jinja.palletsprojects.com/en/3.0.x/) - [Postgresql](https://www.postgresql.org/) - [Redis](https://redis.io/) cache persistant - [NGINX](https://www.nginx.com/) serveur Web frontal - [gunicorn](https://gunicorn.org/) WSGI HTTP server - et bien sûr Linux (Debian) et systemd. # Principaux objets Les objets manipulés par ScoDoc sont pour la plupart stockés en base postgres et accédé soit directement en SQL (anciennes parties de ScoDoc), soit à travers l'ORM SQLAlchemy (recommandé pour tout nouveau code). Les modèles correspondant sont déclarés dans `/opt/scodoc/app/models/`. Principales classes (le nom de certaines classes Python est donné en `CaractèresCommeCa`). - Étudiants (classe `Identite`): nom, codes INE/NIP, etc - Formations: programmes pédagogiques, contenant - Unités d'Enseignement (`UniteEns`); - Matières et Modules (`Module`, avec son type standard, bonus, ressources ou SAÉ). - FormSemestre: instanciation d'une session de formation, avec un programme pédagogique donné (Formation), les dates de début et fin, des étudiants inscrits, des responsables, divers codes, et les ModuleImpl mis en œuvre. - ModuleImpl: la mise en place d'un module pédagogique (le ModuleImpl est au Module ce que le FormSemestre est à la Formation): lié à un module, avec un enseignant responsable et des étudiants inscrits. - Inscriptions: tables d'association avec codes et/ou état (démission, défaillant): FormsemestreInscription ModuleImplInscription. # Vues et décorateurs Une vue ordinaire (Web) pourrait ressembler à cela. Noter la présence de décorateurs: - `@scodoc` récupère le département (présent dans l'URL) et initialise quelques trucs; - `@permission_required`: permet de contrôler l'accès, en se basant sur les permissions définies dans la classe `Permission`. ``` @bp.route("/un_exemple") @scodoc @permission_required(Permission.ScoChangeFormation) def un_exemple(): # Récupérer le ou les arguments: exemple avec formation_id formation_id = int(request.args["formation_id"]) # Charger le ou les objets utilies: formation = models.Formation.query.get( formation_id=formation_id ).first_or_404() # Effectuer au besoin un traitement resultat = ... # Afficher le résultat return render_template( "exemple_template.html", resultat=resultat, # par exemple formation=formation, ... # etc ) ```