Skip to content

Commit 35200cf

Browse files
authored
Merge branch 'plotly:master' into patch-2
2 parents 4815f87 + 582127f commit 35200cf

60 files changed

Lines changed: 106 additions & 10677 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@ src/py/integration_tests/report*
2323
# avoid ignore .gitkeep
2424
!src/py/integration_tests/renders/.gitkeep
2525
node_modules/
26+
27+
src/py/site/*

src/py/CHANGELOG.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
- Fix bug where attribute was inconsistently named
12
v1.1.0rc0
23
- Improve verbosity of errors when starting kaleido improperly
34
- Add new api functions start/stop_sync_server

src/py/kaleido/__init__.py

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,6 @@
1212
from ._page_generator import PageGenerator
1313
from .kaleido import Kaleido
1414

15-
_global_server = _sync_server.GlobalKaleidoServer()
16-
17-
18-
def start_sync_server(*args, **kwargs):
19-
"""
20-
Start a kaleido server which will process all sync generation requests.
21-
22-
Only one server can be started at a time.
23-
24-
This wrapper function takes the exact same arguments as kaleido.Kaleido().
25-
"""
26-
_global_server.open(*args, **kwargs)
27-
28-
29-
def stop_sync_server():
30-
"""Stop the kaleido server. It can be restarted."""
31-
_global_server.close()
32-
33-
3415
__all__ = [
3516
"Kaleido",
3617
"PageGenerator",
@@ -46,6 +27,40 @@ def stop_sync_server():
4627
"write_fig_sync",
4728
]
4829

30+
_global_server = _sync_server.GlobalKaleidoServer()
31+
32+
33+
def start_sync_server(*args, silence_warnings=False, **kwargs):
34+
"""
35+
Start a kaleido server which will process all sync generation requests.
36+
37+
The kaleido server is a singleton, so it can't be opened twice. This
38+
function will warn you if the server is already running.
39+
40+
This wrapper function takes the exact same arguments as kaleido.Kaleido(),
41+
except one extra, `silence_warnings`.
42+
43+
Args:
44+
*args: all arguments `Kaleido()` would take.
45+
silence_warnings: (bool, default False): If True, don't emit warning if
46+
starting an already started server.
47+
**kwargs: all keyword arguments `Kaleido()` would take.
48+
49+
"""
50+
_global_server.open(*args, silence_warnings=silence_warnings, **kwargs)
51+
52+
53+
def stop_sync_server(*, silence_warnings=False):
54+
"""
55+
Stop the kaleido server. It can be restarted. Warns if not started.
56+
57+
Args:
58+
silence_warnings: (bool, default False): If True, don't emit warning if
59+
stopping a server that's not running.
60+
61+
"""
62+
_global_server.close(silence_warnings=silence_warnings)
63+
4964

5065
async def calc_fig(
5166
fig,

src/py/kaleido/_page_generator.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
from __future__ import annotations
2+
13
from pathlib import Path
4+
from urllib.parse import urlparse
25

36
import logistro
47

@@ -10,6 +13,14 @@
1013
KJS_PATH = Path(__file__).resolve().parent / "vendor" / "kaleido_scopes.js"
1114

1215

16+
def _ensure_path(path: Path | str):
17+
_logger.debug(f"Ensuring path {path!s}")
18+
if urlparse(str(path)).scheme.startswith("http"): # is url
19+
return
20+
if not Path(path).exists():
21+
raise FileNotFoundError(f"{path!s} does not exist.")
22+
23+
1324
class PageGenerator:
1425
"""
1526
A page generator can set the versions of the js libraries used to render.
@@ -35,7 +46,7 @@ class PageGenerator:
3546
footer = f"""
3647
<script src="{KJS_PATH.as_uri()}"></script>
3748
</head>
38-
<body style="{{margin: 0; padding: 0;}}"><img id="kaleido-image"><img></body>
49+
<body style="{{margin: 0; padding: 0;}}"><img id="kaleido-image"></img></body>
3950
</html>
4051
"""
4152
"""The footer is the HTML that always goes on the bottom. Rarely needs changing."""
@@ -45,13 +56,14 @@ def __init__(self, *, plotly=None, mathjax=None, others=None, force_cdn=False):
4556
Create a PageGenerator.
4657
4758
Args:
48-
plotly: the url to the plotly script to use. The default is the one
49-
plotly.py is using, if not installed, it uses the constant declared.
50-
mathjax: the url to the mathjax script. By default is constant above.
51-
Can be set to false to turn off.
52-
others: a list of other script urls to include. Usually strings, but can be
53-
(str, str) where its (url, encoding).
54-
force_cdn: (default False) Don't use plotly import, use CDN
59+
plotly: The url to the plotly.js to use. Defaults to plotly.js
60+
present in plotly.py, if installed. Otherwise fallback to
61+
value of DEFAULT_PLOTLY.
62+
mathjax: The url to the mathjax script. Defaults to values of
63+
DEFAULT_MATHJAX. Can be set to false to disable mathjax.
64+
others: A list of other script urls to include. Usually strings, but
65+
can be (str, str) where it's (url, encoding).
66+
force_cdn: Set True to force CDN use, defaults to False.
5567
5668
"""
5769
self._scripts = []
@@ -81,14 +93,19 @@ def __init__(self, *, plotly=None, mathjax=None, others=None, force_cdn=False):
8193
_logger.info("Plotly not installed. Using CDN.")
8294
plotly = (DEFAULT_PLOTLY, "utf-8")
8395
elif isinstance(plotly, str):
96+
_ensure_path(plotly)
8497
plotly = (plotly, "utf-8")
8598
_logger.debug(f"Plotly script: {plotly}")
8699
self._scripts.append(plotly)
87100
if mathjax is not False:
88101
if not mathjax:
89102
mathjax = DEFAULT_MATHJAX
103+
else:
104+
_ensure_path(mathjax)
90105
self._scripts.append(mathjax)
91106
if others:
107+
for o in others:
108+
_ensure_path(o)
92109
self._scripts.extend(others)
93110

94111
def generate_index(self, path=None):

src/py/kaleido/_sync_server.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from __future__ import annotations
22

33
import asyncio
4+
import atexit
45
import warnings
6+
from functools import partial
57
from queue import Queue
68
from threading import Thread
79
from typing import TYPE_CHECKING, NamedTuple
@@ -53,30 +55,38 @@ def __new__(cls):
5355
def is_running(self):
5456
return self._initialized
5557

56-
def open(self, *args: Any, **kwargs: Any) -> None:
58+
def open(self, *args: Any, silence_warnings=False, **kwargs: Any) -> None:
5759
"""Initialize the singleton with three values."""
5860
if self.is_running():
59-
warnings.warn(
60-
"Server already open.",
61-
RuntimeWarning,
62-
stacklevel=2,
63-
)
61+
if not silence_warnings:
62+
warnings.warn(
63+
"Server already open.",
64+
RuntimeWarning,
65+
stacklevel=2,
66+
)
6467
return
6568
coroutine = self._server(*args, **kwargs)
66-
self._thread: Thread = Thread(target=asyncio.run, args=(coroutine,))
69+
self._thread: Thread = Thread(
70+
target=asyncio.run,
71+
args=(coroutine,),
72+
daemon=True,
73+
)
6774
self._task_queue: Queue[Task | None] = Queue()
6875
self._return_queue: Queue[Any] = Queue()
6976
self._thread.start()
7077
self._initialized = True
78+
close = partial(self.close, silence_warnings=True)
79+
atexit.register(close)
7180

72-
def close(self):
81+
def close(self, *, silence_warnings=False):
7382
"""Reset the singleton back to an uninitialized state."""
7483
if not self.is_running():
75-
warnings.warn(
76-
"Server already closed.",
77-
RuntimeWarning,
78-
stacklevel=2,
79-
)
84+
if not silence_warnings:
85+
warnings.warn(
86+
"Server already closed.",
87+
RuntimeWarning,
88+
stacklevel=2,
89+
)
8090
return
8191
self._task_queue.put(None)
8292
self._thread.join()

src/py/kaleido/kaleido.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ class Kaleido(choreo.Browser):
5656

5757
async def close(self):
5858
"""Close the browser."""
59-
if self.tmp_dir:
60-
self.tmp_dir.clean()
59+
if self._tmp_dir:
60+
self._tmp_dir.clean()
6161
_logger.info("Cancelling tasks.")
6262
for task in self._main_tasks:
6363
if not task.done():
@@ -138,8 +138,8 @@ def __init__(self, *args, **kwargs): # noqa: D417 no args/kwargs in description
138138
elif page and hasattr(page, "is_file") and page.is_file():
139139
self._index = page.as_uri()
140140
else:
141-
self.tmp_dir = TmpDirectory(sneak=self.is_isolated())
142-
index = self.tmp_dir.path / "index.html"
141+
self._tmp_dir = TmpDirectory(sneak=self.is_isolated())
142+
index = self._tmp_dir.path / "index.html"
143143
self._index = index.as_uri()
144144
if not page:
145145
page = PageGenerator(plotly=self._plotlyjs, mathjax=self._mathjax)

src/py/kaleido/vendor/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@
1212
<script src="https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-svg.js"></script>
1313
<script src="./kaleido_scopes.js"></script>
1414
</head>
15-
<body style="{margin: 0; padding: 0;}"><img id="kaleido-image"><img></body>
15+
<body style="{margin: 0; padding: 0;}"><img id="kaleido-image"></img></body>
1616
</html>

0 commit comments

Comments
 (0)