Expand source code
from __future__ import annotations
import click
from importlib_metadata import version
from textual._import_app import import_app, AppFail
@click.group()
@click.version_option(version("textual"))
def run():
pass
@run.command(help="Run the Textual Devtools console.")
@click.option("-v", "verbose", help="Enable verbose logs.", is_flag=True)
@click.option("-x", "--exclude", "exclude", help="Exclude log group(s)", multiple=True)
def console(verbose: bool, exclude: list[str]) -> None:
"""Launch the textual console."""
from rich.console import Console
from textual.devtools.server import _run_devtools
console = Console()
console.clear()
console.show_cursor(False)
try:
_run_devtools(verbose=verbose, exclude=exclude)
finally:
console.show_cursor(True)
@run.command(
"run",
context_settings={
"ignore_unknown_options": True,
},
)
@click.argument("import_name", metavar="FILE or FILE:APP")
@click.option("--dev", "dev", help="Enable development mode", is_flag=True)
@click.option("--press", "press", help="Comma separated keys to simulate press")
def run_app(import_name: str, dev: bool, press: str) -> None:
"""Run a Textual app.
The code to run may be given as a path (ending with .py) or as a Python
import, which will load the code and run an app called "app". You may optionally
add a colon plus the class or class instance you want to run.
Here are some examples:
textual run foo.py
textual run foo.py:MyApp
textual run module.foo
textual run module.foo:MyApp
If you are running a file and want to pass command line arguments, wrap the filename and arguments
in quotes:
textual run "foo.py arg --option"
"""
import os
import sys
from textual.features import parse_features
features = set(parse_features(os.environ.get("TEXTUAL", "")))
if dev:
features.add("debug")
features.add("devtools")
os.environ["TEXTUAL"] = ",".join(sorted(features))
try:
app = import_app(import_name)
except AppFail as error:
from rich.console import Console
console = Console(stderr=True)
console.print(str(error))
sys.exit(1)
press_keys = press.split(",") if press else None
result = app.run(press=press_keys)
if result is not None:
from rich.console import Console
from rich.pretty import Pretty
console = Console()
console.print("[b]The app returned:")
console.print(Pretty(result))
@run.command("borders")
def borders():
"""Explore the border styles available in Textual."""
from textual.cli.previews import borders
borders.app.run()
@run.command("easing")
def easing():
"""Explore the animation easing functions available in Textual."""
from textual.cli.previews import easing
easing.app.run()
@run.command("colors")
def colors():
"""Explore the design system."""
from textual.cli.previews import colors
colors.app.run()