93 lines
3.2 KiB
Python
93 lines
3.2 KiB
Python
# Dynamic import
|
||
import importlib
|
||
|
||
# Get function args
|
||
import inspect
|
||
|
||
# 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. """
|
||
# Find which python module and function will be called
|
||
# And remove empty elements
|
||
elements = tuple(e for e in env['PATH_INFO'].split('/') if e != '')
|
||
print(env)
|
||
|
||
#m = importlib.import_module('python_app.modules.main')
|
||
#f = getattr(m,'index')
|
||
#if env['REQUEST_URI'] == '/':
|
||
# return htmlresp(200, f(), start_response)
|
||
|
||
# Defaults
|
||
path = ''
|
||
module = 'main'
|
||
function = 'index'
|
||
|
||
# Get from url path
|
||
if len(elements) == 1:
|
||
module = elements[0]
|
||
elif len(elements) == 2:
|
||
module = elements[0]
|
||
function = elements[1]
|
||
elif len(elements) > 2:
|
||
path = '/'.join(elements[0:-2])
|
||
module = elements[-2]
|
||
function = elements[-1]
|
||
|
||
# slash stuff
|
||
if path != '':
|
||
path += '/'
|
||
|
||
# Module full path
|
||
module_path = BASE_MODULE_PATH + path + module
|
||
module_path = module_path.replace('/', '.')
|
||
|
||
# Import the function
|
||
try:
|
||
m = importlib.import_module(module_path)
|
||
except ModuleNotFoundError:
|
||
print('Le fichier {} n’a pas été trouvé. {}'.format(module_path, str(elements)))
|
||
return htmlresp(404, 'Le fichier <em>{}</em> n’a pas été trouvé.'.format(path + module), 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> n’a pas été trouvée.'.format(function), start_response)
|
||
|
||
# Pass url parameters to the function
|
||
try:
|
||
params = {p:'' for p in list(inspect.getargspec(f).args)}
|
||
for item in env['QUERY_STRING'].split('&'):
|
||
k,v = tuple(item.split('='))
|
||
if k in 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:
|
||
return htmlresp(400, 'Erreur à l’exécution de la fonction <em>{}</em>.'.format(function), 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')
|