Source code for appyter.render.flask_app.development

from appyter.ext.asyncio.helpers import ensure_sync
import logging

logger = logging.getLogger(__name__)

[docs]async def run_app(config): import os import sys import asyncio return await asyncio.create_subprocess_exec( sys.executable, '-u', '-m', 'appyter', f"--socket={config['HOST']}:{config['PORT']}", stdout=sys.stdout, stderr=sys.stderr, env=os.environ, )
[docs]async def app_runner(emitter, config): import asyncio from appyter.ext.subprocess import interrupt state_lock = asyncio.Lock() state = dict(proc=await run_app(config)) # @emitter.on('reload') async def reload(changes): logger.info(f"Reload {changes}") async with state_lock: if 'proc' in state: proc = state.pop('proc') interrupt(proc) state['proc'] = await run_app(config) # @emitter.on('quit') async def quit(): logger.info('Stopping app..') async with state_lock: proc = state.pop('proc') interrupt(proc)
[docs]async def app_messager(emitter, config): import asyncio from appyter.ext.urllib import join_slash from appyter.ext.socketio import AsyncClient from appyter.ext.asyncio.try_n_times import async_try_n_times async with AsyncClient() as sio: # @emitter.on('livereload') async def livereload(changes): logger.info(f"LiveReload {changes}") await sio.emit('livereload', {}) # @emitter.on('quit') async def quit(): logger.info('Disconnecting..') await sio.disconnect() # origin = f"http://{config['HOST']}:{config['PORT']}" path = join_slash(config['PREFIX'], "socket.io") logger.info(f"Connecting to appyter server at {origin}{path}...") await asyncio.sleep(1) await async_try_n_times(3, sio.connect, origin, socketio_path=path) await sio.wait()
[docs]async def file_watcher(emitter, evt, path, **kwargs): from watchgod import awatch logger.info(f"Watching {path} for {evt}...") async for changes in awatch(path, **kwargs): await emitter.emit(evt, changes=changes)
[docs]@ensure_sync async def serve(app_path, **kwargs): import os import asyncio import appyter from appyter.ext.asyncio.event_emitter import EventEmitter from appyter.ext.watchgod.watcher import GlobWatcher from appyter.context import get_env config = get_env(**kwargs) emitter = EventEmitter() tasks = [] # run the app and reload it when necessary tasks.append(asyncio.create_task(app_runner(emitter, config))) # the underlying appyter library tasks.append(asyncio.create_task( file_watcher(emitter, 'reload', appyter.__path__[0], watcher_cls=GlobWatcher, watcher_kwargs=dict( include_dir_glob=['*'], include_file_glob=['*.py'], exclude_dir_glob=[], exclude_file_glob=[], ), ) )) # the underlying appyter library's templates/ipynb/staticfiles/... tasks.append(asyncio.create_task( file_watcher(emitter, 'livereload', appyter.__path__[0], watcher_cls=GlobWatcher, watcher_kwargs=dict( include_dir_glob=['*'], include_file_glob=['*'], exclude_dir_glob=[], exclude_file_glob=['*.py'], ), ) )) # the appyter itself's filters/blueprints tasks.append(asyncio.create_task( file_watcher(emitter, 'reload', config['CWD'], watcher_cls=GlobWatcher, watcher_kwargs=dict( include_dir_glob=['filters', 'blueprints'], include_file_glob=['*.py'], exclude_dir_glob=[], exclude_file_glob=[], ), ) )) # the appyter itself's templates/ipynb/staticfiles/... tasks.append(asyncio.create_task( file_watcher(emitter, 'livereload', config['CWD'], watcher_cls=GlobWatcher, watcher_kwargs=dict( include_dir_glob=['*'], include_file_glob=['*'], exclude_dir_glob=[config['DATA_DIR']], exclude_file_glob=['*.py'], ), ) )) tasks.append(asyncio.create_task(app_messager(emitter, config))) exit_code = 0 try: await asyncio.Event().wait() except asyncio.CancelledError: pass except: exit_code = 1 finally: await emitter.emit('quit') await emitter.flush() await emitter.clear() for task in tasks: try: task.cancel() await task except asyncio.CancelledError: pass return exit_code