diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..08063af --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +output/ +.venv/ +.envrc diff --git a/2021-en-attendant-la-pycon-fr-packaging.md b/2021-en-attendant-la-pycon-fr-packaging.md new file mode 100644 index 0000000..d0db593 --- /dev/null +++ b/2021-en-attendant-la-pycon-fr-packaging.md @@ -0,0 +1,273 @@ +# Faire ses paquets +En respectant les standards. + +::: notes + +Se présenter, hackinscience, formations, ... + + +## Donc on va parler de distutils ? + +PEP 632 (septembre 2020) : Deprecate distutils module. + +La doc dit de ne plus l'utiliser depuis ~2014… + +::: notes + +setuptools à commencé en étant du monkey-patch de distutils, +maintenant setuptools intègre sa copie de distutils. + + +## Donc on va parler de {buzzword} ? + +- pipenv : 304k lignes de code. +- bento : 37k lignes de code. +- poetry : 16k lignes de code. +- flit : 4k lignes de code. +- build : <1k lignes de code. + +::: notes + +Ils utilisent tous setuptools ^^ + + +## Non mais pourquoi pas {buzzword} ? + +- Ça demande du temps pour migrer d'un standard à un outil tiers. +- Ça demande à une partie de l'équipe d'apprendre ce nouvel outil. +- Puis ça demande du temps pour migrer à nouveau vers le standard quand l'outil est abandonné. + +::: notes + +On a mieux a faire de notre temps. + + +## Mais les Pipfile ? + +En fait oui et non, Pipfile c'est une spec à part : + +=> https://github.com/pypa/pipfile + +Rien n'empêche d'un jour pouvoir faire un : +``` +pip install --pipfile Pipfile.lock +``` + +::: notes + +Cherchez dans les issues de pypa/pip, la discussion est ouverte. + +Et puis pipenv c'est abandonné ? + + +# OK, bon, comment on fait sans buzzwords ? + +## pyproject.toml + +Les PEP 517 et 518 normalisent la construction de paquets en déclarant son outil de build dans `pyproject.toml` : + +```toml +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" +``` + +Le backend étant `setuptools.build_meta`, on aura besoin d'un `setup.cfg`. + +::: notes + +C'est typiquement utilisé par pip lors d'un `pip install .`. + +## setup.py + +En 2020 il ne prenait plus qu'une ou deux lignes, bienvenu en 2021. + +::: notes + +`setuptools` autorise depuis la v40.0.9 de ne pas avoir de `setup.py`, +à condition d'avoir un `pyproject.toml`. + +(La PEP517 ne gère pas encore les installations éditables, si vous les utilisez, +vous aurez donc tout de même besoin d'un `setup.py`.) + +https://setuptools.readthedocs.io/en/latest/setuptools.html#setup-cfg-only-projects + +Bon c'est quand même pratique les installations éditables, et `pip-compile setup.py`. + + +## setup.cfg + +``` +[metadata] +name = oeis +version = attr: oeis.__version__ +description = Implementation of a few integer sequences. +long_description = file: README.md +long_description_content_type = text/markdown; charset=UTF-8 +... +``` + +::: notes + +Voir mon setup.cfg sur le projet githup.com/JulienPalard/oeis. + + +## Vous venez de 2020 ? + +Ne faites pas la conversion à la main ! + +```text +pip install setup-py-upgrade +``` + + +## Comment je build ? + +On peut utiliser `build` de la PyPA, un outil qui ne fait qu'une chose mais qui le fait bien : + +``` +pip install build +python -m build --sdist --wheel . +``` + +::: notes + +Les dépendances de build sont installées dans un environnement isolé (*isolated build*). +Oui oui il crée vraiment un venv, avec le module venv de Python. + +Pas besoin de `pip install setuptools wheel` + + +## Et comment j'upload ? + +On peut utiliser `twine` de la PyPA, un outil qui ne fait qu'une chose mais qui le fait bien : + +```text +pip install twine +twine upload -r test dist/* +pip install --index-url https://test.pypi.org/simple/ oeis +twine upload dist/* +``` + + +# Et les dépendances !? + +Les dépendances « runtime » (`install_requires`) sont décrites dans le `setup.cfg`. + + +## Épinglées ou pas ? + +Ça dépend de ce que vous faites, mais généralement on vise le plus large possible. + +::: notes + +Vous voulez que votre lib, ou votre programme puisse s'installer sans conflit avec une autre lib ou un autre programme. + +Et on ne va pas maintenir, à la main, dans le setup.cfg, des versions précisément. + + +## Épingler saybien ! + +Je n'ai pas dit que c'était mal, c'est très bien pour les développeurs, pour la CI, pour la prod… + + +## Épingler saybien ! + +J'utilise un outil qui ne fait qu'une chose mais qui le fait bien : + +`pip-compile` du paquet `pip-tools`, ça ne fait *que* geler les dépendances, et ça le fait bien. + +::: notes + +Oui on sent que je n'aime pas les projets qui essayent de tout résoudre d'un coup. + + +## Épingler saybien ! + +On peut donc "geler" les dépendances du projet via un : + +``` +pip-compile setup.py +``` + +::: notes + +https://github.com/jazzband/pip-tools/issues/1047 + + +## Épingler saybien ! + +On peut ensuite documenter ses dépendances de dev dans un `requirements-dev.in` : + +```txt +-r requirements.txt +tox +``` + +## Épingler saybien ! + +Et épingler aussi les requirements de dev, afin de les utiliser dans des tests reproductibles : + +```txt +pip-compile requirements-dev.in +``` + + +## Épingler saybien ! + +On peut même hasher les dépendances pour les plus paranos : + +```txt +pip-compile --generate-hashes setup.py +``` + +## Qu'est-ce que ça donne ? + +``` +pyproject.toml // 3 lignes +setup.cfg +requirements.txt // autogénéré par pip-compile +requirements-dev.in +requirements-dev.txt // autogénéré par pip-compile +``` + +## Mettre à jour + +```txt +pip-compile --upgrade requirements-dev.in +``` + +# Installer + +Il existe un outil qui ne fait qu'une chose, mais qui le fait bien : `pip`. + +``` +pip install oeis +``` + + +## Installer + +Vous connaissez alors je passe sur le plus gros, mais n'oubliez pas : + +```txt +pip install git+https://github.com/org/project@branch +``` + +::: notes + +Typiquement pour tester la PR de quelqu'un (et oui ça déclenche la construction d'une wheel via les dépendances +et le point d'entrée décrit dans pyproject.toml). + + +# RTFM + +- https://setuptools.readthedocs.io/en/latest/build_meta.html +- https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html +- https://packaging.python.org/guides/using-testpypi/ +- https://setuptools.readthedocs.io/en/latest/setuptools.html#setup-cfg-only-projects + + +# Questions + +? \ No newline at end of file diff --git a/2022-campus-du-libre-hackinscience.md b/2022-campus-du-libre-hackinscience.md new file mode 100644 index 0000000..49e8732 --- /dev/null +++ b/2022-campus-du-libre-hackinscience.md @@ -0,0 +1,232 @@ +# HackInScience + + + +
+ +Julien Palard + +CPython core dev + + +# Demo time ! + +Parce que vous êtes là pour ça. + +::: notes + +Qui à dit « C'est moche ! » ? Je ne suis pas dev front ! + +Ne pas oublier la démo C et Rust ! + +Ceux pour qui la démo suffit, vous pouvez sortir ♥ + +## Enseigner le Python + +J'ai l'habitude. + +Mais à des groupes de ~6 pendant ~3 jours. + +## C'est green + +![Ruby Rhod](static/ruby-rhod.jpg) + +## Enseigner le Python + +Un jour on nous a proposé un groupe de 50 pendant 7 jours. + +::: notes + +En fait il sont arrivés à 80. + +## C'est pas green + +![Ruby Rhod étranglé](static/pas-green.jpg) + +## Mais on est devs + +Alors on a automatisé tout ce qui pouvait l'être. + +::: notes + +Pour passer du temps avec ceux qui en ont besoin. + + +# HackInScience.org + +C'est un petit Django, avec un peu de celery. + +::: notes + +Pour répartir les corrections sur des machines qui ne font que ça. + + +## 181 lignes de Python + +Ça devrait loger dans quelques slides ;) + +::: notes + +Aujourd'hui c'est 2700 lignes de code… + + +## Django models + +```python +class Exercise(models.Model): + title = models.CharField(max_length=255) + wording = models.TextField() + check = models.TextField() +``` + +## Django view + +```python +class ExerciseListView(LoginRequiredMixin, ListView): + model = Exercise + template_name = "hkis/exercises.html" + +class ExerciseView(LoginRequiredMixin, DetailView): + model = Exercise + template_name = "hkis/exercise.html" +``` + +::: notes + +Vous saviez que la MRO de Python garanti un héritage de gauche à droite ? + +Ici il est garanti que les méthodes surchargées par `LoginRequiredMixin` +sont exécutées avant celles de `ListView`. + + +## Une petite API + +```python +class ExerciseSerializer(HyperlinkedModelSerializer): + class Meta: + model = Exercise + fields = '__all__' + +class ExerciseViewSet(viewsets.ModelViewSet): + queryset = Exercise.objects.all() + serializer_class = ExerciseSerializer + +router = routers.DefaultRouter() +router.register('exercises', ExerciseViewSet) +``` + +::: notes + +Pourquoi un "Router" ? Parce que derrière cette ViewSet il y a plein +de vues ! + +Démo time ! + +## Une interface d'admin + +```python +from django.contrib import admin +from website.models import Answer, Exercise + +admin.site.register(Answer) +admin.site.register(Exercise) +``` + +::: notes + +Comme ça on a pu se concentrer sur les exercices et les moulinettes de correction. + +# C'est utilisé ? + +Je n'ai pas de « pisteur », mais j'ai une DB. + +En octobre 2022 : 730 personnes ont résolu 10_780 exercices + +La moulinette a corrigé près de 50k rendus. + +::: notes + +Google Analytics c'est illégal. Mais je sais écrire du SQL. + +Aucun tracker, aucune pub, aucun asset externe. + +10k c'est peu ou beaucoup, je ne sais pas. + +## Ça tient la charge ? + +Les exercices sont corrigés en environ 200ms. + +Deux serveurs se répartissent le travail. + +Les boucles infinies sont interrompues après 20s. + +::: notes + +Il est très facile d'ajouter un serveur de correction au besoin. + + +## C'est rentable ? + +Ren…quoi ? Pardon ? + +J'ai pas de « business model », et non mon projet ne va pas « mourir demain » pour autant #sry. + +::: notes + +Afficher la page des sponsors, remercier les sponsors et Gandi. + +En fait c'était rentable jusqu'à ce que j'achète des billets de train pour venir ici :D + + +# Côté sécu + +Les rendus sont exécutés côté serveur. + +C'est un challenge niveau sécurité. + +::: notes + +Python est réputé pour ne pas être sandboxable, du moins pas depuis l'intérieur de l'interpréteur. + + +## seccomp + +\+ Linux namespaces + +\+ rlimit + +::: notes + +Pourquoi pas Docker ? Pas besoin d'un filesystem complet, juste d'un processus. + +# Vu d'un enseignant + +::: notes + +Vous êtes libres de quitter la salle. + +## L'interface d'admin + +## Un repo git + +Juste pour les exos. + +# L'hébergement d'instances locales + +Possible, évidement, j'ignore s'il y en a. + +# Mot de la fin + +Si vous aimez Python, n'oubliez pas la PyConFr ! + +Du 16 au 19 février 2023 ! + +# Questions + +- Mastodon : [@mdk@mamot.fr](https://mamot.fr/@mdk) +- XMPP : mdk@chapril.org +- HTTP : https://mdk.fr +- SMTP : julien@python.org +- Whatsapp : HAHAHA jamais. +- Insta : Et puis quoi encore ? +- TikTok : SSTTTTOOOOOOOOP ! diff --git a/sphinx-lint.md b/2023-pycon-fr-sphinx-lint.md similarity index 100% rename from sphinx-lint.md rename to 2023-pycon-fr-sphinx-lint.md diff --git a/Makefile b/Makefile index fca6090..e6296db 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ output/%.html: %.md .PHONY: rsync rsync: static - rsync -vah --delete output/ mdk_fr@mdk.fr:/var/www/mdk.fr/$(DEST)/ + rsync -vah --delete output/ mdk_fr@mdk.fr:/var/www/mdk.fr/talks/ .PHONY: clean clean: diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ba94d4b --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +mdtoreveal diff --git a/static/pas-green.jpg b/static/pas-green.jpg new file mode 100644 index 0000000..b240ddb Binary files /dev/null and b/static/pas-green.jpg differ diff --git a/static/ruby-rhod.jpg b/static/ruby-rhod.jpg new file mode 100644 index 0000000..a52fc05 Binary files /dev/null and b/static/ruby-rhod.jpg differ