Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > fr.comp.lang.python > #3265

integrer un script python a une page web

Newsgroups fr.comp.lang.php, fr.comp.lang.python, fr.comp.infosystemes.www.serveurs, fr.comp.infosystemes.www.auteurs
From Lulu <lulu042@fry.fr.invalid>
Subject integrer un script python a une page web
Organization koitess?
Followup-To fr.comp.lang.python
Message-ID <slrnr3u7vq.ech.lulu042@Minty.Rock-n-Roll.org> (permalink)
Date 2020-02-08 21:54 +0100

Cross-posted to 4 groups.

Followups directed to: fr.comp.lang.python

Show all headers | View raw


[XP : fr.comp.lang.php,fr.comp.lang.python,fr.comp.infosystemes.www.serveurs,fr.comp.infosystemes.www.auteurs]
[fu2 : fr.comp.lang.python ]

Salut,

J'ai écrit un très beau script python qui permet de tracer le spectre
lumineux d'un ou plusieurs éléments chimiques. Il requiert une
interaction avec l'utilisateur pour sélectionner longueur d'onde
initiale et finale, largeur en pixels, continu, émission ou absorption,
et élément(s) chimique(s) à choisir dans une liste.

Bref, ça ro><e sa mère...

Mais j'aimerais bien permettre aux visiteurs de mon site web (sous
apache2) de produire l'image de ce script sans être contraint de
reprogrammer tout ça en php... (je saurais faire, mais ça me semble un
peu stupide et l'occasion d'interfacer un script python avec une page
web me semble une opportunité d'apprendre des choses intéressantes).
(sans compter que j'aurais le script python et le script php à
maintenir...)

Dans mes rêves, je créé une page web avec 4 zones de saisie, 3 boutons
radios, une dizaine de cases à cocher, un morceau de php pour récupérer
tout ça et appeler mon script en python qui fabrique l'image, image qui
serait affichée une seconde plus tard dans la page web.

Oui, mais comment interfacer un script python (exécuté côté serveur)
avec une page web permettant de saisir les paramètres et de récupérer
l'image tracée ?

Partage de code:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

# Auteur : <h.fertin@ac-rouen.fr>, Lycée Jules Siegfried, Le Havre
# Creative Commons : https://creativecommons.org/licenses/by-nc-sa/2.0/fr/
# Attribution :: Pas d'utilisation commerciale :: Partage dans les mêmes conditions

#################### MODE D'EMPLOI #####################################
# on obtient un spectre continu (saisir 1 quand c'est demandé),
# d'émission (saisir 2) ou d'absorption (saisir 3 ou rien).
#
# On peut saisir la longueur d'onde de départ et celle de fin, ce qui
# permet de "zoomer" pour séparer des raies.
#
# On peut choisir la largeur et la hauteur de l'image en pixels.
#
# On peut choisir d'afficher le spectre d'un ou plusieurs éléments.
#
# Le script permet d'enregistrer l'image calculée au format PNG.
#
# les constantes ci-dessous permettent de ne pas saisir à chaque fois
# les mêmes données : ce sont des valeurs par défaut aisées à modifier.
#
# Toute idée d'amélioration est bienvenue !!
#
# samedi 8 février 2020, 14:34:11 (UTC+0100)
# ajout d'un test pour n'ajouter à la liste_de_toutes_les_raies que les
# raies comprises entre WL_start et WL_end.
# Tri de cette liste dans l'ordre croissant.
# Ajout des accents au nom des éléments.

CONST_WL_START = 380
CONST_WL_END = 800
CONST_NB_PIXELS_LARGEUR = 1260
CONST_NB_PIXELS_HAUTEUR = 160
# Le fichier de fonte doit être présent dans le répertoire du script !
CONST_FONTE = 'courbd.ttf'
# CONST_IMPRIME_NOM_ELEMENT vaut soit True soit False
CONST_IMPRIME_NOM_ELEMENT = True


import sys
from datetime import datetime
from PIL import Image, ImageDraw, ImageFont


def color_of_ray( WL ):
    rouge = int( 0 )
    vert = int( 0 )
    bleu = int( 0 )
    if WL >=380 and WL < 420:
        diviseur = 60
        amplification = 0.3 + 0.7 * ( WL - 380) /40
        rouge = int( amplification * 255 * ( 440 - WL ) / diviseur )
        vert = int( 0 )
        bleu = int( amplification * 255 )

    elif WL >=420 and WL < 440:
        diviseur = 60
        rouge = int( 255 * ( 440 - WL ) / diviseur )
        vert = int( 0 )
        bleu = int( 255 )

    elif WL >= 440 and WL < 490:
        diviseur = 50
        rouge = int( 0 )
        vert = int( 255 * ( WL - 440 ) / diviseur )
        bleu = int( 255 )

    elif WL >= 490 and WL < 510:
        diviseur = 20
        rouge = int( 0 )
        vert = int( 255 )
        bleu = int( 255 * ( 510 - WL ) / diviseur )

    elif WL >= 510 and WL < 580:
        diviseur = 70
        rouge = int( 255 * ( WL - 510 ) / diviseur )
        vert = int( 255 )
        bleu = int( 0 )

    elif WL >= 580 and WL < 645:
        diviseur = 65
        rouge = int( 255 )
        vert = int( 255 * ( 645 - WL ) / diviseur )
        bleu = int( 0 )

    elif WL >= 645 and WL < 700:
        rouge = int( 255 )
        vert = int( 0 )
        bleu = int( 0 )

    elif WL >= 700 and WL < 800:
        amplification = 0.3 + 0.7 * ( 800 - WL) / 100
        rouge = int( amplification * 255 )
        vert = int( 0 )
        bleu = int( 0 )

    return (rouge, vert, bleu)


print('\n    ******************************')
print('    * Tracé de spectres lumineux *')
print('    ******************************\n')


# WL_start et WL_end sont les deux valeurs de longueur d'onde du spectre
# (demandées à l'utilisateur), exprimées en nanomètres (nm)
# test pour vérifier que l'utilisateur saisi bien un nombre entier
while True:
    x = input( "Longueur d'onde initiale (en nanomètre) ? " )
    if x == "":
        x = CONST_WL_START
    try:
        WL_start = int(x)
        break
    except ValueError:
        print( "    Saisir un nombre ENTIER !!!")
        pass

while True:
    x = input( "Longueur d'onde finale (en nanomètre) ? " )
    if x == "":
        x = CONST_WL_END
    try:
        WL_end = int(x)
        break
    except ValueError:
        print( "    Saisir un nombre ENTIER !!!" )
        pass

if WL_end < WL_start:
    swap = WL_start
    WL_start = WL_end
    WL_end = swap
    print( "   --> bourriquot !" )

# on se limite évidemment au spectre visible
if WL_start < 380:
    WL_start = 380
if WL_end > 800:
    WL_end = 800

print("   -->", WL_start, "nm à", WL_end, "nm")
WL_range = WL_end - WL_start
print("   --> range :", WL_range, "nm")

# nb_pixels_largeur est une valeur (entière !!) demandée à l'utilisateur,
# typiquement 400, 800 ou 1200 px
# les pixels seront numérotés de pixel(0) à pixel(nb_pixels_largeur - 1)
while True:
    x = input( "Largeur du spectre (en pixel) ? " )
    if x == "":
        x = CONST_NB_PIXELS_LARGEUR
    try:
        nb_pixels_largeur = int(x)
        break
    except ValueError:
        print( "    Saisir un nombre ENTIER !!!" )
        pass

while True:
    x = input( "Hauteur du spectre (en pixel) ? " )
    if x == "":
        x = CONST_NB_PIXELS_HAUTEUR
    try:
        nb_pixels_hauteur = int(x)
        break
    except ValueError:
        print( "    Saisir un nombre ENTIER !!!" )
        pass

s = nb_pixels_largeur * nb_pixels_hauteur
print("   --> taille de l'image :", nb_pixels_largeur, "px x", nb_pixels_hauteur ,"px =", s, "px²")

# WL_resolution est le nombre de nanomètre que représente un pixel
WL_resolution = ( WL_range ) / ( nb_pixels_largeur )
print("   --> Résolution : {0:.2e}".format(WL_resolution), "nm/pixel")

# une fois connue la largeur du spectre en pixels, création de deux listes
# contenant la valeur en nanomètres du début du pixel et de la fin du pixel
WL_list_start = []
WL_list_end = []
for i in range(nb_pixels_largeur):
    WL_list_start.append( WL_start + i * WL_resolution )
    WL_list_end.append( WL_start + ( i + 1 ) * WL_resolution )


print("")
while True:
    print( "1  --> spectre continu ;" )
    print( "2  --> spectre d'émission ;" )
    print( "3  --> spectre d'absorption." )
    choix = input( "Choix ? " )
    if choix == "":
        choix = "3"
    try:
        if choix == "1" or choix == "2" or choix == "3":
            break
    except ValueError:
        print('    Saisir un nombre ENTIER !!!')
        pass

if choix == "1":
    element = ""
    choix_spectre = "continu"
    couleur_graduation = ( 0, 0, 0 )
    print( "   --> Spectre continu\n" )
if choix == "2":
    choix_spectre = "emission"
    couleur_graduation = ( 255, 255, 255 )
    print( "   --> Spectre d'émission\n" )
if choix == "3":
    choix_spectre = "absorption"
    couleur_graduation = ( 0, 0, 0 )
    print( "   --> Spectre d'absorption\n" )


# raies trouvées sur
# https://media4.obspm.fr/public/ressources_lu/pages_tp-spectre-soleil/identification.html
liste_de_toutes_les_raies=[]
liste_elements=[]
if not choix == "1":
    print( "Éléments chimiques disponibles : H,He,Li,Na,Mg,Ar,Ca,Ti,Mn,Fe,Hg")
    print( "(il est possible de saisir plusieurs éléments en les séparant par des")
    print( "virgules, sans espace)")
    saisie_elements = input( "Symbole de l'élément chimique ? " )
    # le cas d'une liste qui comporterait un élément inconnu n'est pas traité car la seule
    # conséquence est que cet élément inconnu apparaîtra dans le nom du fichier : c'est
    # donc une "feature" qui permet d'ajouter un commentaire dans le nom du fichier.
    if ',' in saisie_elements:
        liste_elements = saisie_elements.split(",")
    else:
        liste_elements.append(saisie_elements)

    if saisie_elements == "":
        liste_elements = ["Ca"]

    nom_element = ""
    for ze_element in liste_elements:
        # Pas d'intensité de raies (pour l'instant)
        if ze_element == "H":
            nom_element = "Hydrogène "
            liste_raies = [ 388.9, 397, 410.2, 434.1, 486.1, 656.3 ]
            for raie in liste_raies:
                if raie >= WL_start - 1 and raie <= WL_end +1 :
                    liste_de_toutes_les_raies.append(raie)

        elif ze_element == "He":
            nom_element = nom_element + "Hélium "
            liste_raies = [ 447, 468.5, 471.5, 492, 501.5, 587.5, 668 ]
            for raie in liste_raies:
                if raie >= WL_start - 1 and raie <= WL_end +1 :
                    liste_de_toutes_les_raies.append(raie)

        elif ze_element == "Li":
            nom_element = nom_element + "Lithium "
            liste_raies = [ 496, 549, 610, 671 ]
            for raie in liste_raies:
                if raie >= WL_start - 1 and raie <= WL_end +1 :
                    liste_de_toutes_les_raies.append(raie)

        elif ze_element == "Na":
            nom_element = nom_element + "Sodium "
            liste_raies = [ 568.8, 589, 589.6, 615.4 ] 
            for raie in liste_raies:
                if raie >= WL_start - 1 and raie <= WL_end +1 :
                    liste_de_toutes_les_raies.append(raie)

        elif ze_element == "Mg":
            nom_element = nom_element + "Magnésium "
            liste_raies = [ 516.7, 517.3, 518.4 ]
            for raie in liste_raies:
                if raie >= WL_start - 1 and raie <= WL_end +1 :
                    liste_de_toutes_les_raies.append(raie)

        elif ze_element == "Ar":
            nom_element = nom_element + "Argon "
            liste_raies = [ 452, 472, 562, 605, 644, 670 ]
            for raie in liste_raies:
                if raie >= WL_start - 1 and raie <= WL_end +1 :
                    liste_de_toutes_les_raies.append(raie)

        elif ze_element == "Ca":
            nom_element = nom_element + "Calcium "
            liste_raies = [ 393.3, 396.9, 425, 433, 447, 588, 589, 614, 618, 646, 648, 674, 717, 735 ]
            for raie in liste_raies:
                if raie >= WL_start - 1 and raie <= WL_end +1 :
                    liste_de_toutes_les_raies.append(raie)

        elif ze_element == "Ti":
            nom_element = nom_element + "Titane "
            liste_raies = [ 466.8, 469.1, 498.2 ]
            for raie in liste_raies:
                if raie >= WL_start - 1 and raie <= WL_end +1 :
                    liste_de_toutes_les_raies.append(raie)

        elif ze_element == "Mn":
            nom_element = nom_element + "Manganèse "
            liste_raies = [ 402.1, 403.1, 403.6 ] 
            for raie in liste_raies:
                if raie >= WL_start - 1 and raie <= WL_end +1 :
                    liste_de_toutes_les_raies.append(raie)

        elif ze_element == "Fe":
            nom_element = nom_element + "Fer "
            liste_raies =  [ 389.9, 404.6, 423.4, 425.1, 426, 427.2, 438.3, 452.9, 459.3, 489.1, 491.9, 495.7, 501.2, 508, 527, 532.8, 536.7, 536.9, 543, 543.4, 544.7, 545.6, 561.6 ]
            for raie in liste_raies:
                if raie >= WL_start - 1 and raie <= WL_end +1 :
                    liste_de_toutes_les_raies.append(raie)

        elif ze_element == "Hg":
            nom_element = nom_element + "Hydrargyrum"
            liste_raies = [ 404.7, 435.8, 546.1, 577, 579.1]
            for raie in liste_raies:
                if raie >= WL_start - 1 and raie <= WL_end +1 :
                    liste_de_toutes_les_raies.append(raie)

    # tri de la liste de toutes les raies par ordre croissant
    x = liste_de_toutes_les_raies.sort()

else:
    # j'imprime le nom de l'élément sur le spectre, donc rien
    # s'il s'agit d'un spectre continu
    element = ""
    nom_element = ""


#creation en mémoire de l'image du spectre
try:
    spectre_image = Image.new( "RGB", ( nb_pixels_largeur, nb_pixels_hauteur) )
except:
    print('\n' * 2)
    print("    Erreur, impossible de créer une image de ", nb_pixels_largeur, "pixels de large et", nb_pixels_hauteur, "pixels de haut")
    print('\n' * 2)
    sys.exit(1)

now = datetime.now()
timestamp_debut = datetime.timestamp(now)

draw = ImageDraw.Draw(spectre_image)

if choix_spectre == "continu":
    for i in range(nb_pixels_largeur):
        WL_middle = ( WL_list_start[i] + WL_list_end[i] ) / 2
        draw.line(( i, 0, i, nb_pixels_hauteur ), fill = color_of_ray( WL_middle ))
else:
    print( "   --> Liste des raies pour ", liste_elements, ": ", end='')
    for i in liste_de_toutes_les_raies:
        print( i, "nm ; ", end = '')

    print('')
    print("   -->", len(liste_de_toutes_les_raies), "raies à tracer")


# La largeur d'une raie dépend de la valeur de WL_resolution de manière
# à séparer les raies mitoyennes quand on "zoome" en demandant une
# étendue faible en nanomètre mais élevée en pixels.
# Mais je voudrais qu'une raie soit large d'un nombre impair de pixels...
# Sur la TODO list !
if choix_spectre == "emission":
    for i in range(nb_pixels_largeur):
        WL_middle = ( WL_list_start[i] + WL_list_end[i] ) / 2
        for raie in liste_de_toutes_les_raies:
            # if abs( WL_middle - raie ) <= 0.5:
            if abs( WL_middle - raie ) <= ( 2 * WL_resolution ):
                draw.line(( i, 0, i, nb_pixels_hauteur ), fill = color_of_ray( WL_middle ))


if choix_spectre == "absorption":
    for i in range(nb_pixels_largeur):
        WL_middle = ( WL_list_start[i] + WL_list_end[i] ) / 2
        draw_the_ray = True
        for raie in liste_de_toutes_les_raies:
            # if abs( WL_middle - raie ) <= 0.5:
            if abs( WL_middle - raie ) <= ( 2 * WL_resolution ):
                draw_the_ray = False # on est à moins de 0,5 nm d'une raie : laisser noir

        if draw_the_ray:
            draw.line(( i, 0, i, nb_pixels_hauteur ), fill = color_of_ray( WL_middle ))


font = ImageFont.truetype(CONST_FONTE, 14)
draw = ImageDraw.Draw(spectre_image)
Comment = "from " + str( WL_start ) + " nm to " + str( WL_end ) + " nm" 

if choix_spectre == "emission":
    # fond noir
    draw.text((10.0, 10.0), Comment, couleur_graduation, font=font)
    if CONST_IMPRIME_NOM_ELEMENT:
        draw.text((10.0, 22.0), nom_element, couleur_graduation, font=font)
else:
    # fond coloré
    draw.text((9.0, 9.0), Comment, ( 255, 255, 255 ), font=font)
    draw.text((9.0, 10.0), Comment, ( 255, 255, 255 ), font=font)
    draw.text((9.0, 11.0), Comment, ( 255, 255, 255 ), font=font)
    draw.text((10.0, 9.0), Comment, ( 255, 255, 255 ), font=font)
    draw.text((10.0, 11.0), Comment, ( 255, 255, 255 ), font=font)
    draw.text((11.0, 9.0), Comment, ( 255, 255, 255 ), font=font)
    draw.text((11.0, 10.0), Comment, ( 255, 255, 255 ), font=font)
    draw.text((11.0, 11.0), Comment, ( 255, 255, 255 ), font=font)
    draw.text((10.0, 10.0), Comment, couleur_graduation, font=font)

    if CONST_IMPRIME_NOM_ELEMENT:
        draw.text((9.0, 21.0), nom_element, ( 255, 255, 255 ), font=font)
        draw.text((9.0, 22.0), nom_element, ( 255, 255, 255 ), font=font)
        draw.text((9.0, 22.0), nom_element, ( 255, 255, 255 ), font=font)
        draw.text((10.0, 21.0), nom_element, ( 255, 255, 255 ), font=font)
        draw.text((10.0, 23.0), nom_element, ( 255, 255, 255 ), font=font)
        draw.text((11.0, 21.0), nom_element, ( 255, 255, 255 ), font=font)
        draw.text((11.0, 22.0), nom_element, ( 255, 255, 255 ), font=font)
        draw.text((11.0, 23.0), nom_element, ( 255, 255, 255 ), font=font)
        draw.text((10.0, 22.0), nom_element, couleur_graduation, font=font)
    

# tracé des graduations
hauteur_dizaine = nb_pixels_hauteur // 16       # un trait court pour 10 nm 
hauteur_cinquantaine = nb_pixels_hauteur // 8   # un trait moyen pour 50 nm
hauteur_centaine = nb_pixels_hauteur // 4       # un trait long pour 100 nm
base = nb_pixels_hauteur                        # base du trait
# couleur_graduation a été déterminée au moment du choix de type de spectre

# largeur d'un trait de graduation en pixel :
#    impair
#    peu ou prou égal à un nanomètre donc (presque égal à 1 / WL_resolution)

WL_res_inverse = 1 / WL_resolution
if int( WL_res_inverse ) % 2 == 0:   # pair
    largeur_graduation = int( WL_res_inverse ) + 1
else:  # impair
    largeur_graduation = int( WL_res_inverse )

# graduation sur le premier pixel ? (donc i = 0)
if WL_start % 100 == 0:
    draw.line(( 0,base,0,base-hauteur_centaine),fill=couleur_graduation)
    draw.rectangle(((0, base),(((largeur_graduation-1)/2),base-hauteur_centaine+1)), fill=couleur_graduation )
elif WL_start % 50 == 0:
    draw.line((0,base,0,base-hauteur_cinquantaine),fill=couleur_graduation)
    draw.rectangle(((0,base),(((largeur_graduation-1)/2),base-hauteur_cinquantaine+1)),fill=couleur_graduation)
elif WL_start % 10 == 0:
    draw.line((0,base,0,base-hauteur_dizaine),fill=couleur_graduation )
    draw.rectangle(((0,base),(((largeur_graduation-1)/2),base-hauteur_dizaine+1)),fill=couleur_graduation)


for i in range(nb_pixels_largeur):
    # un trait vertical quand passer de WL_list_start[i] à WL_list_end[i] fait
    # changer de dizaine sur les nanomètres...
    if int( WL_list_start[i] // 100 ) != int( WL_list_end[i] // 100 ):
        # changement de centaine sur les nanomètres
        draw.line((i,base,i,base-hauteur_centaine),fill=couleur_graduation)
        draw.rectangle(((i-((largeur_graduation-1)/2),base),(i+((largeur_graduation-1)/2),base-hauteur_centaine+1)),fill=couleur_graduation)

    elif int( WL_list_start[i] // 50 ) != int( WL_list_end[i] // 50 ):
        # changement de cinquantaine sur les nanomètres
        draw.line((i,base,i,base-hauteur_cinquantaine),fill=couleur_graduation)
        draw.rectangle(((i-((largeur_graduation-1)/2),base),(i+((largeur_graduation-1)/2),base-hauteur_cinquantaine+1)),fill=couleur_graduation)

    elif int( WL_list_start[i] // 10 ) != int( WL_list_end[i] // 10 ):
        # changement de dizaine sur les nanomètres
        draw.line((i,base,i,base-hauteur_dizaine),fill=couleur_graduation)
        draw.rectangle(((i-((largeur_graduation-1)/2),base),(i+((largeur_graduation-1)/2),base-hauteur_dizaine+1)),fill=couleur_graduation)


now = datetime.now()
timestamp_fin = datetime.timestamp(now)
duree = timestamp_fin - timestamp_debut
print('\ndone in =',"{:0.3f}".format(duree),"seconde(s)")

spectre_image.show()

x = input( "Enregistrer l'image ? (Y/n) ")
if x == "":
   x = "Y"

if x[0] == "Y" or x[0] == "y" or x[0] == "O" or x[0] == "o":
    nom_image = "Spectre_" + choix_spectre + "_" + str(WL_start) + "_to_" + str(WL_end)

    if choix_spectre == "emission" or choix_spectre == "absorption": 
        for ze_element in liste_elements:
            nom_image = nom_image + "_" + ze_element

    year = now.year
    month = now.month
    if month < 10:
        month = "0" + str( month )
    day = now.day
    if day < 10:
        day = "0" + str( day )
    hour = now.hour
    if hour < 10:
        hour = "0" + str( hour )
    minute = now.minute
    if minute < 10:
        minute = "0" + str( minute )
    second = now.second
    if second < 10:
        second = "0" + str( second)
    nom_image = nom_image + "_" + str(year) + "-" + str(month) + "-" + str(day) 
    nom_image = nom_image + "_" + str(hour) + str(minute) + str(second) + str(".png")

    spectre_image.save( nom_image, "PNG" )
    print("Enregistré sous :", nom_image)

Back to fr.comp.lang.python | Previous | NextNext in thread | Find similar


Thread

integrer un script python a une page web Lulu <lulu042@fry.fr.invalid> - 2020-02-08 21:54 +0100
  Re: integrer un script python a une page web Eric Demeester <neuneu@potiron.invalid> - 2020-02-09 12:19 +0100
    Re: integrer un script python a une page web Lulu <lulu042@fry.fr.invalid> - 2020-02-09 22:32 +0100
    Re: integrer un script python a une page web Lulu <lulu042@fry.fr.invalid> - 2020-02-13 23:19 +0100
      Re: integrer un script python a une page web Eric Demeester <neuneu@potiron.invalid> - 2020-02-14 07:38 +0100
        Re: integrer un script python a une page web Nicolas <nicolasp@aaton.com> - 2020-02-14 08:23 +0100
          Re: integrer un script python a une page web Lulu <lulu042@fry.fr.invalid> - 2020-02-14 08:42 +0100
            Re: integrer un script python a une page web Nicolas <nicolasp@aaton.com> - 2020-02-14 11:02 +0100
              Re: integrer un script python a une page web Lulu <lulu042@fry.fr.invalid> - 2020-02-14 22:13 +0100
                Re: integrer un script python a une page web Lulu <lulu042@fry.fr.invalid> - 2020-02-14 22:24 +0100
                Re: integrer un script python a une page web Nicolas <nicolasp@aaton.com> - 2020-02-18 09:19 +0100
        Re: integrer un script python a une page web Lulu <lulu042@fry.fr.invalid> - 2020-02-14 08:42 +0100
  Re: integrer un script python a une page web Jo Engo <yl@icite.fr> - 2020-02-09 13:37 +0000
    Re: integrer un script python a une page web Lulu <lulu042@fry.fr.invalid> - 2020-02-14 21:50 +0100
  Re: integrer un script python a une page web Nicolas <nicolasp@aaton.com> - 2020-02-11 15:56 +0100
    Re: integrer un script python a une page web Lulu <lulu042@fry.fr.invalid> - 2020-02-13 23:27 +0100
      Re: integrer un script python a une page web Nicolas <nicolasp@aaton.com> - 2020-02-14 08:19 +0100

csiph-web