Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

integrer un script python a une page web

16 réponses
Avatar
Lulu
[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)

10 réponses

1 2
Avatar
Eric Demeester
Bonjour,
Lulu (Sat, 8 Feb 2020 21:54:18 +0100 - fr.comp.lang.python) :
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 ?

Je ne connais pas Python, ma réponse sera un peu générique.
Côté client (le navigateur), pas le choix, tu dois créer un formulaire
html pour que ton visiteur renseigne les différents paramètres
nécessaires à l'exécution de ton script.
Tu devras ensuite utiliser Ajax (pour faire simple du javascript capable
d'interagir avec le serveur web) et JSON (un format de données) afin
d'envoyer les paramètres saisis dans le formulaire à ton script python
côté serveur, lequel renverra l'image à afficher après avoir effectué
les traitements adéquats ; Ajax permettant ensuite d'afficher l'image
sur la page web à l'emplacement prévu.
À la lecture de ton script, tu ne pourras pas l'utiliser tel quel, car
il intègre des « input » alors que dans le cas d'une page web, les
paramètres seront envoyés au script via Ajax en JSON.
Quelques éléments si tu comprends l'anglais :
https://healeycodes.com/javascript/python/beginners/webdev/2019/04/11/talking-between-languages.html
https://stackoverflow.com/questions/464040/how-are-post-and-get-variables-handled-in-python/464977#464977
Une vidéo en français :
https://www.youtube.com/watch?v=5PZ03AO-bmA
Bon courage !
Avatar
Jo Engo
Le Sat, 08 Feb 2020 21:54:18 +0100, Lulu a écrit :
Creative Commons

Pourquoi choisir cc plutôt que la GPL pour un programme ?
--
Penser c'est dire non.
-+- Émile Chartier, dit Alain (1868-1951), Propos sur la religion
-+-
Avatar
Lulu
Le 09-02-2020, Eric Demeester a écrit :
Bonjour,
Lulu (Sat, 8 Feb 2020 21:54:18 +0100 - fr.comp.lang.python) :
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 ?

Je ne connais pas Python, ma réponse sera un peu générique.
Côté client (le navigateur), pas le choix, tu dois créer un formulaire
html pour que ton visiteur renseigne les différents paramètres
nécessaires à l'exécution de ton script.
Tu devras ensuite utiliser Ajax (pour faire simple du javascript capable
d'interagir avec le serveur web) et JSON (un format de données) afin
d'envoyer les paramètres saisis dans le formulaire à ton script python
côté serveur, lequel renverra l'image à afficher après avoir effectué
les traitements adéquats ; Ajax permettant ensuite d'afficher l'image
sur la page web à l'emplacement prévu.
À la lecture de ton script, tu ne pourras pas l'utiliser tel quel, car
il intègre des « input » alors que dans le cas d'une page web, les
paramètres seront envoyés au script via Ajax en JSON.
Quelques éléments si tu comprends l'anglais :
https://healeycodes.com/javascript/python/beginners/webdev/2019/04/11/talking-between-languages.html
https://stackoverflow.com/questions/464040/how-are-post-and-get-variables-handled-in-python/464977#464977
Une vidéo en français :
https://www.youtube.com/watch?v=5PZ03AO-bmA
Bon courage !

Merci pour ta réponse qui me donne des pistes à exploiter.
Effectivement, il faudra que je modifie mon script pour qu'il n'utilise
pas d'input() dans le cas où il est appelé avec des arguments.
Avatar
Nicolas
Bonjour,
Ensuite,
Le 08/02/2020 à 21:54, Lulu a écrit :
[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.

Il faut commencer à modifier ton très beau script en magnifique script :)
Pour cela, il faut créer une/des fonction(s) pour y mettre le calcul de
l'image.
Bref, ça ro><e sa mère...

Et là, ça ro><e sa grand-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 ?

Il te faut un serveur WEB dédié à la page en question. Quelque chose de
simple comme Bottle, Flask, CherryPi... fera très bien l'affaire. Le
rôle de ce serveur est de gérer la page concernée. C'est lui qui va
appeler ton script de création d'image. Il doit être configuré sur un
port autre que le 80 (déjà utilisé par ton serveur Apache).
Le serveur Apache doit être configuré pour récupérer le contenu du
serveur dédié lorsque la page en question est demandée. Une sorte de
redirection interne.
Cerise sur le gâteau : Coté navigateur, tu peux remplacer le code
javascript (exécuté dans le navigateur) par du code Python en utilisant
Brython. Du dev full Python ! C'est pas beau ça ?
Nicolas
Avatar
Lulu
Le 09-02-2020, Eric Demeester a écrit :
Lulu (Sat, 8 Feb 2020 21:54:18 +0100 - fr.comp.lang.python) :
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 ?

Je ne connais pas Python, ma réponse sera un peu générique.
Côté client (le navigateur), pas le choix, tu dois créer un
formulaire html pour que ton visiteur renseigne les différents
paramètres nécessaires à l'exécution de ton script.
Tu devras ensuite utiliser Ajax (pour faire simple du javascript
capable d'interagir avec le serveur web) et JSON (un format de
données) afin d'envoyer les paramètres saisis dans le formulaire à
ton script python côté serveur, lequel renverra l'image à afficher
après avoir effectué les traitements adéquats ; Ajax permettant
ensuite d'afficher l'image sur la page web à l'emplacement prévu.
À la lecture de ton script, tu ne pourras pas l'utiliser tel quel, car
il intègre des « input » alors que dans le cas d'une page web, les
paramètres seront envoyés au script via Ajax en JSON.
Quelques éléments si tu comprends l'anglais :
https://healeycodes.com/javascript/python/beginners/webdev/2019/04/11/talking-between-languages.html
https://stackoverflow.com/questions/464040/how-are-post-and-get-variables-handled-in-python/464977#464977
Une vidéo en français :
https://www.youtube.com/watch?v=5PZ03AO-bmA
Bon courage !

Bon...
Il a suffit que je rende mon script capable de lire ses arguments sur la
ligne de commande et aussi de le rendre silencieux pour une bête
histoire d'encodage de caractère et ça Rul3z da worldz : mon formulaire
PHP permet de sélectionner les arguments et un appel à system() avec la
bonne ligne de commande me calcule le spectre qui est ensuite affiché
sous mon formulaire.
Merci à toi.
Avatar
Lulu
Le 11-02-2020, Nicolas a écrit :
Le 08/02/2020 à 21:54, Lulu a écrit :
[XP : fr.comp.lang.php,fr.comp.lang.python,fr.comp.infosystemes.www.serveurs,fr.comp.infosystemes.www.auteurs]
[fu2 : fr.comp.lang.python ]
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.

Il faut commencer à modifier ton très beau script en magnifique script :)
Pour cela, il faut créer une/des fonction(s) pour y mettre le calcul de
l'image.

Que le calcul de l'image soit dans le corps du script ou dans une
fonction ne change rien...
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 ?

Il te faut un serveur WEB dédié à la page en question. Quelque chose de
simple comme Bottle, Flask, CherryPi... fera très bien l'affaire. Le
rôle de ce serveur est de gérer la page concernée. C'est lui qui va
appeler ton script de création d'image. Il doit être configuré sur un
port autre que le 80 (déjà utilisé par ton serveur Apache).

Mais après modification de mon script python pour qu'il lise des
arguments sur sa ligne de commande, ça marche très bien sur le port 80
avec un simple appel à system()
(il aura aussi fallu rendre le script python silencieux pour une obscure
question d'encodage de caractère sur sa sortie).
Le serveur Apache doit être configuré pour récupérer le contenu du
serveur dédié lorsque la page en question est demandée. Une sorte de
redirection interne.

J'avais bien évidemment déjà un serveur web en route : apache2
Cerise sur le gâteau : Coté navigateur, tu peux remplacer le code
javascript (exécuté dans le navigateur) par du code Python en utilisant
Brython. Du dev full Python ! C'est pas beau ça ?

Je n'ai pas de code javascript, je n'y connais rien.
Je jetterai un oeil à brython.
Avatar
Eric Demeester
Bonjour,
Lulu (Thu, 13 Feb 2020 23:19:57 +0100 - fr.comp.lang.python) :
Il a suffit que je rende mon script capable de lire ses arguments sur la
ligne de commande et aussi de le rendre silencieux pour une bête
histoire d'encodage de caractère et ça Rul3z da worldz :

[...]
Merci à toi.

Heureux d'avoir pu te donner des pistes, et heureux que ça fonctionne !
Il ne te reste plus qu'à mettre la page en question en ligne pour qu'on
puisse jouer avec :)
Avatar
Nicolas
Que le calcul de l'image soit dans le corps du script ou dans une
fonction ne change rien...

Si tu veux pouvoir utiliser ton algo avec un appel direct du script
et/ou à partir d'un autre script, ça change tout.
Mais après modification de mon script python pour qu'il lise des
arguments sur sa ligne de commande, ça marche très bien sur le port 80
avec un simple appel à system()

Et tu viens d'introduire un ENORME trou de sécurité dans ta machine.
Avatar
Nicolas
Il ne te reste plus qu'à mettre la page en question en ligne pour qu'on
puisse jouer avec :)

Avec le trou de sécurité qu'il vient d'introduire dans sa machine, il
vaudrait mieux pas.
Avatar
Lulu
Le 14-02-2020, Eric Demeester a écrit :
Lulu (Thu, 13 Feb 2020 23:19:57 +0100 - fr.comp.lang.python) :
Il a suffit que je rende mon script capable de lire ses arguments sur
la ligne de commande et aussi de le rendre silencieux pour une bête
histoire d'encodage de caractère et ça Rul3z da worldz :

[...]
Merci à toi.

Heureux d'avoir pu te donner des pistes, et heureux que ça fonctionne !
Il ne te reste plus qu'à mettre la page en question en ligne pour
qu'on puisse jouer avec :)

Suis chez free, et je viens de tester, pas possible de faire appel à
python. Dommage...
1 2