plotly-cloud 0.2.0__tar.gz → 0.2.1__tar.gz
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.
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/PKG-INFO +2 -3
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/__init__.py +1 -1
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/_deploy.py +1 -3
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/_devtool_hooks.py +2 -27
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/_devtool_publish_rpc.py +2 -0
- plotly_cloud-0.2.1/plotly_cloud/_run_sync.py +34 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/cli.py +0 -3
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/pyproject.toml +2 -3
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/.gitignore +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/LICENSE +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/README.md +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/_api_types.py +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/_changes.py +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/_cloud_env.py +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/_commands.py +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/_definitions.py +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/_oauth.py +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/_parser.py +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/cloud-env.toml +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/cloud_devtools.css +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/cloud_devtools.js +0 -0
- {plotly_cloud-0.2.0 → plotly_cloud-0.2.1}/plotly_cloud/exceptions.py +0 -0
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotly-cloud
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Python extension for Plotly Cloud with CLI and Dash dev tools integration
|
|
5
5
|
Project-URL: Repository, https://github.com/plotly/plotly-cloud-extension
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Requires-Python: >=3.9
|
|
8
|
-
Requires-Dist: dash>=2.0
|
|
8
|
+
Requires-Dist: dash>=3.2.0
|
|
9
9
|
Requires-Dist: httpx<1.0.0,>=0.24.0
|
|
10
|
-
Requires-Dist: nest-asyncio>=1.6.0
|
|
11
10
|
Requires-Dist: rich>=10.0.0
|
|
12
11
|
Requires-Dist: tomli-w>=1.2.0
|
|
13
12
|
Requires-Dist: tomli>=2.2.1
|
|
@@ -135,9 +135,7 @@ async def create_deployment_zip(project_path: str, output_path: str) -> int:
|
|
|
135
135
|
dirs[:] = [
|
|
136
136
|
d
|
|
137
137
|
for d in dirs
|
|
138
|
-
if not should_exclude_path(
|
|
139
|
-
str(os.path.relpath(os.path.join(root, d), project_path)), exclude_patterns
|
|
140
|
-
)
|
|
138
|
+
if not should_exclude_path(str(os.path.relpath(os.path.join(root, d), project_path)), exclude_patterns)
|
|
141
139
|
]
|
|
142
140
|
|
|
143
141
|
for file in files:
|
|
@@ -1,36 +1,11 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
|
|
3
1
|
import dash
|
|
4
2
|
import flask
|
|
5
|
-
from packaging.version import parse as _parse_version
|
|
6
3
|
|
|
7
4
|
from plotly_cloud._devtool_publish_rpc import PlotlyCloudPublishRPC
|
|
8
|
-
|
|
9
|
-
dash_version = _parse_version(dash.__version__)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def _run_sync(coro):
|
|
13
|
-
"""Run an async coroutine synchronously, handling event loop correctly for Python 3.10+."""
|
|
14
|
-
try:
|
|
15
|
-
# Check if there's already a running loop
|
|
16
|
-
loop = asyncio.get_running_loop()
|
|
17
|
-
except RuntimeError:
|
|
18
|
-
# No running loop, try to get or create one
|
|
19
|
-
loop = asyncio.get_event_loop()
|
|
20
|
-
if loop is None or loop.is_closed():
|
|
21
|
-
loop = asyncio.new_event_loop()
|
|
22
|
-
asyncio.set_event_loop(loop)
|
|
23
|
-
|
|
24
|
-
return loop.run_until_complete(coro)
|
|
5
|
+
from plotly_cloud._run_sync import run_sync
|
|
25
6
|
|
|
26
7
|
|
|
27
8
|
def install_hook():
|
|
28
|
-
import nest_asyncio
|
|
29
|
-
|
|
30
|
-
# Make asyncio stuff runs smoothly.
|
|
31
|
-
# Prevent no loop and existing loop errors.
|
|
32
|
-
nest_asyncio.apply()
|
|
33
|
-
|
|
34
9
|
rpc = PlotlyCloudPublishRPC()
|
|
35
10
|
|
|
36
11
|
try:
|
|
@@ -59,7 +34,7 @@ def install_hook():
|
|
|
59
34
|
@dash.hooks.route("_plotly_cloud_publish", methods=["POST"])
|
|
60
35
|
def plotly_cloud_publish_rpc():
|
|
61
36
|
data = flask.request.get_json()
|
|
62
|
-
data =
|
|
37
|
+
data = run_sync(rpc.handle_operation(data))
|
|
63
38
|
return flask.jsonify(data)
|
|
64
39
|
|
|
65
40
|
@dash.hooks.setup()
|
|
@@ -4,6 +4,7 @@ import asyncio
|
|
|
4
4
|
import importlib
|
|
5
5
|
import os
|
|
6
6
|
import tempfile
|
|
7
|
+
import traceback
|
|
7
8
|
from typing import Any
|
|
8
9
|
|
|
9
10
|
import dash
|
|
@@ -167,6 +168,7 @@ class PlotlyCloudPublishRPC:
|
|
|
167
168
|
method = getattr(self, operation_name)
|
|
168
169
|
return await method(data)
|
|
169
170
|
except Exception as e:
|
|
171
|
+
traceback.print_exc()
|
|
170
172
|
return {"error": str(e)}
|
|
171
173
|
|
|
172
174
|
async def initialize(self, data: Any) -> RPCResponse:
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Background event loop for async operations
|
|
2
|
+
import asyncio
|
|
3
|
+
import threading
|
|
4
|
+
|
|
5
|
+
_loop: asyncio.AbstractEventLoop = None # type: ignore
|
|
6
|
+
_loop_thread: threading.Thread = None # type: ignore
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _get_event_loop():
|
|
10
|
+
"""Get or create a background event loop running in a separate thread."""
|
|
11
|
+
global _loop, _loop_thread
|
|
12
|
+
|
|
13
|
+
if _loop is None or _loop.is_closed():
|
|
14
|
+
_loop = asyncio.new_event_loop()
|
|
15
|
+
|
|
16
|
+
def run_loop():
|
|
17
|
+
asyncio.set_event_loop(_loop)
|
|
18
|
+
_loop.run_forever()
|
|
19
|
+
|
|
20
|
+
_loop_thread = threading.Thread(target=run_loop, daemon=True)
|
|
21
|
+
_loop_thread.start()
|
|
22
|
+
|
|
23
|
+
return _loop
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def run_sync(coro):
|
|
27
|
+
"""Run an async coroutine synchronously using a background event loop.
|
|
28
|
+
|
|
29
|
+
This avoids issues with nested event loops and ensures proper task context
|
|
30
|
+
for Python 3.14+ where anyio requires asyncio.current_task() to return a valid task.
|
|
31
|
+
"""
|
|
32
|
+
loop = _get_event_loop()
|
|
33
|
+
future = asyncio.run_coroutine_threadsafe(coro, loop)
|
|
34
|
+
return future.result()
|
|
@@ -7,7 +7,6 @@ import textwrap
|
|
|
7
7
|
from collections.abc import Sequence
|
|
8
8
|
from typing import Union
|
|
9
9
|
|
|
10
|
-
import nest_asyncio
|
|
11
10
|
from rich.console import Console
|
|
12
11
|
from rich.panel import Panel
|
|
13
12
|
|
|
@@ -216,8 +215,6 @@ def print_command_help(command_class: BaseCommand, group: str, command: str) ->
|
|
|
216
215
|
|
|
217
216
|
def main() -> None:
|
|
218
217
|
"""Main CLI entry point."""
|
|
219
|
-
# Allow to run multiple calls to asyncio run.
|
|
220
|
-
nest_asyncio.apply()
|
|
221
218
|
|
|
222
219
|
# Parse group and command
|
|
223
220
|
group, command, args_index = parse_group_and_command()
|
|
@@ -4,17 +4,16 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "plotly-cloud"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "Python extension for Plotly Cloud with CLI and Dash dev tools integration"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
11
11
|
dependencies = [
|
|
12
12
|
"httpx>=0.24.0,<1.0.0",
|
|
13
|
-
"dash>=2.0
|
|
13
|
+
"dash>=3.2.0",
|
|
14
14
|
"rich>=10.0.0",
|
|
15
15
|
"tomli>=2.2.1",
|
|
16
16
|
"tomli-w>=1.2.0",
|
|
17
|
-
"nest-asyncio>=1.6.0",
|
|
18
17
|
]
|
|
19
18
|
|
|
20
19
|
[project.urls]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|