Пример #1
0
def test_compute_log_subscription(mock_watch_completed):
    mock_watch_completed.return_value = False

    schema = create_schema()
    server = DagsterSubscriptionServer(schema=schema)

    with instance_for_test() as instance:
        run = execute_pipeline(example_pipeline, instance=instance)
        assert run.success
        assert run.run_id

        with create_subscription_context(instance) as context:
            start_subscription(
                server,
                context,
                COMPUTE_LOG_SUBSCRIPTION,
                {
                    "runId": run.run_id,
                    "stepKey": "example_solid",
                    "ioType": "STDERR",
                },
            )
            gc.collect()
            assert len(objgraph.by_type("SubscriptionObserver")) == 1
            assert len(objgraph.by_type("ComputeLogSubscription")) == 1
            end_subscription(server, context)
            gc.collect()
            assert len(objgraph.by_type("SubscriptionObserver")) == 0
            assert len(objgraph.by_type("ComputeLogSubscription")) == 0
Пример #2
0
def create_app_from_workspace(workspace: Workspace,
                              instance: DagsterInstance,
                              path_prefix: str = ""):
    check.inst_param(workspace, "workspace", Workspace)
    check.inst_param(instance, "instance", DagsterInstance)
    check.str_param(path_prefix, "path_prefix")

    if path_prefix:
        if not path_prefix.startswith("/"):
            raise Exception(
                f'The path prefix should begin with a leading "/": got {path_prefix}'
            )
        if path_prefix.endswith("/"):
            raise Exception(
                f'The path prefix should not include a trailing "/": got {path_prefix}'
            )

    warn_if_compute_logs_disabled()

    print("Loading repository...")  # pylint: disable=print-call

    context = WorkspaceProcessContext(instance=instance,
                                      workspace=workspace,
                                      version=__version__)

    log_workspace_stats(instance, context)

    schema = create_schema()

    return instantiate_app_with_views(context, schema, path_prefix)
Пример #3
0
def create_app_from_workspace_process_context(
    workspace_process_context: WorkspaceProcessContext,
    path_prefix: str = "",
) -> Flask:
    check.inst_param(workspace_process_context, "workspace_process_context",
                     WorkspaceProcessContext)
    check.str_param(path_prefix, "path_prefix")

    instance = workspace_process_context.instance

    if path_prefix:
        if not path_prefix.startswith("/"):
            raise Exception(
                f'The path prefix should begin with a leading "/": got {path_prefix}'
            )
        if path_prefix.endswith("/"):
            raise Exception(
                f'The path prefix should not include a trailing "/": got {path_prefix}'
            )

    warn_if_compute_logs_disabled()

    log_workspace_stats(instance, workspace_process_context)

    schema = create_schema()

    return instantiate_app_with_views(workspace_process_context,
                                      schema,
                                      path_prefix,
                                      include_notebook_route=True)
Пример #4
0
def create_app(handle, instance):
    check.inst_param(handle, 'handle', ExecutionTargetHandle)
    check.inst_param(instance, 'instance', DagsterInstance)

    app = Flask('dagster-ui')
    sockets = Sockets(app)
    app.app_protocol = lambda environ_path_info: 'graphql-ws'

    schema = create_schema()
    subscription_server = DagsterSubscriptionServer(schema=schema)

    execution_manager = MultiprocessingExecutionManager()

    print('Loading repository...')

    context = DagsterGraphQLContext(handle=handle,
                                    instance=instance,
                                    execution_manager=execution_manager,
                                    version=__version__)

    app.add_url_rule(
        '/graphql',
        'graphql',
        DagsterGraphQLView.as_view(
            'graphql',
            schema=schema,
            graphiql=True,
            # XXX(freiksenet): Pass proper ws url
            graphiql_template=PLAYGROUND_TEMPLATE,
            executor=Executor(),
            context=context,
        ),
    )
    sockets.add_url_rule(
        '/graphql', 'graphql',
        dagster_graphql_subscription_view(subscription_server, context))

    app.add_url_rule(
        # should match the `build_local_download_url`
        '/download/<string:run_id>/<string:step_key>/<string:file_type>',
        'download_view',
        download_view(context),
    )

    # these routes are specifically for the Dagit UI and are not part of the graphql
    # API that we want other people to consume, so they're separate for now.
    # Also grabbing the magic global request args dict so that notebook_view is testable
    app.add_url_rule('/dagit/notebook', 'notebook',
                     lambda: notebook_view(request.args))

    app.add_url_rule('/static/<path:path>/<string:file>', 'static_view',
                     static_view)
    app.add_url_rule('/vendor/<path:path>/<string:file>', 'vendor_view',
                     vendor_view)
    app.add_url_rule('/<path:_path>', 'index_catchall', index_view)
    app.add_url_rule('/', 'index', index_view, defaults={'_path': ''})

    CORS(app)

    return app
Пример #5
0
def test_event_log_subscription_chunked():
    schema = create_schema()
    server = DagsterSubscriptionServer(schema=schema)

    with instance_for_test() as instance, environ(
        {"DAGIT_EVENT_LOAD_CHUNK_SIZE": "2"}):
        run = execute_pipeline(example_pipeline, instance=instance)
        assert run.success
        assert run.run_id

        with create_subscription_context(instance) as context:
            start_subscription(server, context, EVENT_LOG_SUBSCRIPTION,
                               {"runId": run.run_id})
            gc.collect()
            assert len(objgraph.by_type("SubscriptionObserver")) == 1
            subs = objgraph.by_type("PipelineRunObservableSubscribe")
            assert len(subs) == 1
            subscription_obj = subs[0]
            end_subscription(server, context)
            subscription_obj.stopped.wait(30)
            subs = None
            subscription_obj = None
            gc.collect()

            assert len(objgraph.by_type("SubscriptionObserver")) == 0
            assert len(objgraph.by_type("PipelineRunObservableSubscribe")) == 0
Пример #6
0
def test_execute_hammer_through_dagit():
    handle = ExecutionTargetHandle.for_pipeline_python_file(
        file_relative_path(
            __file__, '../../../../examples/dagster_examples/toys/hammer.py'),
        'hammer_pipeline',
    )
    instance = DagsterInstance.local_temp()

    execution_manager = SubprocessExecutionManager(instance)

    context = DagsterGraphQLInProcessRepositoryContext(
        handle=handle, execution_manager=execution_manager, instance=instance)

    executor = SyncExecutor()

    variables = {
        'executionParams': {
            'environmentConfigData': {
                'storage': {
                    'filesystem': {}
                },
                'execution': {
                    'dask': {}
                }
            },
            'selector': {
                'name': handle.build_pipeline_definition().name
            },
            'mode': 'default',
        }
    }

    start_pipeline_result = graphql(
        request_string=START_PIPELINE_EXECUTION_MUTATION,
        schema=create_schema(),
        context=context,
        variables=variables,
        executor=executor,
    )

    run_id = start_pipeline_result.data['startPipelineExecution']['run'][
        'runId']

    context.execution_manager.join()

    subscription = execute_dagster_graphql(context,
                                           SUBSCRIPTION_QUERY,
                                           variables={'runId': run_id})

    subscribe_results = []
    subscription.subscribe(subscribe_results.append)

    messages = [
        x['__typename']
        for x in subscribe_results[0].data['pipelineRunLogs']['messages']
    ]

    assert 'PipelineStartEvent' in messages
    assert 'PipelineSuccessEvent' in messages
Пример #7
0
def create_app(handle,
               pipeline_run_storage,
               use_synchronous_execution_manager=False):
    check.inst_param(handle, 'handle', ExecutionTargetHandle)
    check.inst_param(pipeline_run_storage, 'pipeline_run_storage',
                     PipelineRunStorage)
    check.bool_param(use_synchronous_execution_manager,
                     'use_synchronous_execution_manager')

    app = Flask('dagster-ui')
    sockets = Sockets(app)
    app.app_protocol = lambda environ_path_info: 'graphql-ws'

    schema = create_schema()
    subscription_server = DagsterSubscriptionServer(schema=schema)

    if use_synchronous_execution_manager:
        execution_manager = SynchronousExecutionManager()
    else:
        execution_manager = MultiprocessingExecutionManager()
    context = DagsterGraphQLContext(
        handle=handle,
        pipeline_runs=pipeline_run_storage,
        execution_manager=execution_manager,
        version=__version__,
    )

    app.add_url_rule(
        '/graphql',
        'graphql',
        DagsterGraphQLView.as_view(
            'graphql',
            schema=schema,
            graphiql=True,
            # XXX(freiksenet): Pass proper ws url
            graphiql_template=PLAYGROUND_TEMPLATE,
            executor=Executor(),
            context=context,
        ),
    )
    sockets.add_url_rule(
        '/graphql', 'graphql',
        dagster_graphql_subscription_view(subscription_server, context))

    # these routes are specifically for the Dagit UI and are not part of the graphql
    # API that we want other people to consume, so they're separate for now.
    # Also grabbing the magic glabl request args dict so that notebook_view is testable
    app.add_url_rule('/dagit/notebook', 'notebook',
                     lambda: notebook_view(request.args))

    app.add_url_rule('/static/<path:path>/<string:file>', 'static_view',
                     static_view)
    app.add_url_rule('/<path:_path>', 'index_catchall', index_view)
    app.add_url_rule('/', 'index', index_view, defaults={'_path': ''})

    CORS(app)

    return app
Пример #8
0
def test_execute_hammer_through_dagit():
    with instance_for_test() as instance:
        with get_workspace_process_context_from_kwargs(
            instance,
            version="",
            read_only=False,
            kwargs={
                "python_file": file_relative_path(
                    __file__, "../../../dagster-test/dagster_test/toys/hammer.py"
                ),
                "attribute": "hammer_pipeline",
            },
        ) as workspace_process_context:
            context = workspace_process_context.create_request_context()
            selector = infer_pipeline_selector(context, "hammer_pipeline")
            executor = SyncExecutor()

            variables = {
                "executionParams": {
                    "runConfigData": {
                        "execution": {"dask": {"config": {"cluster": {"local": {}}}}},
                    },
                    "selector": selector,
                    "mode": "default",
                }
            }

            start_pipeline_result = graphql(
                request_string=LAUNCH_PIPELINE_EXECUTION_MUTATION,
                schema=create_schema(),
                context=context,
                variables=variables,
                executor=executor,
            )

            if start_pipeline_result.errors:
                raise Exception("{}".format(start_pipeline_result.errors))

            run_id = start_pipeline_result.data["launchPipelineExecution"]["run"]["runId"]

            context.instance.run_launcher.join(timeout=60)

            subscription = execute_dagster_graphql(
                context, SUBSCRIPTION_QUERY, variables={"runId": run_id}
            )

            subscribe_results = []
            subscription.subscribe(subscribe_results.append)

            messages = [
                x["__typename"] for x in subscribe_results[0].data["pipelineRunLogs"]["messages"]
            ]

            assert "RunStartEvent" in messages
            assert "RunSuccessEvent" in messages
Пример #9
0
def create_app(
    process_context: WorkspaceProcessContext,
    debug: bool,
    app_path_prefix: str,
):
    graphql_schema = create_schema()
    base_dir = path.dirname(__file__)

    bound_index_endpoint = partial(index_endpoint, base_dir, app_path_prefix)

    return Starlette(
        debug=debug,
        routes=[
            Route("/dagit_info", dagit_info_endpoint),
            Route(
                "/graphql",
                partial(graphql_http_endpoint, graphql_schema, process_context,
                        app_path_prefix),
                name="graphql-http",
                methods=["GET", "POST"],
            ),
            WebSocketRoute(
                "/graphql",
                partial(graphql_ws_endpoint, graphql_schema, process_context),
                name="graphql-ws",
            ),
            # static resources addressed at /static/
            Mount(
                "/static",
                StaticFiles(
                    directory=path.join(base_dir, "./webapp/build/static")),
                name="static",
            ),
            # static resources addressed at /vendor/
            Mount(
                "/vendor",
                StaticFiles(
                    directory=path.join(base_dir, "./webapp/build/vendor")),
                name="vendor",
            ),
            # specific static resources addressed at /
            *create_root_static_endpoints(base_dir),
            # download file endpoints
            Route(
                "/download_debug/{run_id:str}",
                partial(download_debug_file_endpoint, process_context),
            ),
            Route("/{path:path}", bound_index_endpoint),
            Route("/", bound_index_endpoint),
        ],
    )
Пример #10
0
def test_execute_hammer_through_dagit():
    recon_repo = ReconstructableRepository.for_file(
        file_relative_path(__file__, '../../../../examples/dagster_examples/toys/hammer.py'),
        'hammer_pipeline',
    )
    instance = DagsterInstance.local_temp()

    context = DagsterGraphQLContext(
        locations=[InProcessRepositoryLocation(recon_repo)], instance=instance,
    )

    selector = get_legacy_pipeline_selector(context, 'hammer_pipeline')

    executor = SyncExecutor()

    variables = {
        'executionParams': {
            'runConfigData': {
                'storage': {'filesystem': {}},
                'execution': {'dask': {'config': {'cluster': {'local': {}}}}},
            },
            'selector': selector,
            'mode': 'default',
        }
    }

    start_pipeline_result = graphql(
        request_string=START_PIPELINE_EXECUTION_MUTATION,
        schema=create_schema(),
        context=context,
        variables=variables,
        executor=executor,
    )

    if start_pipeline_result.errors:
        raise Exception('{}'.format(start_pipeline_result.errors))

    run_id = start_pipeline_result.data['startPipelineExecution']['run']['runId']

    context.drain_outstanding_executions()

    subscription = execute_dagster_graphql(context, SUBSCRIPTION_QUERY, variables={'runId': run_id})

    subscribe_results = []
    subscription.subscribe(subscribe_results.append)

    messages = [x['__typename'] for x in subscribe_results[0].data['pipelineRunLogs']['messages']]

    assert 'PipelineStartEvent' in messages
    assert 'PipelineSuccessEvent' in messages
Пример #11
0
def instantiate_app_with_views(context):
    app = Flask(
        'dagster-ui',
        static_url_path='',
        static_folder=os.path.join(os.path.dirname(__file__),
                                   './webapp/build'),
    )
    sockets = Sockets(app)
    app.app_protocol = lambda environ_path_info: 'graphql-ws'

    schema = create_schema()
    subscription_server = DagsterSubscriptionServer(schema=schema)

    app.add_url_rule(
        '/graphql',
        'graphql',
        DagsterGraphQLView.as_view(
            'graphql',
            schema=schema,
            graphiql=True,
            # XXX(freiksenet): Pass proper ws url
            graphiql_template=PLAYGROUND_TEMPLATE,
            executor=Executor(),
            context=context,
        ),
    )
    app.add_url_rule('/graphiql', 'graphiql',
                     lambda: redirect('/graphql', 301))
    sockets.add_url_rule(
        '/graphql', 'graphql',
        dagster_graphql_subscription_view(subscription_server, context))

    app.add_url_rule(
        # should match the `build_local_download_url`
        '/download/<string:run_id>/<string:step_key>/<string:file_type>',
        'download_view',
        download_view(context),
    )

    # these routes are specifically for the Dagit UI and are not part of the graphql
    # API that we want other people to consume, so they're separate for now.
    # Also grabbing the magic global request args dict so that notebook_view is testable
    app.add_url_rule('/dagit/notebook', 'notebook',
                     lambda: notebook_view(request.args))

    app.add_url_rule('/dagit_info', 'sanity_view', info_view)
    app.register_error_handler(404, index_view)
    CORS(app)
    return app
Пример #12
0
def create_app(repository_container, pipeline_runs, use_synchronous_execution_manager=False):
    app = Flask('dagster-ui')
    sockets = Sockets(app)
    app.app_protocol = lambda environ_path_info: 'graphql-ws'

    schema = create_schema()
    subscription_server = DagsterSubscriptionServer(schema=schema)

    if use_synchronous_execution_manager:
        execution_manager = SynchronousExecutionManager()
    else:
        execution_manager = MultiprocessingExecutionManager()
    context = DagsterGraphQLContext(
        repository_container=repository_container,
        pipeline_runs=pipeline_runs,
        execution_manager=execution_manager,
        version=__version__,
    )

    app.add_url_rule(
        '/graphql',
        'graphql',
        DagsterGraphQLView.as_view(
            'graphql',
            schema=schema,
            graphiql=True,
            # XXX(freiksenet): Pass proper ws url
            graphiql_template=PLAYGROUND_TEMPLATE,
            executor=Executor(),
            context=context,
        ),
    )
    sockets.add_url_rule(
        '/graphql', 'graphql', dagster_graphql_subscription_view(subscription_server, context)
    )

    # these routes are specifically for the Dagit UI and are not part of the graphql
    # API that we want other people to consume, so they're separate for now.
    app.add_url_rule('/dagit/notebook', 'notebook', notebook_view)

    app.add_url_rule('/static/<path:path>/<string:file>', 'static_view', static_view)
    app.add_url_rule('/<path:_path>', 'index_catchall', index_view)
    app.add_url_rule('/', 'index', index_view, defaults={'_path': ''})

    CORS(app)

    return app
Пример #13
0
def execute_dagster_graphql(context, query, variables=None):
    result = graphql(
        create_schema(),
        query,
        context=context,
        variables=variables,
        # executor=GeventObservableExecutor(),
        allow_subscriptions=True,
        return_promise=False,
    )

    # has to check attr because in subscription case it returns AnonymousObservable
    if hasattr(result, 'errors') and result.errors:
        if result.errors[0].original_error:
            raise result.errors[0].original_error
        else:
            raise result.errors[0]

    return result
Пример #14
0
def execute_dagster_graphql(context, query, variables=None):
    result = graphql(
        create_schema(),
        query,
        context_value=context,
        variable_values=variables,
        allow_subscriptions=True,
        return_promise=False,
    )

    # has to check attr because in subscription case it returns AnonymousObservable
    if hasattr(result, "errors") and result.errors:
        first_error = result.errors[0]
        if hasattr(first_error, "original_error") and first_error.original_error:
            raise result.errors[0].original_error

        raise result.errors[0]

    return result
Пример #15
0
def test_event_log_subscription():
    schema = create_schema()
    server = DagsterSubscriptionServer(schema=schema)

    with instance_for_test() as instance:
        run = execute_pipeline(example_pipeline, instance=instance)
        assert run.success
        assert run.run_id

        with create_subscription_context(instance) as context:
            start_subscription(server, context, EVENT_LOG_SUBSCRIPTION,
                               {"runId": run.run_id})
            gc.collect()
            assert len(objgraph.by_type("SubscriptionObserver")) == 1
            assert len(objgraph.by_type("PipelineRunObservableSubscribe")) == 1
            end_subscription(server, context)
            gc.collect()
            assert len(objgraph.by_type("SubscriptionObserver")) == 0
            assert len(objgraph.by_type("PipelineRunObservableSubscribe")) == 0
Пример #16
0
def get_validator_client() -> Client:
    return Client(schema=create_schema())
Пример #17
0
 def build_graphql_schema(self) -> Schema:
     return create_schema()
Пример #18
0
def test_execute_hammer_through_dagit():
    recon_repo = ReconstructableRepository.for_file(
        file_relative_path(
            __file__, "../../../dagster-test/dagster_test/toys/hammer.py"),
        "hammer_pipeline",
    )
    instance = DagsterInstance.local_temp()

    context = DagsterGraphQLContext(
        workspace=Workspace([
            RepositoryLocationHandle.create_in_process_location(
                recon_repo.pointer)
        ]),
        instance=instance,
    )

    selector = infer_pipeline_selector(context, "hammer_pipeline")

    executor = SyncExecutor()

    variables = {
        "executionParams": {
            "runConfigData": {
                "storage": {
                    "filesystem": {}
                },
                "execution": {
                    "dask": {
                        "config": {
                            "cluster": {
                                "local": {}
                            }
                        }
                    }
                },
            },
            "selector": selector,
            "mode": "default",
        }
    }

    start_pipeline_result = graphql(
        request_string=LAUNCH_PIPELINE_EXECUTION_MUTATION,
        schema=create_schema(),
        context=context,
        variables=variables,
        executor=executor,
    )

    if start_pipeline_result.errors:
        raise Exception("{}".format(start_pipeline_result.errors))

    run_id = start_pipeline_result.data["launchPipelineExecution"]["run"][
        "runId"]

    context.drain_outstanding_executions()

    subscription = execute_dagster_graphql(context,
                                           SUBSCRIPTION_QUERY,
                                           variables={"runId": run_id})

    subscribe_results = []
    subscription.subscribe(subscribe_results.append)

    messages = [
        x["__typename"]
        for x in subscribe_results[0].data["pipelineRunLogs"]["messages"]
    ]

    assert "PipelineStartEvent" in messages
    assert "PipelineSuccessEvent" in messages
Пример #19
0
def instantiate_app_with_views(context, app_path_prefix):
    app = Flask(
        "dagster-ui",
        static_url_path=app_path_prefix,
        static_folder=os.path.join(os.path.dirname(__file__), "./webapp/build"),
    )
    schema = create_schema()
    subscription_server = DagsterSubscriptionServer(schema=schema)

    # Websocket routes
    sockets = Sockets(app)
    sockets.add_url_rule(
        "{}/graphql".format(app_path_prefix),
        "graphql",
        dagster_graphql_subscription_view(subscription_server, context),
    )

    # HTTP routes
    bp = Blueprint("routes", __name__, url_prefix=app_path_prefix)
    bp.add_url_rule(
        "/graphiql", "graphiql", lambda: redirect("{}/graphql".format(app_path_prefix), 301)
    )
    bp.add_url_rule(
        "/graphql",
        "graphql",
        DagsterGraphQLView.as_view(
            "graphql",
            schema=schema,
            graphiql=True,
            graphiql_template=PLAYGROUND_TEMPLATE.replace("APP_PATH_PREFIX", app_path_prefix),
            executor=Executor(),
            context=context,
        ),
    )

    bp.add_url_rule(
        # should match the `build_local_download_url`
        "/download/<string:run_id>/<string:step_key>/<string:file_type>",
        "download_view",
        download_view(context),
    )

    # these routes are specifically for the Dagit UI and are not part of the graphql
    # API that we want other people to consume, so they're separate for now.
    # Also grabbing the magic global request args dict so that notebook_view is testable
    bp.add_url_rule("/dagit/notebook", "notebook", lambda: notebook_view(request.args))
    bp.add_url_rule("/dagit_info", "sanity_view", info_view)

    index_path = os.path.join(os.path.dirname(__file__), "./webapp/build/index.html")

    def index_view(_path):
        try:
            with open(index_path) as f:
                return (
                    f.read()
                    .replace('href="/', 'href="{}/'.format(app_path_prefix))
                    .replace('src="/', 'src="{}/'.format(app_path_prefix))
                    .replace(
                        '<meta name="dagit-path-prefix"',
                        '<meta name="dagit-path-prefix" content="{}"'.format(app_path_prefix),
                    )
                )
        except seven.FileNotFoundError:
            raise Exception(
                """Can't find webapp files. Probably webapp isn't built. If you are using
                dagit, then probably it's a corrupted installation or a bug. However, if you are
                developing dagit locally, your problem can be fixed as follows:

                cd ./python_modules/
                make rebuild_dagit"""
            )

    app.app_protocol = lambda environ_path_info: "graphql-ws"
    app.register_blueprint(bp)
    app.register_error_handler(404, index_view)

    # if the user asked for a path prefix, handle the naked domain just in case they are not
    # filtering inbound traffic elsewhere and redirect to the path prefix.
    if app_path_prefix:
        app.add_url_rule("/", "force-path-prefix", lambda: redirect(app_path_prefix, 301))

    CORS(app)
    return app
Пример #20
0
def create_app(handle, instance, reloader=None):
    check.inst_param(handle, 'handle', ExecutionTargetHandle)
    check.inst_param(instance, 'instance', DagsterInstance)
    check.opt_inst_param(reloader, 'reloader', Reloader)

    app = Flask('dagster-ui')
    sockets = Sockets(app)
    app.app_protocol = lambda environ_path_info: 'graphql-ws'

    schema = create_schema()
    subscription_server = DagsterSubscriptionServer(schema=schema)

    execution_manager_settings = instance.dagit_settings.get(
        'execution_manager')
    if execution_manager_settings and execution_manager_settings.get(
            'max_concurrent_runs'):
        execution_manager = QueueingSubprocessExecutionManager(
            instance, execution_manager_settings.get('max_concurrent_runs'))
    else:
        execution_manager = SubprocessExecutionManager(instance)

    warn_if_compute_logs_disabled()

    print('Loading repository...')
    context = DagsterGraphQLContext(
        handle=handle,
        instance=instance,
        execution_manager=execution_manager,
        reloader=reloader,
        version=__version__,
    )

    # Automatically initialize scheduler everytime Dagit loads
    scheduler_handle = context.scheduler_handle
    scheduler = instance.scheduler

    if scheduler_handle:
        if scheduler:
            handle = context.get_handle()
            python_path = sys.executable
            repository_path = handle.data.repository_yaml
            repository = context.get_repository()
            scheduler_handle.up(python_path,
                                repository_path,
                                repository=repository,
                                instance=instance)
        else:
            warnings.warn(MISSING_SCHEDULER_WARNING)

    app.add_url_rule(
        '/graphql',
        'graphql',
        DagsterGraphQLView.as_view(
            'graphql',
            schema=schema,
            graphiql=True,
            # XXX(freiksenet): Pass proper ws url
            graphiql_template=PLAYGROUND_TEMPLATE,
            executor=Executor(),
            context=context,
        ),
    )
    sockets.add_url_rule(
        '/graphql', 'graphql',
        dagster_graphql_subscription_view(subscription_server, context))

    app.add_url_rule(
        # should match the `build_local_download_url`
        '/download/<string:run_id>/<string:step_key>/<string:file_type>',
        'download_view',
        download_view(context),
    )

    # these routes are specifically for the Dagit UI and are not part of the graphql
    # API that we want other people to consume, so they're separate for now.
    # Also grabbing the magic global request args dict so that notebook_view is testable
    app.add_url_rule('/dagit/notebook', 'notebook',
                     lambda: notebook_view(request.args))

    app.add_url_rule('/static/<path:path>/<string:file>', 'static_view',
                     static_view)
    app.add_url_rule('/vendor/<path:path>/<string:file>', 'vendor_view',
                     vendor_view)
    app.add_url_rule('/<string:worker_name>.worker.js', 'worker_view',
                     worker_view)
    app.add_url_rule('/dagit_info', 'sanity_view', info_view)
    app.add_url_rule('/<path:_path>', 'index_catchall', index_view)
    app.add_url_rule('/', 'index', index_view, defaults={'_path': ''})

    CORS(app)

    return app