Journal Python pour la rentrée 2019 - Hors Série - Python revient dans la course face à Node.js

Posté par (page perso) . Licence CC by-sa.
16
3
oct.
2019

Python revient dans la course face à JavaScript et TypeScript

Un article hors-série entre les dépêches #3 et #4.

Un barbu se tient derrière un écran d’ordinateur qui affiche « partie = 3.5, « ASGI Python3.5 » \n print(partie) » et à droite le logo de Python (deux serpents stylisés) entouré de petites icônes symbolisant la variété des domaines où s’applique Python. Attention, cette image peut ne pas s’afficher, car elle est au format WebP et ce format n’est pas toujours pris en charge. Si tel est le cas, merci de nous le signaler dans les commentaires et nous rectifierons le tir pour les prochaines dépêches.

Mon entreprise = JavaScript/TypeScript, Go et Python

Dans mon entreprise, nous avons des développeurs web qui apprécient TypeScript (Node.js et Angular), des AdminSys (Devops) qui codent en Python et Go, et enfin des scientifiques¹ qui codent en Java Python.

¹ Les scientifiques des données (data scientists), les scientifiques de l’apprentissage automatique (machine learning) et les analystes quantitatifs. Bien que le mot scientifique soit épicène, elles sont plusieures chez nous.

Mon équipe = Python

Dans mon équipe, nous avons opté pour Python et un tout petit peu de Go. Pour plus de détails, lire « Moi, expert C++, j’abandonne le C++ ». Dans une entreprise avec des scientifiques connaissant principalement Python, un des avantages à coder un projet en Python : permettre aux scientifiques de nous aider dans le développement, et permettre aussi aux scientifiques qui le souhaitent d’avoir davantage d’activités en tant que développeur.

API web

L’API web (HTTP) était codée avec le micro cadriciel (framework) Flask.
Lors d’une récente refonte (refactoring) de l’API, nous avons souhaité réduire notre dette technique et utiliser de meilleurs pratiques en optant pour des extensions à Flask comme Flask-API, Flask-Classful, Flask-RESTPlus (un fork de Flask-RESTful qui semble aller plus loin)…

Mais…

L’auteur originaire de Flask-API a quitté le navire :

Status: This project is in maintenance mode. The original author (Tom Christie) has shifted his focus to API Star. Passing PRs will still be considered for releases by the maintainer (Jace Browning).

Et en bas du README.md de API Star :

If you're looking for a high-performance Python-based async framework, then I would instead recommend Starlette.

Python 3.5 et ASGI

En bref, Tom Christie, comme d’autres auteur⋅e⋅s de frameworks web open source, sont passé⋅e⋅s du WSGI à ASGI… du côté obscure de la force !

Nouvelle génération du Python Web

En fait, depuis quelques années seulement, depuis Python 3.5 et son asyncio (Asynchronous I/O), les nouveaux cadriciels web (frameworks) fleurissent : Responder, Uvicorn, Starlette, FastAPI, BlackSheep, Japronto, Vibora.io, Bocadillo, Sanic, Quart… Ces deux derniers sont même (théoriquement) rétro-compatibles avec Flask.

Performance doublée

Et depuis 2019, ces nouveaux cadriciels Python en plein essor déchirent et reviennent à fond dans la course face à ceux du monde JavaScript / TypeScript !

Et hop, je prends volontairement un benchmark en faveur de Python face à JavaScript.
Attention, on peut tout faire dire aux résultats…
https://www.techempower.com/benchmarks/#section=data-r18&hw=ph&test=update&l=zijz7j-e&a=2

N’hésitez pas à regarder les autres onglets et les précédents rounds

Février 2018 (round 15)

Juin 2018 (round 16)

Octobre 2018 (round 17)

Juillet 2019 (round 18)

FastAPI

Finalement on a laissé tomber Flask et ses extensions, et nous avons opté pour FastAPI.
En plus de la vérification des JSON en entrée/sortie avec Pydantic, nous avons la génération automatique des API RESTful avec Swagger (OpenAPI) et reDoc.

Uniformiser les API Web

Mais nos collègues développeurs Web aimeraient bien en profiter pour centraliser et rationaliser les API et avoir partout la même technologie : TypeScript et Node.js 😳

Et toi, quel est ton avis ?

Qu’en penses-tu ?
Que valent ces bench ?
Que penser des nouveaux cadriciels Python ?
Quels sont tes conseils ?
Que ferais-tu à notre place ?

Licence : article publié sous licence CC0

PS : toute aide est la bienvenue sur les dépêches Python en cours de rédaction, sinon on va renommer la série en Python pour Noël 2019

  • # asgi rules !

    Posté par (page perso) . Évalué à 6 (+5/-0).

    Sans hésiter … Faut partir avec un framework asgi !
    Tom Christie est un (très) bon … et starlette un excellent choix (je l'utilise depuis 2ans).
    Mais faut targetter un python >=3.7. Starlette n'est toujours pas 3.5 compatible.
    Avec les micro tâches … tu peux faire tellement plus de choses, background task, socket, etc … sans sortir l'artillerie lourde (thread/multiprocess …)
    Et c'est tellement plus naturel, que tu gagnes énormément en lisibilité/maintenance.
    L'avenir est clairement ASGI …
    Quant au choix de starlette vs responder … starlette est l'original, responder est une surcouche. Les gars de starlette répondent très vite et bien.

  • # Performance

    Posté par . Évalué à 10 (+11/-1).

    Mais nos collègues développeurs Web aimeraient bien en profiter pour centraliser et rationaliser les API et avoir partout la même technologie : TypeScript et Node.js 😳

    OSEF ? Le troll des langages c'est bien pour essayer d'amuser la galerie sur linuxfr, mais sorti de là ça n'a plus vraiment de sens. Tu regarde s'il y a des contraintes technologiques fortes, puis tu établi les procédés que tu souhaite mettre en place (performance, tests, qualité de code, que sais-je encore) et te regarde comment les mettre en place avec les langages proposés. Bref il y a moyen d'avoir une méthodologie pour répondre à cette question qui renvoie les remarques classiques aux cours de récréations d'écoles primaires.

    Que valent ces bench ?

    J'en sais rien, mais des graph comme ça ne veulent rien dire (mais bon la dépêche elle-même comporte les même biais).

    « La performance » ça n'a pas de sens en soit. Ton besoin c'est quoi ? De fonctionner sur PI0 ? D'encaisser 10⁹⁹⁹⁹ requêtes/s ? De faire du temps réel dur ? Sans définir ton besoin de performance un bench n'est pas plus pertinent que de comparer les palettes de couleurs des sites des techno dont tu parle1.

    Si tu veux répondre extrêmement vite, il vaut probablement mieux partir sur du C/C++/rust.
    Si tu veux être en capacité d'encaisser énormément de requêtes, c'est une architecture reactive dont tu va avoir besoin (donc oui node, asgi, go, vertx, whatever).
    etc

    Après il faut aussi être humble, est-ce que ce que la charge que vous devez supporter est vraiment importante ? Aujourd'hui n'importe qui peut monter des infrastructures en recopiant ce que peuvent faire Instagram, Facebook, Google, Youtube,… pour gérer 20 requêtes/jour. C'est rigolo2, mais c'est typiquement de l'overengenering.

    Que penser des nouveaux cadriciels Python ?

    Qu'ils sont juste dans la veine actuelle. Tous les écosystèmes qui font du web sont entrain d'y passer. Ils ne sont ni les premiers ni particulièrement originaux.


    La façon dont tu pose la question me donne l'impression que la performance n'est pas une vraie contrainte pour vous (tout du moins sur cette partie là). Vous ne virer flask que parce qu'on vous a dit qu'il y a quelque chose de plus hype et pas parce qu'il vous contraint. Donc pourquoi essayer de faire un choix en fonction de la perf alors que ça n'est pas si important ?


    1. c'est évidement éxagéré 

    2. ça peut être un choix totalement assumé et c'est très bien. Mais alors le besoin ce n'est pas de faire de la performance, mais de s'amuser avec de la techno. 

    • [^] # Re: Performance

      Posté par (page perso) . Évalué à 6 (+5/-1).

      Salut JeanClaude,

      Tu as 100 % raison, la performance n’est pas notre priorité.
      Notre priorité c’est de coder vite et bien avec peu de ressources, et de faciliter la pérennité / maintenance du projet.

      Comme nous réécrivons l’API, c’est le moment de remettre en question le choix de Flask. D’où la découverte des nombreux nouveaux cadriciels web et l’envie d’écrire un journal pour partager.

      Merci de ton commentaire. 👍
      Ton commentaire nous rappelle que, nous, développeurs (surtout ceux, comme moi, qui viennent du C++), avons tendance à nous focaliser sur la performance au lieu de prendre de la hauteur et de lister les priorités du projet, les fonctionnalités attendues…

      Commentaire sous licence Creative Commons Zero CC0 1.0 Universal (Public Domain Dedication)

      • [^] # Re: Performance

        Posté par . Évalué à 2 (+1/-0).

        Comme nous réécrivons l’API, c’est le moment de remettre en question le choix de Flask. D’où la découverte des nombreux nouveaux cadriciels web et l’envie d’écrire un journal pour partager.

        Mon commentaire ne remet pas en cause le fais d'aller regarder autre chose. Pas mal de frameworks réactifs ont des fonctionnalités vraiment sympas et sont plutôt agréables à utiliser. On peut utiliser quelque chose de très performant pour des raisons autres que la performance ;)

        Merci de ton commentaire. 👍

        De rien :)

      • [^] # Re: Performance

        Posté par (page perso) . Évalué à 10 (+10/-0).

        Merci de ton commentaire. 👍
        Ton commentaire nous rappelle que, nous, développeurs (surtout ceux, comme moi, qui viennent du C++), avons tendance à nous focaliser sur la performance au lieu de prendre de la hauteur et de lister les priorités du projet, les fonctionnalités attendues…

        Je suis dev C++ depuis plus de 10 ans et ce n'est pas mon approche sur la performance. Ce que tu décris la ressemble surtout à de l'inexpérience en tant que software architecte.

        C++/Rust sont des langages unique en leur genre car il te donne la puissance d'utiliser ta machine jusqu'au dernier bit si tu en as besoin. Ça ne veut pas dire que tu dois le faire, et dans 99% des cas, tu ne dois pas le faire.

        En premier vient les features, en deuxième vient comment implémenter ces features en identifiant les besoins et les chemins critiques, et les évolutions de ses chemins critique ( scalabilité) en terme de performance.

        Dans une grande majorité des cas (en dehors du monde HPC), ce qui t'évite les problèmes de performances viennent de ton architecture ( persistence, latence appels réseau, back-pressure, bottle-neck caché, ), et non des micro optimisations de tes frameworks.

  • # Pourquoi pas?

    Posté par (page perso) . Évalué à 1 (+0/-2).

    nos collègues développeurs Web aimeraient bien en profiter pour centraliser et rationaliser les API et avoir partout la même technologie : TypeScript et Node.js 😳

    Python ou Node.js, c'est du pareil au self. Pourquoi garder les deux?

    Incubez l'excellence sur https://linuxfr.org/board/

    • [^] # Re: Pourquoi pas?

      Posté par (page perso) . Évalué à 2 (+0/-0).

      Oui, c'est justement le dilemme :

      • Utiliser Python sur tous les projets qui impliquent des scientifiques (connaissant Python) pour leur permettre de participer au développement logiciel ;

      • Utiliser Node.js (et TypeScript) pour toutes les API sur tous les projets, et tan pis si cela ralentit le développement et complexifie la maintenance des projets sur lesquels les scientifiques sont majoritaires.

      Commentaire sous licence Creative Commons Zero CC0 1.0 Universal (Public Domain Dedication)

      • [^] # Re: Pourquoi pas?

        Posté par (page perso) . Évalué à 6 (+5/-0).

        Énoncé comme ça, t'as ta réponse : Python.

        D'un coté tu as un avantage (les dev/scientifiques connaissent python). De l'autre t'as des inconvénients ([…] ralentit le développement et complexifie la maintenance des projets sur lesquels les scientifiques sont majoritaires.)

        Quel serait l'avantage de tout passer à Node.js/TypeScript ?

        Matthieu Gautier|irc:starmad

      • [^] # Re: Pourquoi pas?

        Posté par . Évalué à 3 (+1/-0).

        Jette un oeil à Nestjs.
        C'est le framework node/TS qui monte.

        Il s'inspire beaucoup d'Angular et offre l'avantage de partager du code entre front et back, avantage non négligeable

        • [^] # Re: Pourquoi pas?

          Posté par (page perso) . Évalué à 2 (+0/-0). Dernière modification le 04/10/19 à 10:32.

          En fait, pour complexifier l’équation et accentuer le dilemme, le département IT est situé au siège, dans une ville de province. Et pour recruter des scientifiques, l’entreprise a ouvert un site à Paris (je suis l’un des deux IT à Paris avec une dizaine de scientifiques). Les scientifiques apprécient Python pour leurs activités de Machine Learning, Data Prediction, Jupyter… donc pas possible de tout passer sur JavaScript/TypeScript…

          Actuellement, nos collègues Web nous parlent souvent de NestJS, et nous émerveillent avec toutes les possibilités qu’offrent les technos Node/JavaScript/TypeScript, notamment pour les API REST !

          Pour le moment, tous les développements des équipes parisiennes en Python. Et celles des équipes IT de province en TypeScript, JavaScript, Go et Python (et un résidu de Java en voie de disparition).

          Commentaire sous licence Creative Commons Zero CC0 1.0 Universal (Public Domain Dedication)

  • # WSGI : marshmallow + flask-smorest

    Posté par . Évalué à 7 (+5/-0). Dernière modification le 03/10/19 à 10:55.

    Je fais de l'info, et pas que, dans une boîte de 60 personnes, dont 4 ou 5 développeurs plus des ingénieurs qui peuvent coder en Python. On fait tout en Python. En gros.

    Comme on fait pas mal de webservice, on s'est penchés sur la question aussi.

    On a envisagé flask-restplus. On a même vu une présentation lors d'un meetup en présence du mainteneur, c'était intéressant. flask-restplus, c'est bien stable et tout, avec pas mal de fonctionnalités. Ce qui nous chiffonnait, c'était que la couche sérialisation / désérialisation était recrée dedans, plutôt que d'utiliser une bibliothèque existante. L'idée d'utiliser marshmallow a été abordée ici mais ça a jamais été fait dans flask-restplus, seulement dans des forks ou des patches.

    Nous on aime bien marshmallow, d'autant qu'on peut générer les schémas d'API depuis les modèles de base de donnée (MongoDB ou SQL), donc on trouvait ça dommage. Surtout que l'environnement marshmallow propose déjà webargs pour injecter les requêtes parsées dans les fonctions de vue, et apispec pour exposer la doc Swagger.

    Manquait une petite couche enrober tout ça. flask-apispec devait le faire mais c'était pas trop vivant et je comprenais pas le code, donc on a fait à notre sauce, puis on a extrait cette couche pour en faire une bibliothèque indépendant et quelques années plus tard, voilà flask-smorest : https://flask-smorest.readthedocs.io/.

    J'ai soumis une proposition de conf à la PyCon 2019 pour présenter tout ça.

    On a jamais touché à l'asynchrone parce qu'on a jamais eu ce besoin. Nos contraintes ne sont pas là. Si on devait le faire, je suppose qu'on essaierait de partir sur les bibliothèques qui sont "compatibles Flask" pour limiter les changements.

    • [^] # Re: WSGI : marshmallow + flask-smorest

      Posté par . Évalué à 3 (+1/-0).

      A une époque, on avait aussi envisagé Flacon parce que dédié webservice et plus rapide que Flask, mais on a privilégie le confort de développement (les écosystèmes Flask et marshmallow) à la performance dont on a pas besoin.

      • [^] # Re: WSGI : marshmallow + flask-smorest

        Posté par (page perso) . Évalué à 4 (+2/-0).

        Il vous manquait Ivresse et son excellente api.

        Python 3 - Apprendre à programmer en Python avec PyZo et Jupyter Notebook → https://www.dunod.com/sciences-techniques/python-3

        • [^] # Re: WSGI : marshmallow + flask-smorest

          Posté par (page perso) . Évalué à 4 (+2/-0).

          Pas mal la blague avec Ivresse 😅

          Le terme WSGI se prononce Whisky.

          Du coup, de nombreux cadriciels Python compatibles WSGI font un clin d'œil avec leurs noms :

          • Bottle
          • Flask
          • api_hour
          • Flacon Falcon

          Ivresse aurait pu être le nom idéal d'un cadriciel WSGI. 😂

          Commentaire sous licence Creative Commons Zero CC0 1.0 Universal (Public Domain Dedication)

  • # [aiohttp|flask|bottle|pyramid] + hapic + [marshmallow|serpyco]

    Posté par (page perso) . Évalué à 5 (+3/-0).

    Hello,

    A algoo, on travaille à mort en python (on fait du python en backend, du JS en front) et on a des contraintes variées selon les projets. Le problème récurrent : développer des API REST (mais pas que) et qu'elles soient vraiment auto-documentées.

    Du coup on a développé hapic qui interface un framework web classique + un (ou des) lib de sérialisation et validation (marshmallow, serpyco) et génère la doc au format OpenAPI et peut aussi la servir avec une ligne de code supplémentaire.

    Concrètement :

    • on utilise pyramid+hapic+marshmallow sur tracim - la documentation est auto-générée par introspection au démarrage du serveur,
    • on utilise aiohttp+hapic+serpyco sur un projet client (contexte embarqué, besoin de performance et d'optimisation de l'utilisation du CPU et des entrées-sorties)

    Serpyco, c'est un collègue à nous qui le développe c'est un serialiser très rapide qui est dévelopé en python et cython.

    Hapic est pas hyper bien documenté, mais ça fait vraiment bien le job, et en plus ça permet de séparer le code source lié aux API et le code purement métier (exemple : la gestion des cas d'erreurs peut se traiter sous forme de décorateur, donc le code métier implémente le cas nominal et n'est pas pollué par des if/elif/else pour gérer les cas d'erreur).

    Un petit exemple de code extrait du code source tracim :

    • handle_exception intercepte des exceptions et génère une erreur JSON avec le code HTTP demandé
    • input_path, input_body, output_body serialisent et valident les structures
    • with_api_doc active l'introspection et la génération de la documentation
    • le code que l'on écrit ne manipule que des objets/classes python, on ne mélange plus d'intelligence HTTP ou JSON dans le code.
        @hapic.with_api_doc(tags=[SWAGGER_TAG__CONTENT_HTML_DOCUMENT_ENDPOINTS])
        @hapic.handle_exception(EmptyLabelNotAllowed, HTTPStatus.BAD_REQUEST)
        @hapic.handle_exception(ContentFilenameAlreadyUsedInFolder, HTTPStatus.BAD_REQUEST)
        @check_right(is_contributor)
        @check_right(is_html_document_content)
        @hapic.input_path(WorkspaceAndContentIdPathSchema())
        @hapic.input_body(TextBasedContentModifySchema())
        @hapic.output_body(TextBasedContentSchema())
        def update_html_document(
            self, context, request: TracimRequest, hapic_data=None
        ) -> ContentInContext:
            """
            update_html_document
            """
            app_config = request.registry.settings["CFG"]  # type: CFG
            api = ContentApi(
                show_archived=True,
                show_deleted=True,
                current_user=request.current_user,
                session=request.dbsession,
                config=app_config,
            )
            content = api.get_one(hapic_data.path.content_id, content_type=content_type_list.Any_SLUG)
            with new_revision(session=request.dbsession, tm=transaction.manager, content=content):
                api.update_content(
                    item=content,
                    new_label=hapic_data.body.label,
                    new_content=hapic_data.body.raw_content,
                )
                api.save(content)
                api.execute_update_content_actions(content)
            return api.get_content_in_context(content)
    
  • # Migre en NodeJS

    Posté par (page perso) . Évalué à 2 (+1/-1). Dernière modification le 03/10/19 à 13:51.

    J'ai beaucoup utilisé Python et AsyncIO, j'ai même contribué dans cette stack, néanmoins, par expérience, j'ai dû malgré tout me mettre à NodeJS notamment avec GraphQL, car la caisse à outils en NodeJS est impressionnante et énorme à côté de celle en AsyncIO.

    Mais justement, avec une architecture micro-services avec un loadbalancer devang, tu peux facilement mixer les deux technologies et/ou migrer tranquillement de python vers NodeJS.

  • # Support du webp

    Posté par (page perso) . Évalué à 4 (+2/-0).

    Dans Firefox avec Debian Stretch, ça passe pas.
    Titre de l'image

    Adhérer à l'April, ça vous tente ?

    • [^] # Re: Support du webp

      Posté par (page perso) . Évalué à 0 (+0/-2).

      Merci pour ton feed-back.

      Faut peut-être attendre tou⋅te⋅s les utilisat⋅rice⋅eur⋅s de Debian/Strech (juin 2017 - juin 2022) migrent vers Debian/Buster (juillet 2019 - 2024) pour pouvoir mettre des images au format WebP sur LinuxFr.org…

      Quelle version de Firefox as-tu ?

      Commentaire sous licence Creative Commons Zero CC0 1.0 Universal (Public Domain Dedication)

    • [^] # Re: Support du webp

      Posté par . Évalué à 2 (+1/-0).

      Idem sous Ubuntu-mate 19.04 avec Firefox 60.8.0 ESR et JavaScript autorisé pour le domaine linuxfr.org.

    • [^] # Re: Support du webp

      Posté par . Évalué à 2 (+1/-0).

      Idem au boulot sous un windows 7 / firefox 60.6.3esr (64 bits), et windows server 2012 / firefox 60.9.0esr (32 bits)

    • [^] # Re: Support du webp

      Posté par (page perso) . Évalué à 2 (+0/-0). Dernière modification le 04/10/19 à 12:04.

      Merci pour vos commentaires. J'ai pu reproduire le problème sur ma Fedora 30 avec IceCat : c'est la version 60.9.0esr qui est installée.

      La page Wikipédia suivante indique que 3.6 % des pages visitées avec Firefox se font avec Firefox 60 et 60 ESR :

      https://en.wikipedia.org/wiki/Template:Firefox_usage_share#cite_note-1

      La dernière ESR (version 68) est sortie en juillet 2019, c'est qui est très récent. Mais bon, j'ai bon espoir que la plupart des Firefox 60 ESR seront migrés en Firefox 68 ESR, d'ici quelques années.

      Donc, j'attends encore 2020…2021 pour utiliser à nouveau des images au format WebP sur LinuxFr.org…

      En attendant, j'utilise le format PNG pour les images avec un fond transparent. Pour réduire la taille de l'image j'ai deux techniques complémentaires :

      • Compression avec perte de données en passant du RGBA (32 bits par pixel) vers des couleurs indexées (3 bits par pixel pour 7 couleurs + transparence) ;
      • Utiliser pngcrush pour optimiser la taille du fichier PNG.

      Commentaire sous licence Creative Commons Zero CC0 1.0 Universal (Public Domain Dedication)

      • [^] # Re: Support du webp

        Posté par . Évalué à 4 (+2/-0).

        La dernière ESR (version 68) est sortie en juillet 2019, c'est qui est très récent. Mais bon, j'ai bon espoir que la plupart des Firefox 60 ESR seront migrés en Firefox 68 ESR, d'ici quelques années.

        Les Firefox ESR 60 seront migrés en Firefox ESR 68 à partir du 23 octobre (avec la release de la 68.2.0) comme indiqué ici : https://support.mozilla.org/en-US/kb/firefox-esr-release-cycle

      • [^] # Re: Support du webp

        Posté par (page perso) . Évalué à 6 (+4/-0). Dernière modification le 05/10/19 à 23:03.

        Je partage dans ce commentaire mes trouvailles pour réduire davantage les images PNG. 🤩

        J’ai testé les outils pngcrush, pngnq, pngquant et Trimage. Ce dernier outil, Trimage, est une application graphique qui se base sur les outils pngcrush, optipng, et advpng.

        Installation

        sudo apt install pngcrush pngnq pngquant trimage

        Présentation à partir des Manpages

        • pngcrush is an optimizer for PNG (Portable Network Graphics) files. Its main purpose is to reduce the size of the file's IDAT chunk (or stream). pngcrush can also be used to modify a PNG's ancillary chunks (example : transparency information or textual comments). Some familiarity with the PNG (pronounced “ping”) format may be helpful to users of pngcrush. pngcrush has reasonable defaults so running with no options may produce smaller files.
        • pngnq quantizes a 32-bit RGBA PNG image to an 8 bit RGBA palette PNG using the neuquant algorithm. The output file name is the input file name extended with -nq8.png or a specified extension.
        • pngquant converts 32-bit RGBA PNGs to 8-bit (or smaller) RGBA-palette PNGs, optionally using Floyd-Steinberg dithering. The output filename is the same as the input name except that it ends in -fs8.png or -or8.png.
        • trimage is a front-end to compress png and jpeg images via optipng, advpng, pngcrush and jpegoptim.

        Recompression PNG

        cd chemin/avec/des/images
        for f in *.png ; do pngcrush --brute $f ${f}crush.png ; done
        for f in *.png ; do pngnq -s 1 $f ; done
        for f in *.png ; do pngquant --speed 1 --ext -pngquant.png $f ; done

        Je n’avais pas vu que Trimage pouvait être utilisé à la ligne de commande : je l’ai utilisé via l’interface graphique.

        Résultats pour une image RGBA

        Taille Opération
        186467 Image RGBA 32 bits de type logo enregistrée avec GIMP
        145386 Juste pngcrush
        138587 Juste Trimage
        52348 Juste pngquant
        52118 Juste pngnq
        50066 Double combinaison pngnq + pngquant
        47784 Double combinaison pngquant + Trimage
        46383 Double combinaison pngnq + Trimage
        45654 Triple combinaison pngnq + pngquant + Trimage

        Notons que Trimage intègre la compression fournie par pngcrush.

        En utilisant un seul outil, c’est pngnq qui s’en est sorti le mieux (avec mon image), suivi de près par pngquant, ces deux outils réalisant des opérations similaires.

        J’ai été surpris que la combinaison de tous ces outils puissent obtenir une encore meilleure compression ! D'ailleur l'auteur de pngnq donne l'exemple suivant :

        pngnq -n 256 image.png && pngcrush image-nq8.png smallimage.png

        Résultats pour une image avec des couleurs indexées

        Taille Opération
        55227 La même image avec 32 couleurs indexées (sans transparence), enregistrée en GIF avec GIMP
        31158 La même image avec 32 couleurs indexées (sans transparence), enregistrée en PNG avec GIMP
        30367 Juste pngquant
        26951 Juste Trimage
        26701 Combinaison pngquant et Trimage

        Dans ce second test, l’outil pngnq augmentait la taille. :-/

        Notons au passage, que le format GIF semble dépassé pour ce type d’image !

        Bilan

        Avec ces différentes astuces, nous passons d’une image PNG initiale de 182 Kio (RGBA) à 26 Kio, soit 14 % de l’original, sans aucune différence à mes yeux !

        Et le WebP sans pertes ?

        • Installation
          sudo apt install webp
        • Conversion PNG -> WebP
          for f in */*.png ; do cwebp -preset icon -lossless -z 9 -m 6 $f -o $f.webp ; done
        PNG WebP Image
        186467 76048 Image RGBA initiale (GIMP)
        52348 40918 Juste pngquant
        52118 38358 Juste pngnq
        31158 21340 Image 32 couleurs indexées (GIMP)
        31857 21338 Juste pngnq sur l’image 32 couleurs indexées

        Incroyable, l’outil cwebp compresse encore mieux quand le PNG a été optimisé. Et, bien que pngnq augmente la taille du PNG avec couleurs indexées, le WebP final est encore un tout petit peu meilleur !

        Dans tous les cas, l’écart s’amenuise entre un PNG très optimisé et un WebP sans pertes. Le WebP, parvient tout de même à compresser un tiers.

        Conclusion

        Pour mes prochaines dépêches sur LinuxFr.org, je vais combiner différents outils pour obtenir des fichiers PNG avec le meilleur ratio qualité/taille. Et puis, plus tard, quand quasiment tout le lectorat de LinuxFr.org pourra profiter des images au format WebP, je passerai au WebP, mais en recompressant préalablement mes fichiers avec pngnq.

        Commentaire sous licence Creative Commons Zero CC0 1.0 Universal (Public Domain Dedication)

  • # Et Django?

    Posté par . Évalué à 5 (+5/-0).

    Bonjour, question de béotien:
    Django est-il devenu has been? Si oui pour quelle raison?

    • [^] # Re: Et Django?

      Posté par . Évalué à 7 (+6/-0).

      Il n'a plus la hype, mais non il est encore très bien. Dango est une solution complète qui vient avec une opinion. Il t'expliquer comment accéder à ta base de données, comment faire de l'authentification, etc. Flask et les autres microframworks sont beaucoup plus petits, ils font donc bien moins de choses et on leur ajoute des plugins du coup.

      Si ton but est de recréer un site web complet "classique" ou si tu veux être guidé, django est vraiment très bien. Si tu veux juste faire une API et que tu veux faire les choses à ta façon (possiblement mal) les microframworks sont là pour toi.

      Tu retrouve la même dichotomie en ruby avec rail et synatra, en perl avec catalyst et dancer en java avec spring et vertx, en scala avec play et scalatra. Dédicace tout de même à python avec zope2 et java avec javaee d'avoir des trucs encore plus lourd.

    • [^] # Re: Et Django?

      Posté par . Évalué à 10 (+9/-0).

      Non c'est pas du tout mort.

      Je ne comprends pas trop pourquoi les gens partent sur tous ces microframeworks, vu que deux minutes plus tard tu as dix extentions / plugins / ou partie développer pour mettre authentification / sécu etc.

      Tu prends django + django-restframework (fait par Tom Christie) et hop tu as la même chose.

      Je pense surtout que beaucoup de personnes ne voient pas qu'on peut très facilement retirer des modules de django (enfin ne pas les charger). Un petit ajoute dans le settings, et tu retirent le moteur de template, les middlwares non voulus etc.

      Après encore, faut pas hésiter de sortir du cadre de l'orm etc. Je vois beaucoup trop de dev vouloir absolument faire fonctionner un truc non prévu par le framework en utilisant le framework.

      Django va sortir l'agsi pour sa prochaine version (mais pas encore l'orm en async) se qui va peut être le rendre un peu plus hype.

      Je crois aussi que beaucoup de personnes préfèrent avoir un "outil modulaire qui n'impose rien" pour faire croire ou se persuader qu'ils ont "choisi" une voie particulière pour un projet "particulier".

      On prend l'exemple de node et nestjs (pareil pour flask) :

      • Je peux choisir ce que je veux, de base c'est super light
      • Je suis libre de choisir exactement ce que je veux mettre.

      Au final un service rest ordinaire avec : une authentification / une gestion de permission / de filtre / des requetes sur des bases de donnée etc.

      La différence : 50 modules installés (issue de la communauté, maintenu ou pas par un mec dans son coin), une conf maison, des "choix maison" sur des problématiques tellement courants (comme la gestion de la session) et l'oubli de fonctionnalité de sécu. Mais ça fait plaisir aux devs / chefs de projet.

      J'entends aussi (concernant le choix nodejs) c'est le même langage que le front : c'est faux !!!

      Tu prend du nestjs et de l'angular : oui c'est en typescript (c'est les mêmes boucles for, la même façon de faire des class ok) mais ça s'arrete là.
      - Le backend c'est une api node pour l'accès disque, l'accès à la base de donnée, peut-être un orm (typeorm), de la sérialisation etc, via l'api de node.
      - Le frontend : Du HTML, du css, un moteur de template, une api pour manipuler le dom, la gestion des évents utilisateurs, les animations etc.

      Bref, un argument pour justifier de coller deux métiers complement différents (oui une personne peut avoir la double compétence, mais c'est bien une double) à un junior qui a être propulsé dev full stack.

      Petit scénario :
      - On a une supper idée : on va prendre un dev, mais on n'a pas de sous donc ça va être stage / alternance / junior (en fonction du budget)
      - Il faut une techno en back et en front rapide à apprendre : ok pour du js, on fait une pierre deux coups
      - en back faut pas un truc compliqué, le mec doit codé la solution en deux jours, donc on choisi un truc avec rien dedans, une doc qui se lit en une heure et puis si nécessaire on ajoutera des trucs petits à petit
      - en front on va prendre du react, c'est pareil de base il n'y a rien, il pourra démarrer le projet tout de suite.

      Attention, je ne dis pas que c'est des mauvais choix, je dis que c'est souvent à partir de mauvaises raisons que ces choix sont fait.

      • [^] # Re: Et Django?

        Posté par (page perso) . Évalué à 7 (+5/-1). Dernière modification le 04/10/19 à 11:15.

        Le vrai souci c'est de systématiquement faire du frontend une application, souvent single page.

        Un bête site web avec peu de js, c'est souvent plus simple, plus accessible et plus efficace pour 78% des cas (chiffre Dave Newton Institute Of Normal Webology).

        Incubez l'excellence sur https://linuxfr.org/board/

        • [^] # Re: Et Django?

          Posté par . Évalué à 0 (+1/-2).

          Le vrai souci c'est de systématiquement faire du frontend une application, souvent single page.

          1. Quel est le souci ?
          2. Quel est le rapport avec le commentaire au quel tu répond ?
      • [^] # Re: Et Django?

        Posté par . Évalué à 4 (+3/-0).

        J'entends aussi (concernant le choix nodejs) c'est le même langage que le front : c'est faux !!!

        En fait tu te concentre sur la technique, mais c'est pas le plus important là. Tu peux partager du code métier entre ton front et ton back et ça peut être très utile. Il peut facilement arriver qu'une logique implémenter coté client soit finalement plus utile dans le serveur et vice et versa.

        Ça n'est pas compliqué d'avoir de la logique métier qui ne soit pas adhérente à ton framework (ça a aussi pleins de bonnes propriétés en particulier pour les tests) et ça te donne beaucoup de flexibilités d'évolutions.

      • [^] # Re: Et Django?

        Posté par . Évalué à 2 (+1/-0).

        Tu as un lien pour l'ASGI pour Django ?
        Je ne trouve rien.

  • # Et toi, quel est ton avis ?

    Posté par . Évalué à -5 (+2/-9).

    Es-tu sur que tu veux le savoir ?

    Qu’en penses-tu ?

    J'aime pas les serpents.

    Que valent ces bench ?

    Pas grand chose. Qui les a faits, et avec quoi ?

    Que penser des nouveaux cadriciels Python ?

    La même chose que le serpent.

    Quels sont tes conseils ?

    Virer Python, parce que la maintenabilité à long terme c'est pas ça ? Remplacer par du go par exemple … Ou Erlang comme indiqué dans le lien ?

    Que ferais-tu à notre place ?

    Je chasserais les serpents.

    Ca te plaira peut-être pas, mais bon, tu as demandé mon avis, je le donne … ;)

    • [^] # Re: Et toi, quel est ton avis ?

      Posté par . Évalué à 10 (+11/-0).

      Il est marrant ton lien, il nous apprend que si on laisse un furieux coder de façon débridée sans lui faire faire des efforts pour que son code soit possible à maintenir, après on a du mal à le maintenir !
      J'ai presque le sentiment d'avoir appris quelque chose :)

      Ensuite, il m'apparaît comme relativement évident que si on doit réécrire un truc, mieux vaut partir sur des bases carrément différentes, pour bien tout repenser, et ne pas réutiliser - par facilité - de l'ancien code, dont on veut se débarrasser. Virer un projet Python pour le refaire en Python ce n'est peut-être pas aller assez loin pour repenser le projet sans biais. Et puis Erlang est aussi un très bon langage.

      J'ai une expérience différente d'un gros projet python, onze années de passif, un nombre inconnu de mains ayant brutalisé la base de 200 000 lignes de code, personne aujourd'hui n'a jamais rencontré les gens à l'origine du projet, voire n'a rencontré de gens ayant rencontré les gens à l'origine.
      La dette technique majeure c'est d'être toujours en Python 2.4.

      Ben figure-toi que de passer tout ça à Python3 (avec mise à jour de toutes les libs python externes, y compris pyuno, argh…) est nettement plus simple qu'il n'y parait.
      Parce que malgré des choix architecturaux douteux (peut-être pas il y a onze ans ?), le code est plutôt propre, et il y a des TU, des TNR sur l'ensemble de l'appli, et qu'il existe des outils d'analyse statique du code Python pour pointer du doigt ce qui va merder.

      Alors bon, le côté Python pas maintenable dans la durée, je le vois franchement biaisé par le problème de base : qui a codé le cœur du projet et a-t-il eu à un seul moment en tête l'idée que quelqu'un d'autre viendrait relire son code derrière lui.
      Et ça… c'est valable pour tous les langages…

      Tu vois, de mon côté, je ne comprend toujours pas qu'on puisse être masochiste au point d'aimer subir le Javascript aussi du côté du serveur, comme si du côté du brouteur c'était pas amplement suffisant !
      Chacun ses biais personnels :)

      Yth.

      • [^] # Re: Et toi, quel est ton avis ?

        Posté par . Évalué à 5 (+3/-0).

        Alors bon, le côté Python pas maintenable dans la durée, je le vois franchement biaisé par le problème de base : qui a codé le cœur du projet

        J'ai fais l'expérience en réécrivant à l'identique (quasi du copier-coller) en Go des applications et libs que j'avais écrites moi-même en Python. Pour moi il n'y a pas photo, la maintenance est clairement facilité en Go. En terme de maintenance je parle de la reprise du code mais aussi du déploiement, des dépendances à suivre, des éventuels soucis de perfs etc.

        Même sur des applis qui n'ont à priori aucun besoin de puissance ça peut jouer également. Par exemple un utilisateur qui s'amuse à sortir une édition pdf détaillée sur plusieurs années "juste pour voir" : 6000 pages… Avec reportlab c'est la sanction immédiate, en Go l'erreur est pardonnée.

        • [^] # Re: Et toi, quel est ton avis ?

          Posté par (page perso) . Évalué à 7 (+5/-0).

          Avec reportlab c'est la sanction immédiate, en Go l'erreur est pardonnée.

          En l'occurrence c'est plus un biais de confirmation ici.

          Bien sûr que Go est plus performant (code natif, typage statique, parallélisme…), mais dans ce cas :

          • soit c'est une limite de conception (le PDF est entièrement en RAM) et le code en Go explosera lui aussi, mais plus tard (au sens 'PDF avec plus de pages') ; "l'erreur est pardonnée" n'est vrai que parce que la limite, plus lointaine, te suffit (tant mieux).
          • soit c'est une différence de conception (ex: en Python le PDF est entièrement en RAM, en Go il est écrit au fur et à mesure dans un fichier/socket), et dans ce cas comparer les langages est injuste (rien n'empêche—dans l'absolu—de faire la même chose en Python).
      • [^] # Re: Et toi, quel est ton avis ?

        Posté par . Évalué à 2 (+0/-0).

        Tu vois, de mon côté, je ne comprend toujours pas qu'on puisse être masochiste au point d'aimer subir le Javascript aussi du côté du serveur, comme si du côté du brouteur c'était pas amplement suffisant !

        Le javascript a pas mal évolué depuis quelques années. Je me rappelle par exemple qu'à une époque, la notion d'objet était assez curieuse en Javascript. Et j'ai découvert il y a peu que ce n'est plus le cas : les objets sont gérés comme beaucoup d'autres langages.

    • [^] # Re: Et toi, quel est ton avis ?

      Posté par (page perso) . Évalué à 2 (+0/-0).

      Pour accéder à la présentation originale :

      https://olibre.github.io/slides/erlangparis/frompython2erlang

      PS : D’après la page de garde, les diapositives (slides) originales sont dans le fichier index.html (le fichier PDF est produit à partir du fichier index.html). J’ai bifurqué (forked) le dépôt Git, puis activé les GitHub-pages (les GitHub-pages ne semblent pas être actives pour le dépôt Git original).

      Commentaire sous licence Creative Commons Zero CC0 1.0 Universal (Public Domain Dedication)

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.