singlestoredb 1.6.3__cp38-abi3-win32.whl → 1.7.0__cp38-abi3-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of singlestoredb might be problematic. Click here for more details.

_singlestoredb_accel.pyd CHANGED
Binary file
singlestoredb/__init__.py CHANGED
@@ -13,7 +13,7 @@ Examples
13
13
 
14
14
  """
15
15
 
16
- __version__ = '1.6.3'
16
+ __version__ = '1.7.0'
17
17
 
18
18
  from typing import Any
19
19
 
@@ -0,0 +1,2 @@
1
+ from ._cloud_functions import run_function_app # noqa: F401
2
+ from ._dashboards import run_dashboard_app # noqa: F401
@@ -0,0 +1,70 @@
1
+ import asyncio
2
+ import typing
3
+ import urllib.parse
4
+
5
+ from ._config import AppConfig
6
+ from ._process import kill_process_by_port
7
+
8
+ if typing.TYPE_CHECKING:
9
+ from fastapi import FastAPI
10
+ from ._uvicorn_util import AwaitableUvicornServer
11
+
12
+ # Keep track of currently running server
13
+ _running_server: 'typing.Optional[AwaitableUvicornServer]' = None
14
+
15
+
16
+ async def run_function_app(
17
+ app: 'FastAPI',
18
+ log_level: str = 'error',
19
+ kill_existing_app_server: bool = True,
20
+ ) -> None:
21
+
22
+ global _running_server
23
+ from ._uvicorn_util import AwaitableUvicornServer
24
+
25
+ try:
26
+ import uvicorn
27
+ except ImportError:
28
+ raise ImportError('package uvicorn is required to run cloud functions')
29
+ try:
30
+ import fastapi
31
+ except ImportError:
32
+ raise ImportError('package fastapi is required to run cloud functions')
33
+
34
+ if not isinstance(app, fastapi.FastAPI):
35
+ raise TypeError('app is not an instance of FastAPI')
36
+
37
+ app_config = AppConfig.from_env()
38
+
39
+ if kill_existing_app_server:
40
+ # Shutdown the server gracefully if it was started by us.
41
+ # Since the uvicorn server doesn't start a new subprocess
42
+ # killing the process would result in kernel dying.
43
+ if _running_server is not None:
44
+ await _running_server.shutdown()
45
+ _running_server = None
46
+
47
+ # Kill if any other process is occupying the port
48
+ kill_process_by_port(app_config.listen_port)
49
+
50
+ # Add `GET /` route, used for liveness check
51
+ @app.get('/')
52
+ def ping() -> str:
53
+ return 'Success!'
54
+
55
+ base_path = urllib.parse.urlparse(app_config.url).path
56
+ app.root_path = base_path
57
+
58
+ config = uvicorn.Config(
59
+ app,
60
+ host='0.0.0.0',
61
+ port=app_config.listen_port,
62
+ log_level=log_level,
63
+ )
64
+ _running_server = AwaitableUvicornServer(config)
65
+
66
+ asyncio.create_task(_running_server.serve())
67
+ await _running_server.wait_for_startup()
68
+
69
+ if app_config.running_interactively:
70
+ print(f'Cloud function available at {app_config.url}')
@@ -0,0 +1,33 @@
1
+ import os
2
+ from dataclasses import dataclass
3
+
4
+
5
+ @dataclass
6
+ class AppConfig:
7
+ listen_port: int
8
+ url: str
9
+ running_interactively: bool
10
+
11
+ @classmethod
12
+ def from_env(cls) -> 'AppConfig':
13
+ port = os.environ.get('SINGLESTOREDB_APP_LISTEN_PORT')
14
+ if port is None:
15
+ raise RuntimeError(
16
+ 'Missing SINGLESTOREDB_APP_LISTEN_PORT environment variable. '
17
+ 'Is the code running outside SingleStoreDB notebook environment?',
18
+ )
19
+ url = os.environ.get('SINGLESTOREDB_APP_URL')
20
+ if url is None:
21
+ raise RuntimeError(
22
+ 'Missing SINGLESTOREDB_APP_URL environment variable. '
23
+ 'Is the code running outside SingleStoreDB notebook environment?',
24
+ )
25
+
26
+ workload_type = os.environ.get('SINGLESTOREDB_WORKLOAD_TYPE')
27
+ running_interactively = workload_type == 'InteractiveNotebook'
28
+
29
+ return cls(
30
+ listen_port=int(port),
31
+ url=url,
32
+ running_interactively=running_interactively,
33
+ )
@@ -0,0 +1,51 @@
1
+ import typing
2
+ import urllib.parse
3
+
4
+ from ._config import AppConfig
5
+ from ._process import kill_process_by_port
6
+
7
+ if typing.TYPE_CHECKING:
8
+ from plotly.graph_objs import Figure
9
+
10
+
11
+ def run_dashboard_app(
12
+ figure: 'Figure',
13
+ debug: bool = False,
14
+ kill_existing_app_server: bool = True,
15
+ ) -> None:
16
+ try:
17
+ import dash
18
+ except ImportError:
19
+ raise ImportError('package dash is required to run dashboards')
20
+
21
+ try:
22
+ from plotly.graph_objs import Figure
23
+ except ImportError:
24
+ raise ImportError('package dash is required to run dashboards')
25
+
26
+ if not isinstance(figure, Figure):
27
+ raise TypeError('figure is not an instance of plotly Figure')
28
+
29
+ app_config = AppConfig.from_env()
30
+
31
+ if kill_existing_app_server:
32
+ kill_process_by_port(app_config.listen_port)
33
+
34
+ base_path = urllib.parse.urlparse(app_config.url).path
35
+
36
+ app = dash.Dash(requests_pathname_prefix=base_path)
37
+ app.layout = dash.html.Div(
38
+ [
39
+ dash.dcc.Graph(figure=figure),
40
+ ],
41
+ )
42
+
43
+ app.run(
44
+ host='0.0.0.0',
45
+ debug=debug,
46
+ port=str(app_config.listen_port),
47
+ jupyter_mode='external',
48
+ )
49
+
50
+ if app_config.running_interactively:
51
+ print(f'Dash app available at {app_config.url}')
@@ -0,0 +1,32 @@
1
+ import os
2
+ import signal
3
+ import typing
4
+ if typing.TYPE_CHECKING:
5
+ from psutil import Process
6
+
7
+
8
+ def kill_process_by_port(port: int) -> None:
9
+ existing_process = _find_process_by_port(port)
10
+ kernel_pid = os.getpid()
11
+ # Make sure we are not killing current kernel
12
+ if existing_process is not None and kernel_pid != existing_process.pid:
13
+ print(f'Killing process {existing_process.pid} which is using port {port}')
14
+ os.kill(existing_process.pid, signal.SIGKILL)
15
+
16
+
17
+ def _find_process_by_port(port: int) -> 'Process | None':
18
+ try:
19
+ import psutil
20
+ except ImportError:
21
+ raise ImportError('package psutil is required')
22
+
23
+ for proc in psutil.process_iter(['pid']):
24
+ try:
25
+ connections = proc.connections()
26
+ for conn in connections:
27
+ if conn.laddr.port == port:
28
+ return proc
29
+ except psutil.AccessDenied:
30
+ pass
31
+
32
+ return None
@@ -0,0 +1,32 @@
1
+ import asyncio
2
+ import socket
3
+ from typing import List
4
+ from typing import Optional
5
+ try:
6
+ import uvicorn
7
+ except ImportError:
8
+ raise ImportError('package uvicorn is required')
9
+
10
+
11
+ class AwaitableUvicornServer(uvicorn.Server):
12
+ """
13
+ Adds `wait_for_startup` method.
14
+ The function (asynchronously) blocks until the server
15
+ starts listening or throws an error.
16
+ """
17
+
18
+ def __init__(self, config: 'uvicorn.Config') -> None:
19
+ super().__init__(config)
20
+ self._startup_future = asyncio.get_event_loop().create_future()
21
+
22
+ async def startup(self, sockets: Optional[List[socket.socket]] = None) -> None:
23
+ try:
24
+ result = await super().startup(sockets)
25
+ self._startup_future.set_result(True)
26
+ return result
27
+ except Exception as error:
28
+ self._startup_future.set_exception(error)
29
+ raise error
30
+
31
+ async def wait_for_startup(self) -> None:
32
+ await self._startup_future
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: singlestoredb
3
- Version: 1.6.3
3
+ Version: 1.7.0
4
4
  Summary: Interface to the SingleStoreDB database and workspace management APIs
5
5
  Home-page: https://github.com/singlestore-labs/singlestoredb-python
6
6
  Author: SingleStore
@@ -1,5 +1,5 @@
1
- _singlestoredb_accel.pyd,sha256=l1XvUL0_WR4DaSMvC6OgddP4vAsZPnV70dBcs1dYJjs,59904
2
- singlestoredb/__init__.py,sha256=SpL4-XLoAIa7QepM8vcdktkpliC5inG2FiqFYdZ181o,1697
1
+ _singlestoredb_accel.pyd,sha256=RynkDNV_UXfCdGo5PfvktuRnMaaGyfgMd5y4O_kj97U,59904
2
+ singlestoredb/__init__.py,sha256=QfF5_hgd3Qij5ssWBZesWxdych7o-gKPfWx4G1uR-XM,1697
3
3
  singlestoredb/auth.py,sha256=RmYiH0Wlc2RXc4pTlRMysxtBI445ggCIwojWKC_eDLE,7844
4
4
  singlestoredb/config.py,sha256=LlrwKor_23uA9u7jWBYb-IaOKs30CjWIM7o9xCXEPcc,12721
5
5
  singlestoredb/connection.py,sha256=QC5YQemwJOhdW_-ZBFpNLE15xFxwI1fB2LuvE1hNi9k,46812
@@ -10,6 +10,12 @@ singlestoredb/types.py,sha256=Lv0BEQl6aSZBiAe0OSI07FEJhcHZ9HX45iT9NU_mxHQ,10334
10
10
  singlestoredb/ai/__init__.py,sha256=nT048t90xqjaNhz7KJ10KfSVW4RcZRoujyC6po6Nmb8,61
11
11
  singlestoredb/ai/embeddings.py,sha256=KVvQY3viyYWXDBobFpj0xqiGRijt36zcHHlPNAfFAxA,770
12
12
  singlestoredb/alchemy/__init__.py,sha256=bUmCl1xUn2v36RMbXLIrvgKzZSqx71mp1ReUw9JeVA8,2613
13
+ singlestoredb/apps/__init__.py,sha256=IKQrPKb1d_LQvmr7jXQvgPRrB5Ja_1kGAXwYvdjp6ok,120
14
+ singlestoredb/apps/_cloud_functions.py,sha256=v8PEBz8MXryarE0nfqjwwnZiAO1S659WeITXGjJRcC4,2106
15
+ singlestoredb/apps/_config.py,sha256=DzWlFdW0_wANnE5XddLQeUv8y_zRUvw8KNz7B4l9KnU,1089
16
+ singlestoredb/apps/_dashboards.py,sha256=FOEPjxpiQL9vBaMQBlTfpmA0b4a-cadSdTFrfjdIcY4,1323
17
+ singlestoredb/apps/_process.py,sha256=eMiBO4piaRX1S6zdnMx0X0E4J7E1XrXndnVW0GRYq1Y,976
18
+ singlestoredb/apps/_uvicorn_util.py,sha256=Petkmq5keBPfXZsHBrnZfY3O2rUHvb3Cw6o-BRz5MP0,994
13
19
  singlestoredb/functions/__init__.py,sha256=EVxqWOCcXiIX4Yj7rljAYBBoVbTvm2KSuKSkMBDnEeU,42
14
20
  singlestoredb/functions/decorator.py,sha256=M103c1JAZfyGFQAU4uJ_J8XGGH3InhcfrNUCoEORNFQ,5335
15
21
  singlestoredb/functions/dtypes.py,sha256=5IwMSaSzxtSowxXrm5hZXW1lpNm6QILxiU4mAUEkBO0,32854
@@ -117,9 +123,9 @@ singlestoredb/utils/events.py,sha256=rC9cHAetua_E1f-EiFkFM-gJzQSQIH5Uk-4sspC3KjI
117
123
  singlestoredb/utils/mogrify.py,sha256=gCcn99-vgsGVjTUV7RHJ6hH4vCNrsGB_Xo4z8kiSPDQ,4201
118
124
  singlestoredb/utils/results.py,sha256=wR70LhCqlobniZf52r67zYLBOKjWHQm68NAskdRQND8,15862
119
125
  singlestoredb/utils/xdict.py,sha256=-wi1lSPTnY99fhVMBhPKJ8cCsQhNG4GMUfkEBDKYgCw,13321
120
- singlestoredb-1.6.3.dist-info/LICENSE,sha256=Bojenzui8aPNjlF3w4ojguDP7sTf8vFV_9Gc2UAG1sg,11542
121
- singlestoredb-1.6.3.dist-info/METADATA,sha256=vTNnIJWmEAPO7KExTeaoD9Xp2h8-_BNHUUhDq2lZU-U,5710
122
- singlestoredb-1.6.3.dist-info/WHEEL,sha256=c4k7z5HB0t-y0nBCv6KyJ6KCjn8SEGPddD0lhaPtU3E,96
123
- singlestoredb-1.6.3.dist-info/entry_points.txt,sha256=bSLaTWB5zGjpVYPAaI46MkkDup0su-eb3uAhCNYuRV0,48
124
- singlestoredb-1.6.3.dist-info/top_level.txt,sha256=SDtemIXf-Kp-_F2f_S6x0db33cHGOILdAEsIQZe2LZc,35
125
- singlestoredb-1.6.3.dist-info/RECORD,,
126
+ singlestoredb-1.7.0.dist-info/LICENSE,sha256=Bojenzui8aPNjlF3w4ojguDP7sTf8vFV_9Gc2UAG1sg,11542
127
+ singlestoredb-1.7.0.dist-info/METADATA,sha256=dx6R3uQafE_V3NoNKsT5mJCqTo1jrF6NdTdBqZ0rgY4,5710
128
+ singlestoredb-1.7.0.dist-info/WHEEL,sha256=c4k7z5HB0t-y0nBCv6KyJ6KCjn8SEGPddD0lhaPtU3E,96
129
+ singlestoredb-1.7.0.dist-info/entry_points.txt,sha256=bSLaTWB5zGjpVYPAaI46MkkDup0su-eb3uAhCNYuRV0,48
130
+ singlestoredb-1.7.0.dist-info/top_level.txt,sha256=SDtemIXf-Kp-_F2f_S6x0db33cHGOILdAEsIQZe2LZc,35
131
+ singlestoredb-1.7.0.dist-info/RECORD,,