Skip to content

Commit 317b672

Browse files
committed
Misc changes
1 parent 2875760 commit 317b672

4 files changed

Lines changed: 66 additions & 13 deletions

File tree

singlestoredb/apps/_config.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,52 @@ def token(self) -> Optional[str]:
6464
return self.app_token
6565
else:
6666
return self.user_token
67+
68+
69+
@dataclass
70+
class PythonUdfAppConfig:
71+
listen_port: int
72+
base_url: str
73+
base_path: str
74+
running_interactively: bool
75+
is_gateway_enabled: bool
76+
77+
@staticmethod
78+
def _read_variable(name: str) -> str:
79+
value = os.environ.get(name)
80+
if value is None:
81+
raise RuntimeError(
82+
f'Missing {name} environment variable. '
83+
'Is the code running outside SingleStoreDB notebook environment?',
84+
)
85+
return value
86+
87+
@classmethod
88+
def from_env(cls) -> 'AppConfig':
89+
port = cls._read_variable('SINGLESTOREDB_APP_LISTEN_PORT')
90+
base_url = cls._read_variable('SINGLESTOREDB_APP_BASE_URL')
91+
base_path = cls._read_variable('SINGLESTOREDB_APP_BASE_PATH')
92+
93+
workload_type = os.environ.get('SINGLESTOREDB_WORKLOAD_TYPE')
94+
running_interactively = workload_type == 'InteractiveNotebook'
95+
96+
is_gateway_enabled = 'SINGLESTOREDB_NOVA_GATEWAY_ENDPOINT' in os.environ
97+
98+
if running_interactively:
99+
if is_gateway_enabled:
100+
base_url = cls._read_variable('SINGLESTOREDB_PYTHON_UDF_BASE_URL')
101+
base_path = cls._read_variable('SINGLESTOREDB_PYTHON_UDF_BASE_PATH')
102+
assert base_url is not None
103+
assert base_path is not None
104+
else:
105+
raise RuntimeError(
106+
'Running Python UDFs in interactive mode without nova-gateway enabled is not supported'
107+
)
108+
109+
return cls(
110+
listen_port=int(port),
111+
base_url=base_url,
112+
base_path=base_path,
113+
running_interactively=running_interactively,
114+
is_gateway_enabled=is_gateway_enabled,
115+
)
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from dataclasses import dataclass
2-
from typing import Optional
2+
from typing import Optional, Dict, Any
33

44

55
@dataclass
@@ -8,3 +8,8 @@ class ConnectionInfo:
88

99
# Only present in interactive mode
1010
token: Optional[str]
11+
12+
@dataclass
13+
class PythonUdfConnectionInfo:
14+
url: str
15+
functions: Dict[str, Any]

singlestoredb/apps/_python_udfs.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import asyncio
22
import textwrap
33
import typing
4+
import os
45

5-
from ._config import AppConfig
6-
from ._connection_info import ConnectionInfo
6+
from ._config import PythonUdfAppConfig
7+
from ._connection_info import ConnectionInfo, PythonUdfConnectionInfo
78
from ._process import kill_process_by_port
89
from ..functions.ext.asgi import Application
910

@@ -15,9 +16,8 @@
1516

1617

1718
async def run_udf_app(
18-
app: Application,
1919
log_level: str = 'error',
20-
kill_existing_app_server: bool = False,
20+
kill_existing_app_server: bool = True,
2121
) -> ConnectionInfo:
2222
global _running_server
2323
from ._uvicorn_util import AwaitableUvicornServer
@@ -27,7 +27,7 @@ async def run_udf_app(
2727
except ImportError:
2828
raise ImportError('package uvicorn is required to run python udfs')
2929

30-
app_config = AppConfig.from_env()
30+
app_config = PythonUdfAppConfig.from_env()
3131

3232
if kill_existing_app_server:
3333
# Shutdown the server gracefully if it was started by us.
@@ -40,10 +40,9 @@ async def run_udf_app(
4040
# Kill if any other process is occupying the port
4141
kill_process_by_port(app_config.listen_port)
4242

43+
app = Application()
4344
app.root_path = app_config.base_path
4445

45-
print("Listening on port", app_config.listen_port)
46-
4746
config = uvicorn.Config(
4847
app,
4948
host='0.0.0.0',
@@ -52,14 +51,14 @@ async def run_udf_app(
5251
)
5352
_running_server = AwaitableUvicornServer(config)
5453

54+
# In interactive mode this should be set to true
55+
replace = app_config.running_interactively
5556
app.register_functions(replace=True)
57+
5658
asyncio.create_task(_running_server.serve())
5759
await _running_server.wait_for_startup()
5860

59-
connection_info = ConnectionInfo(app_config.base_url, app_config.token)
61+
connection_info = PythonUdfConnectionInfo(app_config.base_url, app.get_function_info())
6062

61-
print(
62-
'Following Python UDFs are available: ', app.get_function_info()
63-
)
6463

6564
return connection_info

singlestoredb/functions/ext/asgi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ def __init__(
500500
]
501501
] = None,
502502
app_mode: str = get_option('external_function.app_mode'),
503-
url: str = get_option('external_function.url') + "invoke",
503+
url: str = get_option('external_function.url'),
504504
data_format: str = get_option('external_function.data_format'),
505505
data_version: str = get_option('external_function.data_version'),
506506
link_name: Optional[str] = get_option('external_function.link_name'),

0 commit comments

Comments
 (0)