dash-startup-loading-plugin 0.2.0__tar.gz → 0.4.0__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.
- {dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin.egg-info → dash_startup_loading_plugin-0.4.0}/PKG-INFO +207 -145
- {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/README.md +205 -141
- {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/pyproject.toml +6 -3
- {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/src/dash_startup_loading_plugin/__init__.py +8 -2
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/__init__.py +5 -0
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/__main__.py +5 -0
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/antd.py +109 -0
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/basic.py +49 -0
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/cli.py +89 -0
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/fac.py +110 -0
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/mantine.py +79 -0
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/examples/shared.py +33 -0
- {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/src/dash_startup_loading_plugin/plugin.py +96 -33
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/resources/loading.css +64 -0
- dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin/resources/startup-loading.js → dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/resources/loading.js +6 -6
- dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin/resources/startup-theme.js → dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin/resources/theme.js +2 -2
- {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin.egg-info}/PKG-INFO +207 -145
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin.egg-info/SOURCES.txt +24 -0
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin.egg-info/entry_points.txt +5 -0
- dash_startup_loading_plugin-0.4.0/src/dash_startup_loading_plugin.egg-info/requires.txt +1 -0
- dash_startup_loading_plugin-0.4.0/tests/test_examples.py +150 -0
- dash_startup_loading_plugin-0.4.0/tests/test_plugin.py +237 -0
- dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin/resources/startup-loading.css +0 -64
- dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin.egg-info/SOURCES.txt +0 -15
- dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin.egg-info/entry_points.txt +0 -2
- dash_startup_loading_plugin-0.2.0/src/dash_startup_loading_plugin.egg-info/requires.txt +0 -4
- dash_startup_loading_plugin-0.2.0/tests/test_plugin.py +0 -153
- {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/LICENSE +0 -0
- {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/setup.cfg +0 -0
- {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/src/dash_startup_loading_plugin.egg-info/dependency_links.txt +0 -0
- {dash_startup_loading_plugin-0.2.0 → dash_startup_loading_plugin-0.4.0}/src/dash_startup_loading_plugin.egg-info/top_level.txt +0 -0
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dash-startup-loading-plugin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A configurable full-screen startup loading overlay for Dash apps, packaged as a Dash Hooks plugin.
|
|
5
5
|
Author-email: Ethan Zhang <ethan.zhang2016@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
|
-
Keywords: dash,plotly,loading,plugin
|
|
7
|
+
Keywords: dash,plotly,loading,plugin
|
|
8
8
|
Classifier: Framework :: Dash
|
|
9
9
|
Requires-Python: >=3.9
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Requires-Dist: dash>=3.0.3
|
|
13
|
-
Provides-Extra: test
|
|
14
|
-
Requires-Dist: pytest>=8; extra == "test"
|
|
15
13
|
Dynamic: license-file
|
|
16
14
|
|
|
17
15
|
# dash-startup-loading-plugin
|
|
@@ -51,7 +49,7 @@ discovery, resource hooks, and the index hook described in the official
|
|
|
51
49
|
## Installation
|
|
52
50
|
|
|
53
51
|
```bash
|
|
54
|
-
pip install "dash-startup-loading-plugin>=0.
|
|
52
|
+
pip install "dash-startup-loading-plugin>=0.4.0"
|
|
55
53
|
```
|
|
56
54
|
|
|
57
55
|
The package declares the following entry point:
|
|
@@ -66,6 +64,25 @@ package therefore enables the default startup overlay for Dash applications in
|
|
|
66
64
|
that Python environment; an explicit import is only needed when changing its
|
|
67
65
|
configuration or using its Python API.
|
|
68
66
|
|
|
67
|
+
When `dash_antd_components` from Dash Ant Design is installed in the same
|
|
68
|
+
environment, the plugin detects it during automatic hook discovery and applies
|
|
69
|
+
the matching `#ffffff` and `#121212` loading backgrounds. Dash Ant Design
|
|
70
|
+
applications therefore only need to install this plugin; calling
|
|
71
|
+
`configure_antd()` is optional and is reserved for explicit overrides.
|
|
72
|
+
|
|
73
|
+
## What's new in 0.4.0
|
|
74
|
+
|
|
75
|
+
- Adds `configure_antd()` with matching `#ffffff` and `#121212` loading
|
|
76
|
+
backgrounds plus explicit light/dark overrides.
|
|
77
|
+
- Adds `configure_mantine()` with theme defaults sourced from Dash Mantine
|
|
78
|
+
Components and its pre-render color-scheme hook.
|
|
79
|
+
- Updates the Dash Ant Design example for the structured
|
|
80
|
+
`ConfigProvider.theme.algorithm` API.
|
|
81
|
+
- Adds a Dash Mantine Components example with persisted theme switching.
|
|
82
|
+
- Adds `configure_fac()` and a feffery-antd-components example.
|
|
83
|
+
- Uses one shared set of display copy across all packaged examples.
|
|
84
|
+
- Supports Dash versions from 3.0.3 onward.
|
|
85
|
+
|
|
69
86
|
## What's new in 0.2.0
|
|
70
87
|
|
|
71
88
|
- Resolves the loading background before first paint from a persisted
|
|
@@ -104,25 +121,73 @@ from dash import Dash, html
|
|
|
104
121
|
from dash_startup_loading_plugin import configure
|
|
105
122
|
|
|
106
123
|
configure(
|
|
107
|
-
required_selectors=["#
|
|
124
|
+
required_selectors=["#usage-header", "#usage-sidebar-menu"],
|
|
108
125
|
pending_selector="[data-dac-async-placeholder]",
|
|
109
126
|
timeout_ms=6000,
|
|
110
|
-
minimum_display_ms=200,
|
|
111
127
|
fade_duration_ms=160,
|
|
112
|
-
color="#1677ff",
|
|
113
|
-
dark_color="#4096ff",
|
|
114
128
|
)
|
|
115
129
|
|
|
116
130
|
app = Dash(__name__)
|
|
117
131
|
app.layout = html.Div(
|
|
118
132
|
[
|
|
119
|
-
html.Header("Dashboard", id="
|
|
120
|
-
html.Nav("Navigation", id="sidebar-menu"),
|
|
133
|
+
html.Header("Dashboard", id="usage-header"),
|
|
134
|
+
html.Nav("Navigation", id="usage-sidebar-menu"),
|
|
121
135
|
]
|
|
122
136
|
)
|
|
123
137
|
```
|
|
124
138
|
|
|
125
|
-
|
|
139
|
+
## Installed demos
|
|
140
|
+
|
|
141
|
+
The example applications are included in the installed Python package. Select a
|
|
142
|
+
packaged example with the `dash-startup-loading-plugin` command:
|
|
143
|
+
|
|
144
|
+
Component libraries are not dependencies of this plugin. Install the library
|
|
145
|
+
used by the selected example separately:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
pip install dash-mantine-components
|
|
149
|
+
pip install dash-ant-design
|
|
150
|
+
pip install "feffery-antd-components>=0.4.0"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
If the selected component library cannot be imported, the command exits with
|
|
154
|
+
an error naming the failed import and the package to install.
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Framework-neutral Dash
|
|
158
|
+
dash-startup-loading-plugin examples.dash
|
|
159
|
+
|
|
160
|
+
# Dash Mantine Components
|
|
161
|
+
dash-startup-loading-plugin examples.dash-mantine-components
|
|
162
|
+
|
|
163
|
+
# Dash Ant Design
|
|
164
|
+
dash-startup-loading-plugin examples.dash-ant-design
|
|
165
|
+
|
|
166
|
+
# feffery-antd-components
|
|
167
|
+
dash-startup-loading-plugin examples.feffery-antd-components
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Server options can be supplied directly:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
dash-startup-loading-plugin examples.dash-mantine-components \
|
|
174
|
+
--host 0.0.0.0 --port 8050 --debug
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The same launcher is available through Python when a console-script path is not
|
|
178
|
+
available:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
python -m dash_startup_loading_plugin.examples examples.dash-mantine-components
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Application code can create a selected demo without starting its server:
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
from dash_startup_loading_plugin.examples import create_demo_app
|
|
188
|
+
|
|
189
|
+
app = create_demo_app("dash-mantine-components")
|
|
190
|
+
```
|
|
126
191
|
|
|
127
192
|
## Readiness behavior
|
|
128
193
|
|
|
@@ -152,7 +217,7 @@ immutable `StartupLoadingConfig` instance.
|
|
|
152
217
|
| Option | Default | Description |
|
|
153
218
|
|---|---:|---|
|
|
154
219
|
| `enabled` | `True` | Inject the startup overlay. Set to `False` to disable it. |
|
|
155
|
-
| `overlay_id` | `"dash-
|
|
220
|
+
| `overlay_id` | `"dash-loading"` | HTML `id` of the injected overlay; also used by the browser API. |
|
|
156
221
|
| `aria_label` | `"Loading"` | Accessible label on the overlay's `role="status"` element. |
|
|
157
222
|
| `root_selector` | `"#react-entry-point"` | Dash renderer root observed for mounted content. |
|
|
158
223
|
| `required_selectors` | `("#react-entry-point",)` | Iterable of document-level CSS selectors that must all exist. A single string is not accepted. |
|
|
@@ -187,35 +252,136 @@ in this order:
|
|
|
187
252
|
followed by the common `theme`, `color-theme`, and `color-scheme` keys.
|
|
188
253
|
6. `prefers-color-scheme`.
|
|
189
254
|
|
|
190
|
-
The result is written to `data-dash-
|
|
255
|
+
The result is written to `data-dash-loading-theme` before the body is
|
|
191
256
|
parsed. This isolates the overlay styling without changing classes or data
|
|
192
257
|
attributes owned by Tailwind, Dash Mantine Components, or the application.
|
|
193
258
|
The stylesheet also adjusts its animation for `prefers-reduced-motion`.
|
|
194
259
|
|
|
260
|
+
### Dash Mantine Components
|
|
261
|
+
|
|
262
|
+
Dash Mantine Components 2.6 and later includes `ColorSchemeToggle`, which
|
|
263
|
+
switches the active color scheme without a callback and persists it in
|
|
264
|
+
`mantine-color-scheme-value`. The startup plugin reads that value before Dash
|
|
265
|
+
and React mount. To make the loading transition seamless, use Mantine's current
|
|
266
|
+
default dark body color for the overlay:
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
import dash_mantine_components as dmc
|
|
270
|
+
from dash_startup_loading_plugin import configure_mantine
|
|
271
|
+
|
|
272
|
+
configure_mantine()
|
|
273
|
+
|
|
274
|
+
app.layout = dmc.MantineProvider(
|
|
275
|
+
[
|
|
276
|
+
dmc.ColorSchemeToggle(
|
|
277
|
+
lightIcon=dmc.Text("☀"),
|
|
278
|
+
darkIcon=dmc.Text("☾"),
|
|
279
|
+
),
|
|
280
|
+
dmc.Text("Application content", id="app-ready"),
|
|
281
|
+
],
|
|
282
|
+
defaultColorScheme="auto",
|
|
283
|
+
)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Run `dash-startup-loading-plugin examples.dash-mantine-components` for the
|
|
287
|
+
complete example.
|
|
288
|
+
|
|
289
|
+
`configure_mantine()` keeps DMC optional. When used, it registers DMC's
|
|
290
|
+
pre-render color-scheme hook, disables the Dash Ant Design placeholder check,
|
|
291
|
+
and derives the light and dark loading backgrounds from DMC's active default
|
|
292
|
+
theme. Any explicit configuration still takes precedence:
|
|
293
|
+
|
|
294
|
+
```python
|
|
295
|
+
configure_mantine(dark_background="#202020")
|
|
296
|
+
```
|
|
297
|
+
|
|
195
298
|
### Dash Ant Design persistence
|
|
196
299
|
|
|
197
|
-
`dash_antd_components.ConfigProvider`
|
|
198
|
-
|
|
300
|
+
Current `dash_antd_components.ConfigProvider.theme` accepts a structured theme
|
|
301
|
+
configuration whose `algorithm` is `"default"`, `"dark"`, `"compact"`, or an
|
|
302
|
+
array of those values. Persist a user-facing system/light/dark selector, resolve
|
|
303
|
+
the system preference in a clientside callback, and store the semantic choice
|
|
304
|
+
in the small conventional `localStorage["theme"]` value that the startup plugin
|
|
305
|
+
reads before Dash mounts:
|
|
199
306
|
|
|
200
307
|
```python
|
|
201
308
|
import dash_antd_components as dac
|
|
202
|
-
from
|
|
309
|
+
from dash import Input, Output, clientside_callback
|
|
310
|
+
from dash_startup_loading_plugin import configure_antd
|
|
203
311
|
|
|
204
|
-
|
|
312
|
+
configure_antd()
|
|
205
313
|
|
|
206
314
|
provider = dac.ConfigProvider(
|
|
207
|
-
|
|
315
|
+
[
|
|
316
|
+
app_content,
|
|
317
|
+
dac.Segmented(
|
|
318
|
+
id="theme-mode",
|
|
319
|
+
options=["system", "light", "dark"],
|
|
320
|
+
value="system",
|
|
321
|
+
persistence=True,
|
|
322
|
+
persisted_props=["value"],
|
|
323
|
+
persistence_type="local",
|
|
324
|
+
),
|
|
325
|
+
],
|
|
208
326
|
id="theme-provider",
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
327
|
+
theme={"algorithm": "default"},
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
clientside_callback(
|
|
331
|
+
"""function(mode) {
|
|
332
|
+
localStorage.setItem("theme", JSON.stringify(mode));
|
|
333
|
+
const dark = mode === "dark" || (
|
|
334
|
+
mode === "system"
|
|
335
|
+
&& window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
336
|
+
);
|
|
337
|
+
return {algorithm: dark ? "dark" : "default"};
|
|
338
|
+
}""",
|
|
339
|
+
Output("theme-provider", "theme"),
|
|
340
|
+
Input("theme-mode", "value"),
|
|
341
|
+
)
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
The selector owns the semantic `"system"` state; `ConfigProvider` receives only
|
|
345
|
+
the algorithms allowed by its current API. `configure_antd()` uses `#ffffff`
|
|
346
|
+
and `#121212`, matching the component library's default light and dark
|
|
347
|
+
backgrounds. If the application customizes either background, pass the same
|
|
348
|
+
values explicitly:
|
|
349
|
+
|
|
350
|
+
```python
|
|
351
|
+
configure_antd(
|
|
352
|
+
background="#f5f5f5",
|
|
353
|
+
dark_background="#202020",
|
|
354
|
+
)
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Run `dash-startup-loading-plugin examples.dash-ant-design` for the complete
|
|
358
|
+
switcher.
|
|
359
|
+
|
|
360
|
+
### feffery-antd-components persistence
|
|
361
|
+
|
|
362
|
+
FAC 0.4 and later supports Dash 3 and exposes Ant Design's theme algorithm
|
|
363
|
+
through `AntdConfigProvider.algorithm`. Use `configure_fac()` before creating
|
|
364
|
+
the app, persist a semantic system/light/dark selection, and return either
|
|
365
|
+
`"default"` or `"dark"` to the provider:
|
|
366
|
+
|
|
367
|
+
```python
|
|
368
|
+
import feffery_antd_components as fac
|
|
369
|
+
from dash import Dash
|
|
370
|
+
from dash_startup_loading_plugin import configure_fac
|
|
371
|
+
|
|
372
|
+
configure_fac(required_selectors=["#fac-app-ready"])
|
|
373
|
+
|
|
374
|
+
app = Dash(__name__)
|
|
375
|
+
app.layout = fac.AntdConfigProvider(
|
|
376
|
+
fac.AntdButton("Example component", id="fac-app-ready"),
|
|
377
|
+
id="fac-theme-provider",
|
|
378
|
+
algorithm="default",
|
|
212
379
|
)
|
|
213
380
|
```
|
|
214
381
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
[`examples/basic.py`](examples/basic.py) for the complete switcher.
|
|
382
|
+
Run `dash-startup-loading-plugin examples.feffery-antd-components` for the
|
|
383
|
+
complete persisted-theme example. FAC remains an external dependency and is
|
|
384
|
+
imported only when that example is selected.
|
|
219
385
|
|
|
220
386
|
### Custom loader markup
|
|
221
387
|
|
|
@@ -242,12 +408,22 @@ configuration. Never populate it with user input.
|
|
|
242
408
|
from dash_startup_loading_plugin import (
|
|
243
409
|
StartupLoadingConfig,
|
|
244
410
|
configure,
|
|
411
|
+
configure_antd,
|
|
412
|
+
configure_fac,
|
|
413
|
+
configure_mantine,
|
|
245
414
|
get_config,
|
|
246
415
|
reset_config,
|
|
247
416
|
)
|
|
248
417
|
```
|
|
249
418
|
|
|
250
419
|
- `configure(**changes)` validates and applies a partial configuration update.
|
|
420
|
+
- `configure_antd(**changes)` matches the loading backgrounds to Dash Ant
|
|
421
|
+
Design's light and dark themes. Installed Dash Ant Design is detected
|
|
422
|
+
automatically, so this helper is only needed for explicit overrides.
|
|
423
|
+
- `configure_fac(**changes)` applies the equivalent light and dark loading
|
|
424
|
+
backgrounds for feffery-antd-components.
|
|
425
|
+
- `configure_mantine(**changes)` applies DMC theme defaults and registers DMC's
|
|
426
|
+
pre-render color-scheme hook.
|
|
251
427
|
- `get_config()` returns the current immutable configuration.
|
|
252
428
|
- `reset_config()` restores all defaults. It is primarily useful in tests.
|
|
253
429
|
- `StartupLoadingConfig` is the frozen dataclass containing all options.
|
|
@@ -261,21 +437,21 @@ The plugin exposes two methods for integrations that need explicit control:
|
|
|
261
437
|
|
|
262
438
|
```javascript
|
|
263
439
|
// Recheck the configured readiness conditions.
|
|
264
|
-
window.
|
|
440
|
+
window.dashLoading.check();
|
|
265
441
|
|
|
266
442
|
// Begin a manual dismissal.
|
|
267
|
-
window.
|
|
443
|
+
window.dashLoading.finish();
|
|
268
444
|
|
|
269
445
|
// A custom overlay_id can be supplied to either method.
|
|
270
|
-
window.
|
|
446
|
+
window.dashLoading.finish("my-loading-overlay");
|
|
271
447
|
```
|
|
272
448
|
|
|
273
449
|
Before fading out, the overlay dispatches a bubbling
|
|
274
|
-
`dash-
|
|
450
|
+
`dash-loading:ready` event. Its `detail.reason` is `"ready"`,
|
|
275
451
|
`"timeout"`, or `"manual"`:
|
|
276
452
|
|
|
277
453
|
```javascript
|
|
278
|
-
document.addEventListener("dash-
|
|
454
|
+
document.addEventListener("dash-loading:ready", function (event) {
|
|
279
455
|
console.log("Startup overlay finished:", event.detail.reason);
|
|
280
456
|
});
|
|
281
457
|
```
|
|
@@ -345,120 +521,6 @@ This is expected with automatic `dash_hooks` discovery. Use a dedicated virtual
|
|
|
345
521
|
environment, uninstall the package where it is not wanted, or call
|
|
346
522
|
`configure(enabled=False)` before constructing those Dash apps.
|
|
347
523
|
|
|
348
|
-
## Development
|
|
349
|
-
|
|
350
|
-
Clone the repository, then install the project and test dependencies:
|
|
351
|
-
|
|
352
|
-
```bash
|
|
353
|
-
uv sync --extra test
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
Run the tests and example:
|
|
357
|
-
|
|
358
|
-
```bash
|
|
359
|
-
uv run pytest
|
|
360
|
-
uv run --with dash-ant-design python examples/basic.py
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
The example uses `dash_antd_components.ConfigProvider` to demonstrate native
|
|
364
|
-
theme persistence, so `dash-ant-design` is an example-only dependency rather
|
|
365
|
-
than a runtime dependency of the plugin.
|
|
366
|
-
|
|
367
|
-
Build the source distribution and wheel:
|
|
368
|
-
|
|
369
|
-
```bash
|
|
370
|
-
uv build
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
## Publishing to PyPI
|
|
374
|
-
|
|
375
|
-
PyPI does not allow replacing an existing distribution file. Confirm that the
|
|
376
|
-
version in `pyproject.toml` is new before building, then create the artifacts
|
|
377
|
-
from a clean `dist/` directory:
|
|
378
|
-
|
|
379
|
-
```bash
|
|
380
|
-
rm -rf build dist src/*.egg-info
|
|
381
|
-
uv lock
|
|
382
|
-
uv run --extra test pytest
|
|
383
|
-
uvx ruff check src tests examples
|
|
384
|
-
uv build
|
|
385
|
-
uvx twine check dist/*
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
Inspect the resulting files before upload:
|
|
389
|
-
|
|
390
|
-
```bash
|
|
391
|
-
ls -lh dist/
|
|
392
|
-
unzip -l dist/dash_startup_loading_plugin-0.2.0-py3-none-any.whl
|
|
393
|
-
tar -tzf dist/dash_startup_loading_plugin-0.2.0.tar.gz
|
|
394
|
-
uv publish --dry-run dist/*
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
### TestPyPI
|
|
398
|
-
|
|
399
|
-
Create a TestPyPI API token, then upload to its legacy upload endpoint:
|
|
400
|
-
|
|
401
|
-
```bash
|
|
402
|
-
export UV_PUBLISH_TOKEN="pypi-your-test-token"
|
|
403
|
-
uv publish \
|
|
404
|
-
--publish-url https://test.pypi.org/legacy/ \
|
|
405
|
-
--check-url https://test.pypi.org/simple/ \
|
|
406
|
-
dist/*
|
|
407
|
-
unset UV_PUBLISH_TOKEN
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
Test installation in an isolated environment:
|
|
411
|
-
|
|
412
|
-
```bash
|
|
413
|
-
uv run --isolated \
|
|
414
|
-
--index-url https://test.pypi.org/simple/ \
|
|
415
|
-
--extra-index-url https://pypi.org/simple/ \
|
|
416
|
-
--with dash-startup-loading-plugin==0.2.0 \
|
|
417
|
-
python -c "import dash_startup_loading_plugin; print('import ok')"
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
The extra PyPI index is needed because TestPyPI may not contain the plugin's
|
|
421
|
-
runtime dependencies.
|
|
422
|
-
|
|
423
|
-
### PyPI with an API token
|
|
424
|
-
|
|
425
|
-
Create a project-scoped PyPI token and publish the checked artifacts:
|
|
426
|
-
|
|
427
|
-
```bash
|
|
428
|
-
export UV_PUBLISH_TOKEN="pypi-your-project-token"
|
|
429
|
-
uv publish dist/*
|
|
430
|
-
unset UV_PUBLISH_TOKEN
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
Do not place tokens in `pyproject.toml`, shell history, source control, or CI
|
|
434
|
-
logs.
|
|
435
|
-
|
|
436
|
-
### PyPI Trusted Publishing
|
|
437
|
-
|
|
438
|
-
For CI releases, configure the repository and workflow as a Trusted Publisher
|
|
439
|
-
in the PyPI project settings. The publishing job needs the
|
|
440
|
-
`id-token: write` permission and can upload without a long-lived token:
|
|
441
|
-
|
|
442
|
-
```yaml
|
|
443
|
-
permissions:
|
|
444
|
-
contents: read
|
|
445
|
-
id-token: write
|
|
446
|
-
|
|
447
|
-
steps:
|
|
448
|
-
- uses: actions/checkout@v4
|
|
449
|
-
- uses: astral-sh/setup-uv@v8
|
|
450
|
-
- run: uv build
|
|
451
|
-
- run: uv publish --trusted-publishing always
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
After publishing, verify the release:
|
|
455
|
-
|
|
456
|
-
```bash
|
|
457
|
-
uv run --isolated \
|
|
458
|
-
--with dash-startup-loading-plugin==0.2.0 \
|
|
459
|
-
python -c "import dash_startup_loading_plugin; print('import ok')"
|
|
460
|
-
```
|
|
461
|
-
|
|
462
524
|
## License
|
|
463
525
|
|
|
464
526
|
MIT. See [`LICENSE`](LICENSE).
|