def create_app(stream_changes=True, allow_remote_class_registration=True, allow_import_from_main=False, max_queue_size=MAX_QUEUE_SIZE) -> QuartTrio: """Creates the quart app. """ # todo prevent server crashing from any user exceptions or from # connections closing etc. Same for multiprocessing global MAX_QUEUE_SIZE MAX_QUEUE_SIZE = max_queue_size app = QuartTrio(__name__) thread_executor = ThreadExecutor() stream_clients = defaultdict(dict) rest_executor = app.rest_executor = QuartRestServer( quart_app=app, executor=thread_executor, stream_clients=stream_clients) rest_executor.stream_changes = stream_changes rest_executor.allow_remote_class_registration = \ allow_remote_class_registration rest_executor.allow_import_from_main = allow_import_from_main # the objects are shared between the two executors socket_executor = app.socket_executor = QuartSocketServer( quart_app=app, registry=rest_executor.registry, executor=thread_executor, stream_clients=stream_clients) socket_executor.stream_changes = stream_changes socket_executor.allow_remote_class_registration = \ allow_remote_class_registration socket_executor.allow_import_from_main = allow_import_from_main app.add_url_rule('/api/v1/objects/import', view_func=rest_executor.remote_import, methods=['POST']) app.add_url_rule('/api/v1/objects/register_class', view_func=rest_executor.register_remote_class, methods=['POST']) app.add_url_rule('/api/v1/objects/create_open', view_func=rest_executor.ensure_instance, methods=['POST']) app.add_url_rule('/api/v1/objects/delete', view_func=rest_executor.delete_instance, methods=['POST']) app.add_url_rule('/api/v1/objects/execute', view_func=rest_executor.execute, methods=['POST']) app.add_url_rule('/api/v1/objects/execute_generator/stream', view_func=rest_executor.rest_execute_generator, methods=['POST']) app.add_url_rule('/api/v1/objects/list', view_func=rest_executor.get_objects, methods=['GET']) app.add_url_rule('/api/v1/objects/config', view_func=rest_executor.get_object_config, methods=['GET']) app.add_url_rule('/api/v1/objects/properties', view_func=rest_executor.get_object_data, methods=['GET']) app.add_url_rule('/api/v1/echo_clock', view_func=rest_executor.get_echo_clock, methods=['GET']) app.add_url_rule('/api/v1/sleep', view_func=rest_executor.sleep, methods=['GET']) app.add_url_rule('/api/v1/stream/data', view_func=rest_executor.sse_data, methods=['GET']) app.add_url_rule('/api/v1/stream/create', view_func=rest_executor.sse_channel_create, methods=['GET']) app.add_url_rule('/api/v1/stream/delete', view_func=rest_executor.sse_channel_delete, methods=['GET']) app.add_url_rule('/api/v1/stream/execute', view_func=rest_executor.sse_channel_execute, methods=['GET']) app.add_url_rule('/api/v1/stream/all', view_func=rest_executor.sse_channel_all, methods=['GET']) app.add_websocket('/api/v1/ws', view_func=socket_executor.ws) # app.register_error_handler(Exception, handle_unexpected_error) return app
async def run(self): # Serve static files from ./static static_folder = os.path.join(os.path.dirname(__file__), 'static') app = QuartTrio(__name__, static_folder=static_folder) app.add_url_rule('/', 'static', app.send_static_file, defaults={'filename': 'index.html'}) app.add_url_rule('/<path:filename>', 'static', app.send_static_file) app.add_url_rule('/tasks.json', 'task_tree', self.dispatch_task_tree, ['GET']) app.add_url_rule('/task/<int:task_id>/stacktrace.json', 'task_stacktrace', self.dispatch_task_stacktrace, ['GET']) app.add_url_rule('/nursery/<int:nursery_id>/cancel', 'nursery_cancel', self.dispatch_nursery_cancel, ['GET']) app.add_url_rule('/stats.json', 'stats', self.dispatch_stats, ['GET']) config = HyperConfig() #config.access_log_format = '%(h)s %(r)s %(s)s %(b)s %(D)s' #config.access_logger = create_serving_logger() # type: ignore config.bind = [f'{self._host}:{self._port}'] config.error_logger = config.access_logger # type: ignore #trio.hazmat.add_instrument(self) await serve(cors(app), config)