Installation d'un environnement de dev
Pré-requis
-
Python 3.9
-
Poetry (avec les modules poetry-plugin-export, poetry-dotenv-plugin, poetry-plugin-sort)
poetry self add poetry-plugin-export poetry-dotenv-plugin poetry-plugin-sort
- Docker
Ajout de l'utilisateur courant au groupe docker
pour utilisation des commandes docker
sudo usermod -aG docker $USER
Créer un environnement virtuel avec Poetry
Créer un environnement virtuel en python 3.9 : poetry env use 3.9
Installer les dépendances : poetry install
Installer les hooks de pre-commit : poetry run pre-commit install
Debian
Sur une Debian récente, python3.9 n'est plus installable.
Possibilité d'utiliser rye pour le choix de la version de Python
curl -sSf https://rye.astral.sh/get | bash
rye config --set-bool behavior.global-python=true
rye fetch cpython@3.9.19
poetry env use /home/$USER/.rye/py/cpython@3.9.19/bin/python3
poetry install
poetry run pre-commit install
.env
à la racine du projet
Fichier Créer un fichier .env
avec les variables suivantes :
DJANGO_SETTINGS_MODULE=pount.settings.dev
DEFAULT_DB_NAME=pount
DEFAULT_DB_USER=pount
DEFAULT_DB_PASSWORD=pount
DEFAULT_DB_HOST=localhost
DEFAULT_DB_PORT=5432
SIGNING_KEY_PASSWORD=pount
AWS_ACCESS_KEY_ID=ACCESSKEYID
AWS_SECRET_ACCESS_KEY=***********************************
AWS_STORAGE_BUCKET_NAME=pount-dev-3if
RABBITMQ_SERVER='localhost:5672'
RABBITMQ_VHOST='pount'
RABBITMQ_USER='pount'
RABBITMQ_PASSWORD='pount'
MONGODB_USER=pount_dev
MONGODB_PASSWORD=pount_dev
MONGODB_HOST=localhost
MONGODB_DATABASE=pount_dev
Seules les credentials S3 doivent être remplacés. Les autres variables sont les valeurs par défaut en environnement de dev.
En environnement de dev, par habitude le nom du bucket S3 est pount-dev-<pn>
où pn
sont les initiales du dévéloppeur.
pount/settings/dev.py
Configuration dans CAS_SERVER_URL
: URL du serveur CAS
Configurer un serveur SMTP ou utiliser un outil tel que maildev
(docker run -p 1080:1080 -p 1025:1025 maildev/maildev
)
Création des clés JWT
ssh-keygen -t rsa -b 4096 -m PEM -f keys/jwt.key # (mettre "pount" comme mot de passe sinon ES plante)
openssl rsa -in keys/jwt.key -pubout -outform PEM -out keys/jwt.key.pub
Bases de données, cache, autres services
Les services dockérisés sont définis dans docker-compose.yml
Création des conteneurs sans les démarrer : docker-compose up --no-start
Démarrer les services : docker-compose up
Rabbitmq
Se connecter au serveur RabbitMQ (localhost:15672) avec le compte admin par défaut (guest:guest
).
Créer un compte pount
avec le mot de passe pount
. Créer un vhost pount
et donner les droits
à l'utilisateur pount
sur le vhost.
MongoDB
Créer une base de données pount_dev
avec l'utilisateur pount_dev
Se logguer sur le docker mongo : docker exec -it pount_mongo /bin/bash
mongosh "mongodb://localhost" -u pount -p pount
# créer une base pount_dev
use pount_dev
# créer l'utilisateur pount_dev
db.createUser({
user: "pount_dev",
pwd: "pount_dev",
roles: [
{ role: "readWrite", db: "pount_dev" }
]
})
# créer la collection referential_levels
db.createCollection("referential_levels")
# créer les index sur la collection
db.referential_levels.createIndex(
{ id: 1 },
{ name: 'id_1',
unique: true,
collation: {
locale: 'fr',
caseLevel: false,
caseFirst: 'off',
strength: 3,
numericOrdering: false,
alternate: 'non-ignorable',
maxVariable: 'punct',
normalization: false,
backwards: false,
}
}
)
db.referential_levels.createIndex(
{ referential_id: 1, order: 1 },
{ name: 'referential_id_1_order_1',
collation: {
locale: 'fr',
caseLevel: false,
caseFirst: 'off',
strength: 3,
numericOrdering: false,
alternate: 'non-ignorable',
maxVariable: 'punct',
normalization: false,
backwards: false,
}
}
)
# créer la collection referential_nodes
db.createCollection("referential_nodes")
# créer les index sur la collection
db.referential_nodes.createIndex(
{ id: 1 },
{ name: 'id_1',
unique: true,
collation: {
locale: 'fr',
caseLevel: false,
caseFirst: 'off',
strength: 3,
numericOrdering: false,
alternate: 'non-ignorable',
maxVariable: 'punct',
normalization: false,
backwards: false,
}
}
)
db.referential_nodes.createIndex(
{ referential_id: 1, level_id: 1, ancestors: 1, order: 1 },
{ name: 'referential_id_1_level_id_1_ancestors_1_order_1',
collation: {
locale: 'fr',
caseLevel: false,
caseFirst: 'off',
strength: 3,
numericOrdering: false,
alternate: 'non-ignorable',
maxVariable: 'punct',
normalization: false,
backwards: false,
}
}
)
Initialiser le projet
poetry run python manage.py migrate
Création des modèles nécessaires (roles, modèle de méta-données datacite) : poetry run python manage.py create_models
Les comptes utilisateurs sont créés à la première connexion. Par contre, pour pouvoir créer un projet
un utilisateur doit avoir explicitement ce droit. Il est donc nécessaire de créer un super-utilisateur (poetry run python manage.py createsuperuser
)
qui pourra attribuer ce droit aux utilisateurs dans l'admin Django.
Lors de la création des utilisateurs, les attributs suivants sont remontés du serveur CAS et utilisés
pour la création : username
, first_name
, last_name
, email
et affiliation
. Le serveur CAS est configuré pour remonter ces attributs lorsque le nom du service commence par pount-
.
Lancement du serveur
Serveur Django : poetry run python manage.py runserver
Worker Celery : poetry run celery -A pount worker -l INFO
Indexation des items dans Elasticsearch
Pour réinitialiser les index Elasticsearch : poetry run python manage.py searchindex rebuild-indices
NB : le serveur doit être lancé
Gestion des buckets sur S3
Pour faciliter la création et la configuration CORS des buckets sur S3, une commande Django est disponible :
python manage.py s3bucket create -b nom-du-bucket
De même pour supprimer : python manage.py s3bucket delete -b nom-du-bucket
Lister les buckets : python manage.py s3bucket list
Configurer les CORS d'un bucket : python manage.py s3bucket set_cors -b nom-du-bucket
Lister les fichiers d'un bucket : python manage.py s3bucket list -b nom-du-bucket
Upload de fichiers sur S3
L'ajout de fichiers se fait directement sur S3. Pour cela, le client demande une URL S3 pré-signée au backend (/api/items/{id}/post_url/
) et
télécharge le fichier via cette URL sans passer par Django. Il faut ensuite associer ce fichier à un item (POST
sur /api/items/{items_pk}/mediafiles/
.