Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief Creates and runs an Falcon application.
4"""
5import os
6import sys
7import logging
10def _get_app(name, options, secret, users):
11 """
12 Get application.
13 """
14 try:
15 from ..testing import dummy_application, dummy_application_image, dummy_application_fct
16 from ..testing import dummy_application_neighbors, dummy_application_neighbors_image
17 except (ImportError, ValueError):
18 folder = os.path.normpath(os.path.join(
19 os.path.abspath(os.path.dirname(__file__)), "..", ".."))
20 sys.path.append(folder)
21 from lightmlrestapi.testing import dummy_application, dummy_application_image, dummy_application_fct
22 from lightmlrestapi.testing import dummy_application_neighbors, dummy_application_neighbors_image
24 if name == "dummy":
25 # Dummy application.
26 if users:
27 raise NotImplementedError("users not None, not implemented")
28 app = dummy_application()
30 elif name == "dummyfct":
31 # Dummy application with a function.
32 name = options
33 if not os.path.exists(name):
34 raise FileNotFoundError("Unable to find '{0}'.".format(name))
35 path, loc = os.path.split(name)
36 if path not in sys.path:
37 sys.path.append(path)
38 rem = True
39 else:
40 rem = False
41 loc = os.path.splitext(loc)[0]
42 try:
43 mod = __import__(loc)
44 except ImportError as e:
45 if rem:
46 sys.path.pop()
47 with open(name, "r") as f:
48 code = f.read()
49 raise ImportError(
50 "Unable to compile file '{0}'\n{1}".format(name, code)) from e
51 if rem:
52 sys.path.pop()
54 if not hasattr(mod, 'restapi_version'):
55 with open(name, "r") as f:
56 code = f.read()
57 raise AttributeError(
58 "Unable to find function 'restapi_version' in file '{0}'\n{1}".format(name, code))
59 if not hasattr(mod, 'restapi_load'):
60 with open(name, "r") as f:
61 code = f.read()
62 raise AttributeError(
63 "Unable to find function 'restapi_load' in file '{0}'\n{1}".format(name, code))
64 if not hasattr(mod, 'restapi_predict'):
65 with open(name, "r") as f:
66 code = f.read()
67 raise AttributeError(
68 "Unable to find function 'restapi_predict' in file '{0}'\n{1}".format(name, code))
70 if secret == '':
71 secret = None
72 app = dummy_application_fct(mod.restapi_load, mod.restapi_predict, secret=secret,
73 version=mod.restapi_version, users=users)
75 elif name == "dummyimg":
76 # Dummy application with an image.
77 if users:
78 raise NotImplementedError("users not None, not implemented")
79 app = dummy_application_image(options=options, secret=secret)
81 elif name == "dummyknn":
82 # Dummy application with neighbors.
83 if users:
84 raise NotImplementedError("users not None, not implemented")
85 app = dummy_application_neighbors()
87 elif name == "dummyknnimg":
88 # Dummy application with neighbors and an image.
89 if users:
90 raise NotImplementedError("users not None, not implemented")
91 app = dummy_application_neighbors_image(options=options, secret=secret)
93 elif '.py' in name:
94 raise NotImplementedError(
95 "Unable to get application from filename '{}'. Not implemented.".format(name))
97 else:
98 raise NotImplementedError(
99 "Application '{}' is not implemented.".format(name))
100 return app
103def start_mlrestapi(name='dummy', host='127.0.0.1', port=8081, nostart=False, wsgi='waitress',
104 options='', secret='', ccall='single', users='', fLOG=print):
105 """
106 Creates an :epkg:`falcon` application and
107 runs it through a :epkg:`wsgi` server.
109 :param name: class name or filename which defines the application
110 :param host: host
111 :param port: port
112 :param nostart: do not start the wsgi server
113 :param wsgi: :epkg:`wsgi` framework which runs the falcon application
114 :param options: additional options as a string (depends on the application)
115 :param ccall: calling convention, 'single', 'multi' or 'both' depending on the
116 fact that the prediction function can predict for only one observation,
117 multiple ones or both
118 :param secret: secret used to encrypt the logging, default is empty which
119 disables the encryption
120 :param users: registred users, file with two columns login, encrypted password,
121 and no header
122 :param fLOG: logging function
124 Only :epkg:`waitress` is implemented right now.
125 Other alternative such as :epkg:`mod_wsgi` with :epkg:`Apache`.
126 :epkg:`uwsgi` are not implemented.
128 .. cmdref::
129 :title: Creates an falcon application and starts it through a wsgi application
130 :cmd: -m lightmlrestapi start_mlrestapi --help
131 :lid: cmd_start_mlrestapi_cmd
133 Creates an :epkg:`falcon` application and starts it through a :epkg:`wsgi` server.
134 """
135 app = _get_app(name, options=options, secret=secret, users=users)
136 if wsgi == 'waitress':
137 from waitress import serve
138 if not nostart:
139 fLOG("[start_mlrestapi] serve(app, host='{}', port='{}')".format(host, port))
140 logger = logging.getLogger('waitress')
141 logger.setLevel(logging.INFO)
142 serve(app, host=host, port=port)
143 else:
144 fLOG("[start_mlrestapi] do not run serve(app, host='{}', port='{}')".format(
145 host, port))
146 else:
147 raise NotImplementedError(
148 "Server '{}' is not implemented.".format(wsgi))
150 return app