Ejemplo n.º 1
0
 def __init__(self, app_config: AppConfig, app_connection: str):
     self.app_key = app_config.app_key()
     self.app_conn_key = app_connection
     self.app_connection = app_config.app_connections[app_connection]
     settings_key = self.app_connection.settings or app_connection
     self.settings = Payload.from_obj(
         app_config.settings.get(settings_key, {}), AppsClientSettings)
     self.event_connections = {
         event_name: {
             conn.event: conn
             for conn in event_info.connections
             if conn.app_connection == app_connection
         }
         for event_name, event_info in app_config.events.items()
     }
     self.routes = {
         conn.event: self._get_route(conn.event)
         for event_info in app_config.events.values()
         for conn in event_info.connections
         if conn.app_connection == app_connection
     }
     self.conn_state: Optional[AppConnectionState] = None
     self.session: Optional[Any] = None
     self.token: Optional[str] = None
     self.token_expire: int = 0
Ejemplo n.º 2
0
def _update_api_paths(app_config: AppConfig, plugin: Optional[AppConfig] = None):
    """
    Populates paths section of spec based on __api__ specified in implemented events
    """
    assert spec is not None
    events = {
        k: v for k, v in app_config.events.items() if v.plug_mode == EventPlugMode.STANDALONE
    } if plugin is None else {
        k: v for k, v in plugin.events.items() if v.plug_mode == EventPlugMode.ON_APP
    }
    plugin_app = None if plugin is None else plugin.app
    paths = spec.get('paths', {})
    for event_name, event_info in events.items():
        route = app_route_name(app_config.app, event_name=event_name, plugin=plugin_app,
                               override_route_name=event_info.route)
        method = METHOD_MAPPING.get(event_info.type)
        if method is None:
            continue
        event_api_spec = _extract_event_api_spec(
            app_config if plugin is None else plugin, event_name, event_info
        )
        if event_api_spec is None:
            event_api_spec = paths.get(route, {}).get(method)
        if event_api_spec is None and _options.get('generate_mode'):
            event_api_spec = {"description": f"<<<{event_name}>>>", "parameters": [], "responses": {}}
        if event_api_spec is not None:
            event_api_spec['tags'] = [app_config.app_key()]
            _set_optional_fixed_headers(event_api_spec)
            _set_track_headers(event_api_spec, app_config)
            _set_path_security(event_api_spec, app_config, event_info)
            route_path = paths.get(route, {})
            route_path[method] = event_api_spec
            paths[route] = route_path
    spec['paths'] = paths
Ejemplo n.º 3
0
def _setup_client_context(app_config: AppConfig, server_app_config: AppConfig,
                          register_client_key: bool = True) -> EventContext:
    _init_engine_logger(app_config)
    assert app_config.server
    assert server_app_config.server
    app_config.server.auth = AuthConfig(
        secrets_location=f"/tmp/{uuid.uuid4()}",
        auth_passphrase='test_passphrase',
        enabled=True,
        create_keys=True
    )
    auth.init(app_config.app_key(), app_config.server.auth)
    if register_client_key:
        os.rename(
            pathlib.Path(app_config.server.auth.secrets_location) / 'public' / f'{app_config.app_key()}_pub.pem',
            pathlib.Path(server_app_config.server.auth.secrets_location) / 'public' / f'{app_config.app_key()}_pub.pem'
        )
    return EventContext(
        app_config=app_config,
        plugin_config=app_config,
        event_name='mock_event',
        settings=get_event_settings(app_config.effective_settings, 'mock_event'),  # type: ignore
        track_ids={},
        auth_info={}
    )
Ejemplo n.º 4
0
    def __init__(self,
                 *,
                 app_config: AppConfig,
                 plugins: List[AppConfig],
                 enabled_groups: List[str],
                 streams_enabled: bool = True):
        """
        Creates an instance of the AppEngine

        :param app_config: AppConfig, Hopeit application configuration as specified in config module
        :param plugins: List of AppConfig, Hopeit application configurations for enabled plugins
        :enabled_groups: List of str, list of enabled event groups
        :streams_enabled: bool, for testing, set to False to disable automatic starting streams
        """
        self.app_config = app_config
        self.app_key = app_config.app_key()
        self.effective_events = self._config_effective_events(
            app_config, enabled_groups)
        self.plugins = plugins
        self.settings = get_runtime_settings(app_config, plugins)
        self.event_handler: Optional[EventHandler] = None
        self.streams_enabled = streams_enabled
        self.stream_manager: Optional[StreamManager] = None
        self._running: Dict[str, asyncio.Lock] = {
            event_name: asyncio.Lock()
            for event_name, event_info in self.effective_events.items()
            if event_info.type in (EventType.STREAM, EventType.SERVICE)
        }
        logger.init_app(app_config, plugins)
Ejemplo n.º 5
0
async def register_app_connections(app_config: AppConfig):
    """
    Used by the engine to initialize and keep client connections
    """
    _registered_clients[app_config.app_key()] = {
        app_connection: await Client.create(app_config,
                                            app_connection).start()
        for app_connection in app_config.app_connections.keys()
    }
Ejemplo n.º 6
0
    async def start_app(self, app_config: AppConfig):
        """
        Starts and register a Hopeit App into this engine instance

        :param app_config: AppConfog, app configuration as specified in config module
        """
        logger.info(__name__, f"Starting app={app_config.app_key()}...")
        plugins = [
            self.app_engine(app_key=plugin.app_key()).app_config
            for plugin in app_config.plugins
        ]
        app_engine = await AppEngine(app_config=app_config,
                                     plugins=plugins).start()
        self.app_engines[app_config.app_key()] = app_engine
        return app_engine
Ejemplo n.º 7
0
def _set_path_security(event_api_spec: dict, app_config: AppConfig, event_info: EventDescriptor):
    """
    Setup security schemes allowed for each path
    """
    assert spec is not None
    security: list = []
    for auth in event_info.auth:
        if auth == AuthType.REFRESH:
            _update_auth_refresh_method(app_config.app_key())
            auth_str = f"{app_config.app_key()}.refresh"
            security.append({auth_str: []})
        elif auth != AuthType.UNSECURED:
            auth_str = f"auth.{auth.value.lower()}"
            security.append({auth_str: []})
    if len(security) == 0 and AuthType.UNSECURED not in event_info.auth:
        security = spec['security']
    if len(security) > 0:
        event_api_spec['security'] = security
Ejemplo n.º 8
0
async def stream_startup_hook(app_config: AppConfig, *args, **kwargs):
    """
    Start all stream event types configured in app.

    :param app_key: already started app_key
    """
    app_engine = runtime.server.app_engines[app_config.app_key()]
    for event_name, event_info in app_engine.effective_events.items():
        if event_info.type == EventType.STREAM:
            assert event_info.read_stream
            logger.info(
                __name__,
                f"STREAM start event_name={event_name} read_stream={event_info.read_stream.name}"
            )
            asyncio.create_task(app_engine.read_stream(event_name=event_name))
        elif event_info.type == EventType.SERVICE:
            logger.info(__name__, f"SERVICE start event_name={event_name}")
            asyncio.create_task(app_engine.service_loop(event_name=event_name))
Ejemplo n.º 9
0
def _setup_server_context(app_config: AppConfig) -> EventContext:
    _init_engine_logger(app_config)
    assert app_config.server
    app_config.server.auth = AuthConfig(
        secrets_location=f"/tmp/{uuid.uuid4()}",
        auth_passphrase='test_passphrase',
        enabled=True,
        create_keys=True
    )
    auth.init(app_config.app_key(), app_config.server.auth)
    return EventContext(
        app_config=app_config,
        plugin_config=app_config,
        event_name='mock_event',
        settings=get_event_settings(app_config.effective_settings, 'mock_event'),  # type: ignore
        track_ids={},
        auth_info={}
    )
Ejemplo n.º 10
0
 def __init__(self, *,
              app_config: AppConfig,
              plugin_config: AppConfig,
              event_name: str,
              track_ids: Dict[str, str],
              auth_info: Dict[str, Any]):
     self.app_key: str = app_config.app_key()
     self.app: AppDescriptor = app_config.app
     self.env: Env = {**plugin_config.env, **app_config.env}
     self.event_name = event_name
     base_event = event_name.split('$')[0]
     self.event_info: EventDescriptor = plugin_config.events[base_event]
     self.creation_ts: datetime = datetime.now().astimezone(tz=timezone.utc)
     self.auth_info = auth_info
     track_fields = [
         'track.operation_id',
         *app_config.engine.track_headers,
         *(self.event_info.config.logging.stream_fields
           if self.event_info.type == EventType.STREAM
           else [])
     ]
     self.track_ids = {k: track_ids.get(k) or '' for k in track_fields}