cours-snt/test-python-ssh/python_app/main.py

95 lines
3.5 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Dynamic import
import importlib
# Get function args
import inspect
# check file properties
import os
# The directory where student work will be
# not a real path, do not use ./ or stuff like this
BASE_MODULE_PATH = 'python_app/modules'
if BASE_MODULE_PATH != '':
BASE_MODULE_PATH += '/'
def application(env, start_response):
""" Cette fonction est appellée à chaque requête HTTP et doit exécuter le bon code python. """
path = env['PATH_INFO'][1:] # removing first slash
# slash stuff
if path.endswith('/'):
path = path[:-1]
path_elements = tuple(d for d in path.split('/') if d != '')
path_minus_one = '/'.join(path_elements[:-1])
# Find which python module and function will be called
if os.path.isfile(BASE_MODULE_PATH + path_minus_one):
path = path_minus_one
function = path_elements[-1]
elif os.path.isfile(BASE_MODULE_PATH + path):
function = 'index'
elif os.path.isdir(BASE_MODULE_PATH + path):
path += '/main'
function = 'index'
else:
return htmlresp(404, 'Le dossier <em>{}</em> na pas été trouvé.'.format(path), start_response)
# Module full path
module_path = BASE_MODULE_PATH + path
module_path = module_path.replace('/', '.')
# Import the function
try:
m = importlib.import_module(module_path)
importlib.reload(m)
except ModuleNotFoundError:
#print('Le fichier {} na pas été trouvé. {}'.format(module_path, str(path_elements)))
return htmlresp(404, 'Le fichier <em>{}</em> na pas été trouvé.'.format(path), start_response)
# Find which parameters the function needs
try:
f = getattr(m,function)
# Call the function with the rigth attributes
except AttributeError:
return htmlresp(404, 'La fonction <em>{}</em> na pas été trouvée dans {}'.format(function, module_path), start_response)
# Pass url parameters to the function
try:
#print(inspect.getargspec(f))
#params = {p:(d if d is not None else '') for p,d in zip(inspect.getargspec(f).args, inspect.getargspec(f).defaults)}
expected_params = inspect.getargspec(f).args
params = {}
# TODO POST params?
for item in env['QUERY_STRING'].split('&'):
if item == '':
continue
k,v = tuple(item.split('='))
if k in expected_params:
params[k] = v
except Exception:
return htmlresp(400, 'La fonction <em>{}</em> demande les arguments suivants : {}. On a uniquement {}.'.format(function, params, ), start_response)
try:
response = f(**params)
if type(response) is tuple:
return htmlresp(response[0], str(response[1]), start_response, False)
else:
return htmlresp(200, str(response), start_response, False)
except Exception as e:
return htmlresp(400, 'Erreur à lexécution de la fonction <em>{}</em>.<pre style="color:#d90303;">{}</pre>'.format(function, e), start_response)
def htmlresp(code, message, start_response, squelette=True):
""" Cette fonction crée le squelette HTML minimal """
html = '<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body>{}</body></html>'
return resp(code, [('Content-Type','text/html')], html.format(message) if squelette else message, start_response)
def resp(code, headers, message, start_response):
""" Cette fonction permet de faire une réponse HTTP """
start_response(str(code), headers)
return bytes(message, 'utf8')