status: hidden
title: Python — Django isup
slug: inuik9Ah-django-isup
robots: noindex


Le nom du rendu est `isup`, le protocole de rendu est
[là](https://mdk.fr/pages/obiree2uaza2sh-rendu.html).

Le nom du projet Django est libre, l'app Django doit s'appeler `isup`.


## Survol

Votre projet sera composé de :

- Au moins deux modèles : `Domain` et `Check`.
  - Un `Domain` est lié à un `django.contrib.auth.User` (son propriétaire) via une `models.ForeignKey`.
  - Un `Domain` contient au minimum :
      - `name` ou `domain` (le nom de domaine),
      - `is_up` (booléen à True si le site est accessible),
      - `since` qui indique depuis quand le site est up ou down.
  - Un `Check` est lié à un domaine (un domaine peut avoir plusieurs checks).
  - Un `Check` contient au minimum :
      - La date de vérification,
      - un booléen `is_up`
      - un message d'explication comme « HTTPS certificate expired », « Timeout », « Up », ...
- Au moins une vue Django pour la page d'accueil.
- De quoi [créer un
  compte](https://docs.djangoproject.com/en/4.0/topics/auth/default/#django.contrib.auth.forms.UserCreationForm)
  (via Django, pas forcément via l'API), car seuls les utilisateurs
  loggés peuvent créer des domaines (qui leur appartiendront).
- `djangorestframework` pour gérer la sérialisation des modèles, les permissions, les vues d'API, les routes d'API.


## L'API

Je m'attends à pouvoir utiliser votre API de cette manière :

```text
GET /api/domains/  # Lister tous les domaines connus et leurs état (avec de la pagination si nécessaire).
POST /api/domains/ -d '{"domain": "mdk.fr"}'  # Pour ajouter un nom de domaine (qui appartient à celui qui fait le POST).
GET /api/domains/1/  # Afficher les informations du premier domaine.
PUT /api/domains/1/  # Modifier le domaine 1, seulement autorisé si j'en suis propriétaire.
DELETE /api/domains/1/  # Supprimer le domaine 1, seulement autorisé si j'en suis propriétaire.
GET /api/checks/  # Lister toutes les vérifications qui ont été effectuées.
GET /api/checks/?domain=1  # Lister toutes les vérifications effectuées pour le domaine 1.
GET /api/checks/1  # Afficher le check d'id 1.
```

Les checks sont en lecture seule, donc pas de `POST`, `PUT`, `DELETE` dessus.

Si vous voulez que votre API soit REST, la représentation d'un domaine **doit** contenir un lien vers ses `checks` :

```json
    {
        "domain": "mdk.fr",
        "is_up": true,
        "checks_url": "http://localhost:8000/uptime/checks/?domain=1",
        "url": "http://localhost:8000/uptime/domains/1/"
    }
```


## Vérification périodique des domaines connus.

Vous utiliserez une
[Management Command](https://docs.djangoproject.com/en/3.2/howto/custom-management-commands/)
pour mettre à jour votre table, c'est là que votre script implémenté en cours sera utile.

La commande peut s'appeler `check` par exemple. Sur un serveur de
prod, le serveur devra l'appeler périodiquement, par exemples toutes
les 5mn, via un
[timer](https://www.freedesktop.org/software/systemd/man/systemd.timer.html)
ou un [cron](https://manpages.debian.org/bullseye/cron/crontab.5.en.html).

En dev vous pouvez simplement lancer `python manage.py check` à la
main de temps en temps.

Cette commande doit lancer une nouvelle vérification de **tous** les
domaines connus, chaque résultat (up ou down) doit être documenté dans
le modèle `Checks`.


## La page d'accueil

La page d'accueil doit être la plus "Django-less" possible :

- Une simple route.
- Une simple vue d'une seule ligne avec `render`.
- Un template avec au besoin du HTML, du JS, du CSS mais **pas** de templating Django (pas de `{{`, pas de `{%`).

Vous êtes autorisés à stocker le JS et le CSS en
[statique](https://docs.djangoproject.com/en/4.0/howto/static-files/),
mais je n'ai rien contre tout mettre dans le même fichier vu que je
suis dev back #sinvergüenza.

Quand je dis « Django-less » je veux dire que le front doit pouvoir
fonctionner en dehors de Django, et que dans un vrai projet avec une
équipe *front* et une équipe *back* j'aimerai que cette home, ce JS,
et ce CSS puisse être géré dans un autre repo, sans qu'à aucun moment
les devs front n'aient besoin de savoir que c'est du Django côté back.

Vous pouvez donc utiliser le framework front à la mode cette semaine.

Pour récupérer la liste des noms de domaines et leur état, le front
devra donc utiliser l'API. Pas besoin d'être loggé pour ça, on ne
modifie rien, on ne fait que consulter, keep it simple stupid.
