CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-dagster-webserver

Web UI server for Dagster, providing GraphQL API, asset reporting, and browser-based interface for data orchestration platform.

Pending
Overview
Eval results
Files

application.mddocs/

Application Factory

Core functionality for creating ASGI applications from workspace contexts. Enables programmatic webserver integration, custom deployment scenarios, and embedding the Dagster UI in larger applications.

Capabilities

Application Creation

Main factory function for creating Starlette ASGI applications with full Dagster webserver functionality.

def create_app_from_workspace_process_context(
    workspace_process_context: IWorkspaceProcessContext,
    path_prefix: str = "",
    live_data_poll_rate: Optional[int] = None,
    **kwargs
) -> Starlette:
    """
    Create a Starlette ASGI application from workspace process context.
    
    Args:
        workspace_process_context: The workspace context containing instance and code locations
        path_prefix: URL path prefix for hosting (must start with '/' if provided)
        live_data_poll_rate: Rate in milliseconds for UI to poll for live data updates
        **kwargs: Additional arguments passed to Starlette constructor
    
    Returns:
        Starlette: ASGI application ready for deployment
        
    Raises:
        Exception: If path_prefix doesn't start with '/' or ends with '/'
    """

Usage Examples:

from dagster import DagsterInstance
from dagster._core.workspace.context import WorkspaceProcessContext
from dagster_webserver.app import create_app_from_workspace_process_context
import uvicorn

# Basic usage
instance = DagsterInstance.get()
with WorkspaceProcessContext(instance) as workspace_context:
    app = create_app_from_workspace_process_context(workspace_context)
    uvicorn.run(app, host="127.0.0.1", port=3000)

# With path prefix for reverse proxy
with WorkspaceProcessContext(instance) as workspace_context:
    app = create_app_from_workspace_process_context(
        workspace_context,
        path_prefix="/dagster"
    )
    uvicorn.run(app, host="0.0.0.0", port=8080)

# With custom live data polling
with WorkspaceProcessContext(instance) as workspace_context:
    app = create_app_from_workspace_process_context(
        workspace_context,
        live_data_poll_rate=5000  # 5 second polling
    )
    uvicorn.run(app)

# With custom Starlette options
with WorkspaceProcessContext(instance) as workspace_context:
    app = create_app_from_workspace_process_context(
        workspace_context,
        debug=True,
        middleware=[custom_middleware]
    )

ASGI Integration

The created application is a standard ASGI app compatible with various deployment scenarios:

# Gunicorn deployment
# gunicorn -w 4 -k uvicorn.workers.UvicornWorker myapp:app

# FastAPI integration
from fastapi import FastAPI
from fastapi.middleware.wsgi import WSGIMiddleware

main_app = FastAPI()
dagster_app = create_app_from_workspace_process_context(workspace_context, path_prefix="/dagster")
main_app.mount("/dagster", dagster_app)

# Custom ASGI server
import hypercorn.asyncio
import hypercorn.config

config = hypercorn.config.Config()
config.bind = ["0.0.0.0:3000"]
asyncio.run(hypercorn.asyncio.serve(app, config))

Workspace Context Management

The application factory works with various workspace context types:

from dagster._core.workspace.context import WorkspaceProcessContext
from dagster_webserver.debug import WebserverDebugWorkspaceProcessContext

# Standard workspace context
instance = DagsterInstance.get()
with WorkspaceProcessContext(
    instance,
    workspace_load_target=workspace_load_target,
    version="1.11.8"
) as workspace_context:
    app = create_app_from_workspace_process_context(workspace_context)

# Debug workspace context with ephemeral instance
debug_instance = DagsterInstance.ephemeral(preload=debug_payloads)
with WebserverDebugWorkspaceProcessContext(debug_instance) as debug_context:
    app = create_app_from_workspace_process_context(debug_context)

# Read-only workspace context
with WorkspaceProcessContext(
    instance,
    workspace_load_target=workspace_load_target,
    read_only=True
) as readonly_context:
    app = create_app_from_workspace_process_context(readonly_context)

Path Prefix Configuration

Path prefixes enable hosting Dagster UI under subpaths for reverse proxy scenarios:

# Valid path prefix examples
app = create_app_from_workspace_process_context(workspace_context, path_prefix="/dagster")
app = create_app_from_workspace_process_context(workspace_context, path_prefix="/my-org/dagster-ui")

# Invalid path prefixes (will raise exceptions)
# path_prefix="dagster"        # Missing leading slash
# path_prefix="/dagster/"      # Trailing slash not allowed

Live Data Configuration

Control how frequently the UI polls for live data updates:

# Fast polling for development (1 second)
app = create_app_from_workspace_process_context(
    workspace_context,
    live_data_poll_rate=1000
)

# Slow polling for resource conservation (10 seconds) 
app = create_app_from_workspace_process_context(
    workspace_context,
    live_data_poll_rate=10000
)

# Default polling (2 seconds)
app = create_app_from_workspace_process_context(workspace_context)

Deployment Patterns

Container Deployment

# Dockerfile application
from dagster import DagsterInstance
from dagster._core.workspace.context import WorkspaceProcessContext  
from dagster_webserver.app import create_app_from_workspace_process_context

instance = DagsterInstance.from_config("/app/dagster.yaml")
with WorkspaceProcessContext(instance) as workspace_context:
    app = create_app_from_workspace_process_context(
        workspace_context,
        path_prefix=os.getenv("DAGSTER_PATH_PREFIX", "")
    )

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("app:app", host="0.0.0.0", port=3000)

Kubernetes Deployment

# Health check endpoint can be added via custom middleware
from starlette.responses import JSONResponse
from starlette.middleware.base import BaseHTTPMiddleware

class HealthCheckMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        if request.url.path == "/health":
            return JSONResponse({"status": "healthy"})
        return await call_next(request)

app = create_app_from_workspace_process_context(
    workspace_context,
    middleware=[HealthCheckMiddleware]
)

Multi-Instance Deployment

# Multiple instances with different configurations
apps = {}

for config_name, instance_config in instance_configs.items():
    instance = DagsterInstance.from_config(instance_config)
    with WorkspaceProcessContext(instance) as workspace_context:
        apps[config_name] = create_app_from_workspace_process_context(
            workspace_context,
            path_prefix=f"/{config_name}"
        )

# Mount in main application
from starlette.applications import Starlette
from starlette.routing import Mount

main_app = Starlette(routes=[
    Mount(f"/{name}", app) for name, app in apps.items()
])

Error Handling

The application factory performs validation and provides clear error messages:

# Path prefix validation
try:
    app = create_app_from_workspace_process_context(
        workspace_context,
        path_prefix="invalid-prefix"  # Missing leading slash
    )
except Exception as e:
    print(f"Configuration error: {e}")

# Workspace context validation  
try:
    app = create_app_from_workspace_process_context(None)
except Exception as e:
    print(f"Invalid workspace context: {e}")

Integration Helpers

The application supports various integration scenarios through additional configuration:

# Custom middleware integration
custom_middleware = [
    Middleware(CustomAuthMiddleware),
    Middleware(CORSMiddleware, allow_origins=["*"])
]

app = create_app_from_workspace_process_context(
    workspace_context,
    middleware=custom_middleware
)

# Exception handling
from starlette.exceptions import HTTPException
from starlette.responses import JSONResponse

async def http_exception_handler(request, exc):
    return JSONResponse(
        {"error": str(exc.detail)},
        status_code=exc.status_code
    )

app = create_app_from_workspace_process_context(
    workspace_context,
    exception_handlers={HTTPException: http_exception_handler}
)

Install with Tessl CLI

npx tessl i tessl/pypi-dagster-webserver

docs

application.md

asset-reporting.md

cli.md

debug.md

graphql.md

index.md

tile.json