showrunner 0.1.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.
- showrunner-0.1.0/PKG-INFO +112 -0
- showrunner-0.1.0/README.md +89 -0
- showrunner-0.1.0/pyproject.toml +47 -0
- showrunner-0.1.0/src/showrunner/__init__.py +12 -0
- showrunner-0.1.0/src/showrunner/app.py +138 -0
- showrunner-0.1.0/src/showrunner/cli.py +896 -0
- showrunner-0.1.0/src/showrunner/config.py +246 -0
- showrunner-0.1.0/src/showrunner/database.py +75 -0
- showrunner-0.1.0/src/showrunner/hookspecs.py +129 -0
- showrunner-0.1.0/src/showrunner/models.py +169 -0
- showrunner-0.1.0/src/showrunner/pdf_layout.toml +138 -0
- showrunner-0.1.0/src/showrunner/plugins/__init__.py +38 -0
- showrunner-0.1.0/src/showrunner/plugins/admin.py +208 -0
- showrunner-0.1.0/src/showrunner/plugins/cmd.py +51 -0
- showrunner-0.1.0/src/showrunner/plugins/comms.py +51 -0
- showrunner-0.1.0/src/showrunner/plugins/dashboard.py +72 -0
- showrunner-0.1.0/src/showrunner/plugins/db.py +182 -0
- showrunner-0.1.0/src/showrunner/plugins/designer.py +51 -0
- showrunner-0.1.0/src/showrunner/plugins/lighter.py +51 -0
- showrunner-0.1.0/src/showrunner/plugins/mixer.py +51 -0
- showrunner-0.1.0/src/showrunner/plugins/printer.py +600 -0
- showrunner-0.1.0/src/showrunner/plugins/programmer.py +51 -0
- showrunner-0.1.0/src/showrunner/plugins/prompter.py +51 -0
- showrunner-0.1.0/src/showrunner/plugins/recorder.py +51 -0
- showrunner-0.1.0/src/showrunner/plugins/scripter.py +1076 -0
- showrunner-0.1.0/src/showrunner/plugins/stage_manager.py +51 -0
- showrunner-0.1.0/src/showrunner/plugins/stopper.py +51 -0
- showrunner-0.1.0/src/showrunner/templates/sqladmin/layout.html +80 -0
- showrunner-0.1.0/src/showrunner/ui.py +191 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: showrunner
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A collection of tools for live performances including script parsing, cue management, and more.
|
|
5
|
+
Requires-Dist: fastapi>=0.135.2
|
|
6
|
+
Requires-Dist: nicegui>=2.0
|
|
7
|
+
Requires-Dist: pluggy>=1.6.0
|
|
8
|
+
Requires-Dist: screenplay-tools>=0.0.10
|
|
9
|
+
Requires-Dist: sqlmodel>=0.0.37
|
|
10
|
+
Requires-Dist: watchfiles>=1.0.0
|
|
11
|
+
Requires-Dist: sqladmin>=0.20.1 ; extra == 'admin'
|
|
12
|
+
Requires-Dist: showrunner[admin] ; extra == 'all'
|
|
13
|
+
Requires-Dist: showrunner[cli] ; extra == 'all'
|
|
14
|
+
Requires-Dist: showrunner[pdf] ; extra == 'all'
|
|
15
|
+
Requires-Dist: typer>=0.24.1 ; extra == 'cli'
|
|
16
|
+
Requires-Dist: fpdf2>=2.8.7 ; extra == 'pdf'
|
|
17
|
+
Requires-Python: >=3.10, <4.0
|
|
18
|
+
Provides-Extra: admin
|
|
19
|
+
Provides-Extra: all
|
|
20
|
+
Provides-Extra: cli
|
|
21
|
+
Provides-Extra: pdf
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# ShowRunner
|
|
25
|
+
|
|
26
|
+
An application to help running live shows!
|
|
27
|
+
|
|
28
|
+
## About
|
|
29
|
+
|
|
30
|
+
**ShowRunner** is a collection of tools for live performances including script parsing, cue management, and more. It is built using Python and is designed to be flexible, extensible, and powerful for stage managers, designers, directors, and crew members involved in live productions.
|
|
31
|
+
|
|
32
|
+
## Documentation
|
|
33
|
+
|
|
34
|
+
Documentation can be found in the `docs/` directory, or available online: [quaternionmedia.github.io/ShowRunner/](https://quaternionmedia.github.io/ShowRunner/)
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
### Install with pip
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install showrunner[all]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The `[all]` extra includes optional dependencies for the admin panel, CLI, and other tools. You can also install just the core API with `pip install showrunner` and add extras as needed.
|
|
45
|
+
|
|
46
|
+
### Install from source
|
|
47
|
+
|
|
48
|
+
Requires [uv](https://docs.astral.sh/uv/)
|
|
49
|
+
|
|
50
|
+
#### Clone the repo
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
git clone https://github.com/quaternionmedia/ShowRunner.git
|
|
54
|
+
cd ShowRunner
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
#### Create a virtual environment (recommended)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
uv venv
|
|
61
|
+
# Activate the virtual environment:
|
|
62
|
+
source .venv/bin/activate
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
If you are not using a virtual environment, run commands with `uv run [cmd]`
|
|
66
|
+
|
|
67
|
+
#### Install dependencies
|
|
68
|
+
|
|
69
|
+
Including dev tools and optional extras (admin panel, CLI, etc.)
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
uv sync --all-extras
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Start the API server
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
sr start
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Visit [http://localhost:8000](http://localhost:8000) to access the dashboard and tools.
|
|
82
|
+
|
|
83
|
+
Use `sr --help` for CLI options and `sr [tool] --help` for tool-specific commands.
|
|
84
|
+
|
|
85
|
+
## Tools
|
|
86
|
+
|
|
87
|
+
- **ShowDashboard**: Show selector and control dashboard mounted at [/](http://localhost:8000/)
|
|
88
|
+
- **ShowScripter**: Script viewer (PDF, Fountain, etc.) with inline cue placement mounted at [/script](http://localhost:8000/script)
|
|
89
|
+
- **ShowAdmin**: Web-based database admin panel mounted at [/admin](http://localhost:8000/admin) _(requires `admin` group)_
|
|
90
|
+
- **ShowDesigner**: Allows users to design cues based on the parsed script, including setting up cue layers for specific integration with other tools
|
|
91
|
+
- **ShowProgrammer**: Synchronization with QLab and other tools to automatically create and label cues from a script
|
|
92
|
+
- **ShowMixer**: Operates sound mixers to monitor and control channels and effects during a performance (Behringer, Allen & Heath, etc.)
|
|
93
|
+
- **ShowLighter**: Integrates cues directly with lighting control systems for design and performance (ETC Eos, Chamsys, MA Lighting, etc.)
|
|
94
|
+
- **ShowManager**: Designed for Stage Managers to manage cues during a live performance, including triggering cues
|
|
95
|
+
- **ShowStopper**: A stopwatch with helpful features for live performances, such as logging and cue timing
|
|
96
|
+
- **ShowPrompter**: A teleprompter application that can display scripts and cues for performers and crew
|
|
97
|
+
- **ShowComms**: A communication tool for crew members to coordinate during a performance, including messaging and cue notifications
|
|
98
|
+
- **ShowCmd**: A command-line interface to interact with the system with a CLI or TUI
|
|
99
|
+
- **ShowRecorder**: A tool for archiving, annotating, and reviewing rehearsals and performances, including cue logs and performance notes
|
|
100
|
+
|
|
101
|
+
## Contributing
|
|
102
|
+
|
|
103
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for dev setup, testing, linting, and plugin authoring guidelines.
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
uv run pytest # run tests
|
|
107
|
+
uv run ruff check . # lint
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Credit
|
|
111
|
+
|
|
112
|
+
Designed and developed by [Quaternion Media](https://quaternion.media)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# ShowRunner
|
|
2
|
+
|
|
3
|
+
An application to help running live shows!
|
|
4
|
+
|
|
5
|
+
## About
|
|
6
|
+
|
|
7
|
+
**ShowRunner** is a collection of tools for live performances including script parsing, cue management, and more. It is built using Python and is designed to be flexible, extensible, and powerful for stage managers, designers, directors, and crew members involved in live productions.
|
|
8
|
+
|
|
9
|
+
## Documentation
|
|
10
|
+
|
|
11
|
+
Documentation can be found in the `docs/` directory, or available online: [quaternionmedia.github.io/ShowRunner/](https://quaternionmedia.github.io/ShowRunner/)
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### Install with pip
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install showrunner[all]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The `[all]` extra includes optional dependencies for the admin panel, CLI, and other tools. You can also install just the core API with `pip install showrunner` and add extras as needed.
|
|
22
|
+
|
|
23
|
+
### Install from source
|
|
24
|
+
|
|
25
|
+
Requires [uv](https://docs.astral.sh/uv/)
|
|
26
|
+
|
|
27
|
+
#### Clone the repo
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
git clone https://github.com/quaternionmedia/ShowRunner.git
|
|
31
|
+
cd ShowRunner
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
#### Create a virtual environment (recommended)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
uv venv
|
|
38
|
+
# Activate the virtual environment:
|
|
39
|
+
source .venv/bin/activate
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
If you are not using a virtual environment, run commands with `uv run [cmd]`
|
|
43
|
+
|
|
44
|
+
#### Install dependencies
|
|
45
|
+
|
|
46
|
+
Including dev tools and optional extras (admin panel, CLI, etc.)
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
uv sync --all-extras
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Start the API server
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
sr start
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Visit [http://localhost:8000](http://localhost:8000) to access the dashboard and tools.
|
|
59
|
+
|
|
60
|
+
Use `sr --help` for CLI options and `sr [tool] --help` for tool-specific commands.
|
|
61
|
+
|
|
62
|
+
## Tools
|
|
63
|
+
|
|
64
|
+
- **ShowDashboard**: Show selector and control dashboard mounted at [/](http://localhost:8000/)
|
|
65
|
+
- **ShowScripter**: Script viewer (PDF, Fountain, etc.) with inline cue placement mounted at [/script](http://localhost:8000/script)
|
|
66
|
+
- **ShowAdmin**: Web-based database admin panel mounted at [/admin](http://localhost:8000/admin) _(requires `admin` group)_
|
|
67
|
+
- **ShowDesigner**: Allows users to design cues based on the parsed script, including setting up cue layers for specific integration with other tools
|
|
68
|
+
- **ShowProgrammer**: Synchronization with QLab and other tools to automatically create and label cues from a script
|
|
69
|
+
- **ShowMixer**: Operates sound mixers to monitor and control channels and effects during a performance (Behringer, Allen & Heath, etc.)
|
|
70
|
+
- **ShowLighter**: Integrates cues directly with lighting control systems for design and performance (ETC Eos, Chamsys, MA Lighting, etc.)
|
|
71
|
+
- **ShowManager**: Designed for Stage Managers to manage cues during a live performance, including triggering cues
|
|
72
|
+
- **ShowStopper**: A stopwatch with helpful features for live performances, such as logging and cue timing
|
|
73
|
+
- **ShowPrompter**: A teleprompter application that can display scripts and cues for performers and crew
|
|
74
|
+
- **ShowComms**: A communication tool for crew members to coordinate during a performance, including messaging and cue notifications
|
|
75
|
+
- **ShowCmd**: A command-line interface to interact with the system with a CLI or TUI
|
|
76
|
+
- **ShowRecorder**: A tool for archiving, annotating, and reviewing rehearsals and performances, including cue logs and performance notes
|
|
77
|
+
|
|
78
|
+
## Contributing
|
|
79
|
+
|
|
80
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for dev setup, testing, linting, and plugin authoring guidelines.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
uv run pytest # run tests
|
|
84
|
+
uv run ruff check . # lint
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Credit
|
|
88
|
+
|
|
89
|
+
Designed and developed by [Quaternion Media](https://quaternion.media)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "showrunner"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "A collection of tools for live performances including script parsing, cue management, and more."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10,<4.0"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"fastapi>=0.135.2",
|
|
9
|
+
"nicegui>=2.0",
|
|
10
|
+
"pluggy>=1.6.0",
|
|
11
|
+
"screenplay-tools>=0.0.10",
|
|
12
|
+
"sqlmodel>=0.0.37",
|
|
13
|
+
"watchfiles>=1.0.0",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[project.scripts]
|
|
17
|
+
sr = "showrunner.cli:cli"
|
|
18
|
+
|
|
19
|
+
[project.optional-dependencies]
|
|
20
|
+
admin = ["sqladmin>=0.20.1"]
|
|
21
|
+
cli = ["typer>=0.24.1"]
|
|
22
|
+
pdf = ["fpdf2>=2.8.7"]
|
|
23
|
+
all = ["showrunner[admin]", "showrunner[cli]", "showrunner[pdf]"]
|
|
24
|
+
|
|
25
|
+
[dependency-groups]
|
|
26
|
+
dev = ["black>=26.3.1", "pytest>=9.0.2", "ruff>=0.15.8", "uvicorn>=0.42.0"]
|
|
27
|
+
docs = ["zensical>=0.0.31"]
|
|
28
|
+
|
|
29
|
+
[tool.pytest.ini_options]
|
|
30
|
+
testpaths = ["tests"]
|
|
31
|
+
addopts = "-v --tb=short"
|
|
32
|
+
|
|
33
|
+
[tool.ruff]
|
|
34
|
+
line-length = 100
|
|
35
|
+
|
|
36
|
+
[tool.ruff.lint]
|
|
37
|
+
select = ["E", "F", "W", "I"]
|
|
38
|
+
|
|
39
|
+
[tool.ruff.lint.per-file-ignores]
|
|
40
|
+
# Plugins are loaded in dependency order (DB before Admin/Dashboard), not alphabetically.
|
|
41
|
+
"src/showrunner/plugins/__init__.py" = ["I001"]
|
|
42
|
+
# Inline JS strings in the scripter UI are intentionally long.
|
|
43
|
+
"src/showrunner/plugins/scripter.py" = ["E501"]
|
|
44
|
+
|
|
45
|
+
[build-system]
|
|
46
|
+
requires = ["uv_build>=0.11.2,<0.12"]
|
|
47
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""ShowRunner - A collection of tools for live performances."""
|
|
2
|
+
|
|
3
|
+
import pluggy
|
|
4
|
+
|
|
5
|
+
# hookimpl must be defined before importing ShowRunner (which transitively
|
|
6
|
+
# imports plugins that do ``import showrunner; showrunner.hookimpl``).
|
|
7
|
+
hookimpl = pluggy.HookimplMarker("showrunner")
|
|
8
|
+
"""Marker to be used in plugin hook implementations."""
|
|
9
|
+
|
|
10
|
+
from .app import ShowRunner # noqa: E402
|
|
11
|
+
|
|
12
|
+
__all__ = ["hookimpl", "ShowRunner"]
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""ShowRunner core application.
|
|
2
|
+
|
|
3
|
+
Manages the plugin lifecycle and wires plugins into the FastAPI application.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import inspect
|
|
9
|
+
import logging
|
|
10
|
+
from importlib.metadata import entry_points
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
import pluggy
|
|
14
|
+
from fastapi import FastAPI
|
|
15
|
+
|
|
16
|
+
from . import plugins
|
|
17
|
+
from .config import ConfigWatcher, ShowRunnerConfig, load_config
|
|
18
|
+
from .hookspecs import ShowRunnerSpec
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_plugin_manager(
|
|
24
|
+
config: ShowRunnerConfig | None = None,
|
|
25
|
+
) -> pluggy.PluginManager:
|
|
26
|
+
"""Create and configure a PluginManager with built-in plugins loaded.
|
|
27
|
+
|
|
28
|
+
Plugins whose name (case-insensitive) appears in
|
|
29
|
+
``config.plugins.disabled`` are skipped.
|
|
30
|
+
"""
|
|
31
|
+
pm = pluggy.PluginManager("showrunner")
|
|
32
|
+
pm.add_hookspecs(ShowRunnerSpec)
|
|
33
|
+
|
|
34
|
+
disabled = set()
|
|
35
|
+
if config is not None:
|
|
36
|
+
disabled = {n.lower() for n in config.plugins.disabled}
|
|
37
|
+
|
|
38
|
+
# Register all built-in plugins
|
|
39
|
+
for plugin_class in plugins.get_builtin_plugins():
|
|
40
|
+
name = plugin_class.__name__.lower()
|
|
41
|
+
if name in disabled:
|
|
42
|
+
logger.info("Skipping disabled plugin %s", plugin_class.__name__)
|
|
43
|
+
continue
|
|
44
|
+
pm.register(plugin_class())
|
|
45
|
+
|
|
46
|
+
# Discover external plugins installed via setuptools entry points.
|
|
47
|
+
# We load them manually (instead of pm.load_setuptools_entrypoints)
|
|
48
|
+
# so that entry points pointing to a class are instantiated first —
|
|
49
|
+
# pluggy requires hook methods to be bound (i.e. on an instance).
|
|
50
|
+
for ep in entry_points(group="showrunner"):
|
|
51
|
+
if pm.get_plugin(ep.name) is not None:
|
|
52
|
+
continue
|
|
53
|
+
plugin = ep.load()
|
|
54
|
+
if inspect.isclass(plugin):
|
|
55
|
+
plugin = plugin()
|
|
56
|
+
name = getattr(plugin, "__name__", type(plugin).__name__).lower()
|
|
57
|
+
if name in disabled:
|
|
58
|
+
logger.info("Skipping disabled external plugin %s", name)
|
|
59
|
+
continue
|
|
60
|
+
pm.register(plugin, name=ep.name)
|
|
61
|
+
|
|
62
|
+
return pm
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class ShowRunner:
|
|
66
|
+
"""Main ShowRunner application.
|
|
67
|
+
|
|
68
|
+
Holds the plugin manager and the FastAPI app instance.
|
|
69
|
+
Provides lifecycle management for all registered plugins.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
def __init__(self, config_path: Path | None = None) -> None:
|
|
73
|
+
self.config = load_config(config_path)
|
|
74
|
+
self._config_path = config_path or self.config._source_path
|
|
75
|
+
|
|
76
|
+
# Configure logging from show.toml unless already set by the CLI.
|
|
77
|
+
# basicConfig is a no-op when handlers already exist, so CLI
|
|
78
|
+
# flags (--log-level, --verbose, --quiet) take precedence.
|
|
79
|
+
logging.basicConfig(
|
|
80
|
+
level=self.config.logging.level.upper(),
|
|
81
|
+
format="%(levelname)-8s %(name)s: %(message)s",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
self.pm = get_plugin_manager(self.config)
|
|
85
|
+
self._config_watcher: ConfigWatcher | None = None
|
|
86
|
+
self.api = FastAPI(title="ShowRunner", version="0.1.0", docs_url="/api")
|
|
87
|
+
self._mount_routes()
|
|
88
|
+
|
|
89
|
+
def _mount_routes(self) -> None:
|
|
90
|
+
"""Collect APIRouters from all plugins and include them in the FastAPI app."""
|
|
91
|
+
routers = self.pm.hook.showrunner_get_routes()
|
|
92
|
+
for router in routers:
|
|
93
|
+
if router is not None:
|
|
94
|
+
self.api.include_router(router)
|
|
95
|
+
|
|
96
|
+
def startup(self) -> None:
|
|
97
|
+
"""Invoke the startup hook on all plugins and start the config watcher."""
|
|
98
|
+
self.pm.hook.showrunner_startup(app=self)
|
|
99
|
+
|
|
100
|
+
if self._config_path is not None:
|
|
101
|
+
self._config_watcher = ConfigWatcher(self._config_path, self)
|
|
102
|
+
self._config_watcher.start()
|
|
103
|
+
logger.info("Watching %s for changes", self._config_path)
|
|
104
|
+
print(f" Config: {self._config_path} (watching for changes)")
|
|
105
|
+
|
|
106
|
+
def shutdown(self) -> None:
|
|
107
|
+
"""Invoke the shutdown hook on all plugins and stop the config watcher."""
|
|
108
|
+
if self._config_watcher is not None:
|
|
109
|
+
self._config_watcher.stop()
|
|
110
|
+
self._config_watcher = None
|
|
111
|
+
self.pm.hook.showrunner_shutdown(app=self)
|
|
112
|
+
|
|
113
|
+
def list_plugins(self) -> list[dict]:
|
|
114
|
+
"""Return metadata from all registered plugins."""
|
|
115
|
+
return self.pm.hook.showrunner_register()
|
|
116
|
+
|
|
117
|
+
def list_commands(self) -> list[dict]:
|
|
118
|
+
"""Collect CLI commands from all plugins."""
|
|
119
|
+
results = self.pm.hook.showrunner_get_commands()
|
|
120
|
+
# Flatten the list-of-lists into a single list
|
|
121
|
+
return [cmd for group in results if group for cmd in group]
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _create_app() -> FastAPI:
|
|
125
|
+
"""Create and start a ShowRunner instance, returning its FastAPI app.
|
|
126
|
+
|
|
127
|
+
Used as the ASGI entry point for ``uvicorn showrunner.app:app --reload``.
|
|
128
|
+
"""
|
|
129
|
+
show = ShowRunner()
|
|
130
|
+
show.startup()
|
|
131
|
+
return show.api
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def __getattr__(name: str):
|
|
135
|
+
if name == "app":
|
|
136
|
+
globals()["app"] = _create_app()
|
|
137
|
+
return globals()["app"]
|
|
138
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|