MCPcopy
hub / github.com/encode/starlette / Mount

Class Mount

starlette/routing.py:359–456  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

357
358
359class Mount(BaseRoute):
360 def __init__(
361 self,
362 path: str,
363 app: ASGIApp | None = None,
364 routes: Sequence[BaseRoute] | None = None,
365 name: str | None = None,
366 *,
367 middleware: Sequence[Middleware] | None = None,
368 ) -> None:
369 assert path == "" or path.startswith("/"), "Routed paths must start with '/'"
370 assert app is not None or routes is not None, "Either 'app=...', or 'routes=' must be specified"
371 self.path = path.rstrip("/")
372 if app is not None:
373 self._base_app: ASGIApp = app
374 else:
375 self._base_app = Router(routes=routes)
376 self.app = self._base_app
377 if middleware is not None:
378 for cls, args, kwargs in reversed(middleware):
379 self.app = cls(self.app, *args, **kwargs)
380 self.name = name
381 self.path_regex, self.path_format, self.param_convertors = compile_path(self.path + "/{path:path}")
382
383 @property
384 def routes(self) -> list[BaseRoute]:
385 return getattr(self._base_app, "routes", [])
386
387 def matches(self, scope: Scope) -> tuple[Match, Scope]:
388 path_params: dict[str, Any]
389 if scope["type"] in ("http", "websocket"): # pragma: no branch
390 root_path = scope.get("root_path", "")
391 route_path = get_route_path(scope)
392 match = self.path_regex.match(route_path)
393 if match:
394 matched_params = match.groupdict()
395 for key, value in matched_params.items():
396 matched_params[key] = self.param_convertors[key].convert(value)
397 remaining_path = "/" + matched_params.pop("path")
398 matched_path = route_path[: -len(remaining_path)]
399 path_params = dict(scope.get("path_params", {}))
400 path_params.update(matched_params)
401 child_scope = {
402 "path_params": path_params,
403 # app_root_path will only be set at the top level scope,
404 # initialized with the (optional) value of a root_path
405 # set above/before Starlette. And even though any
406 # mount will have its own child scope with its own respective
407 # root_path, the app_root_path will always be available in all
408 # the child scopes with the same top level value because it's
409 # set only once here with a default, any other child scope will
410 # just inherit that app_root_path default value stored in the
411 # scope. All this is needed to support Request.url_for(), as it
412 # uses the app_root_path to build the URL path.
413 "app_root_path": scope.get("app_root_path", root_path),
414 "root_path": root_path + matched_path,
415 "endpoint": self.app,
416 }

Callers 15

test_schemas.pyFile · 0.90
test_routesFunction · 0.90
test_app_mountFunction · 0.90
test_routing.pyFile · 0.90
test_mount_urlsFunction · 0.90
test_reverse_mount_urlsFunction · 0.90
test_mount_at_rootFunction · 0.90

Calls

no outgoing calls

Tested by 15

test_routesFunction · 0.72
test_app_mountFunction · 0.72
test_mount_urlsFunction · 0.72
test_reverse_mount_urlsFunction · 0.72
test_mount_at_rootFunction · 0.72
test_mount_reprFunction · 0.72
test_mount_named_reprFunction · 0.72