Path: blob/main/singlestoredb/apps/_cloud_functions.py
469 views
import asyncio1import textwrap2import typing34from ._config import AppConfig5from ._connection_info import ConnectionInfo6from ._process import kill_process_by_port78if typing.TYPE_CHECKING:9from fastapi import FastAPI10from ._uvicorn_util import AwaitableUvicornServer1112# Keep track of currently running server13_running_server: 'typing.Optional[AwaitableUvicornServer]' = None141516async def run_function_app(17app: 'FastAPI',18log_level: str = 'error',19kill_existing_app_server: bool = True,20) -> ConnectionInfo:21global _running_server22from ._uvicorn_util import AwaitableUvicornServer2324try:25import uvicorn26except ImportError:27raise ImportError('package uvicorn is required to run cloud functions')28try:29import fastapi30except ImportError:31raise ImportError('package fastapi is required to run cloud functions')3233if not isinstance(app, fastapi.FastAPI):34raise TypeError('app is not an instance of FastAPI')3536app_config = AppConfig.from_env()3738if kill_existing_app_server:39# Shutdown the server gracefully if it was started by us.40# Since the uvicorn server doesn't start a new subprocess41# killing the process would result in kernel dying.42if _running_server is not None:43await _running_server.shutdown()44_running_server = None4546# Kill if any other process is occupying the port47kill_process_by_port(app_config.listen_port)4849# Add `GET /` route, used for liveness check50@app.get('/')51def ping() -> str:52return 'Success!'5354app.root_path = app_config.base_path5556config = uvicorn.Config(57app,58host='0.0.0.0',59port=app_config.listen_port,60log_level=log_level,61)62_running_server = AwaitableUvicornServer(config)6364asyncio.create_task(_running_server.serve())65await _running_server.wait_for_startup()6667connection_info = ConnectionInfo(app_config.base_url, app_config.token)6869if app_config.running_interactively:70if app_config.is_gateway_enabled:71print(72'Cloud function available at '73f'{app_config.base_url}docs?authToken={app_config.token}',74)75else:76curl_header = f'-H "Authorization: Bearer {app_config.token}"'77curl_example = f'curl "{app_config.base_url}" {curl_header}'78print(79textwrap.dedent(f"""80Cloud function available at {app_config.base_url}8182Auth Token: {app_config.token}8384Curl example: {curl_example}8586""").strip(),87)8889return connection_info909192