---
title: router_serve
---

<div class="python-reference">
<a id="fastvideo.entrypoints.cli.router_serve-classes"></a>
<a id="fastvideo.entrypoints.cli.router_serve-functions"></a>
<a id="fastvideo.entrypoints.cli.router_serve"></a>
<p><code>fastvideo router-serve</code> CLI subcommand.</p>
<p>Launches the streaming router from a YAML config. Separate from
<code>fastvideo serve</code> because the router is an orthogonal process: it
fronts one or more running servers rather than hosting a generator
itself.</p>
<h2 id="fastvideo.entrypoints.cli.router_serve.load_raw_config"><code>fastvideo.entrypoints.cli.router_serve.load_raw_config</code></h2>
<pre class="doc-signature"><code>load_raw_config(path: str | Path) -&gt; dict&#91;str, Any&#93;</code></pre>

<h2 id="fastvideo.entrypoints.cli.router_serve.CLISubcommand"><code>fastvideo.entrypoints.cli.router_serve.CLISubcommand</code></h2>
<pre class="doc-signature"><code>CLISubcommand()</code></pre>
<p>Base class for CLI subcommands</p>
<h3 id="fastvideo.entrypoints.cli.router_serve.CLISubcommand.cmd"><code>fastvideo.entrypoints.cli.router_serve.CLISubcommand.cmd</code></h3>
<pre class="doc-signature"><code>cmd(args: argparse.Namespace) -&gt; None</code></pre>
<p>Execute the command with the given arguments</p>
<h3 id="fastvideo.entrypoints.cli.router_serve.CLISubcommand.validate"><code>fastvideo.entrypoints.cli.router_serve.CLISubcommand.validate</code></h3>
<pre class="doc-signature"><code>validate(args: argparse.Namespace) -&gt; None</code></pre>
<p>Validate the arguments for this command</p>
<h3 id="fastvideo.entrypoints.cli.router_serve.CLISubcommand.subparser_init"><code>fastvideo.entrypoints.cli.router_serve.CLISubcommand.subparser_init</code></h3>
<pre class="doc-signature"><code>subparser_init(subparsers: argparse._SubParsersAction) -&gt; FlexibleArgumentParser</code></pre>
<p>Initialize the subparser for this command</p>
<h2 id="fastvideo.entrypoints.cli.router_serve.ReplicaEndpoint"><code>fastvideo.entrypoints.cli.router_serve.ReplicaEndpoint</code></h2>
<pre class="doc-signature"><code>ReplicaEndpoint(url: str, name: str | None = None, primary: bool = False, weight: float = 1.0)</code></pre>
<p>One backend replica the router can route to.</p>

<h3 id="fastvideo.entrypoints.cli.router_serve.ReplicaEndpoint.url"><code>fastvideo.entrypoints.cli.router_serve.ReplicaEndpoint.url</code></h3>
<pre class="doc-signature"><code>url: str</code></pre>
<p>HTTP base URL, e.g. <code>http://host:8000</code>. WebSocket URL is
derived automatically by replacing the scheme.</p>
<h3 id="fastvideo.entrypoints.cli.router_serve.ReplicaEndpoint.primary"><code>fastvideo.entrypoints.cli.router_serve.ReplicaEndpoint.primary</code></h3>
<pre class="doc-signature"><code>primary: bool = False</code></pre>
<p><code>True</code> = prefer this replica over others in steady state.</p>
<h2 id="fastvideo.entrypoints.cli.router_serve.RouterConfig"><code>fastvideo.entrypoints.cli.router_serve.RouterConfig</code></h2>
<pre class="doc-signature"><code>RouterConfig(host: str = &#x27;0.0.0.0&#x27;, port: int = 9000, replicas: list&#91;ReplicaEndpoint&#93; = list(), health_check_path: str = &#x27;/health&#x27;, health_check_interval_seconds: float = 5.0, health_check_timeout_seconds: float = 2.0, failure_threshold: int = 3, recovery_threshold: int = 2)</code></pre>
<p>Typed router config loaded from a YAML file.</p>
<p>Example::</p>
<pre><code>router:
  host: 0.0.0.0
  port: 9000
  replicas:
    - url: http://streamer-a:8000
      primary: true
    - url: http://streamer-b:8000
  health_check:
    path: /health
    interval_seconds: 5
    failure_threshold: 3
</code></pre>
<p>Validation runs in <code>__post_init__</code>: empty replicas, non-positive
intervals/timeouts, thresholds &lt; 1, non-http(s) URLs, and more than
one primary all raise <code>ValueError</code> so misconfigurations surface at
load time rather than as confusing runtime failures.</p>

<h2 id="fastvideo.entrypoints.cli.router_serve.init_logger"><code>fastvideo.entrypoints.cli.router_serve.init_logger</code></h2>
<pre class="doc-signature"><code>init_logger(name: str) -&gt; _FastvideoLogger</code></pre>
<p>The main purpose of this function is to ensure that loggers are
retrieved in such a way that we can be sure the root fastvideo logger has
already been configured.</p>
<h2 id="fastvideo.entrypoints.cli.router_serve.FlexibleArgumentParser"><code>fastvideo.entrypoints.cli.router_serve.FlexibleArgumentParser</code></h2>
<pre class="doc-signature"><code>FlexibleArgumentParser(*args, **kwargs)</code></pre>
<p>ArgumentParser that allows both underscore and dash in names.</p>

<h3 id="fastvideo.entrypoints.cli.router_serve.FlexibleArgumentParser.parse_args"><code>fastvideo.entrypoints.cli.router_serve.FlexibleArgumentParser.parse_args</code></h3>
<pre class="doc-signature"><code>parse_args(args = None, namespace = None) -&gt; argparse.Namespace</code></pre>

<h3 id="fastvideo.entrypoints.cli.router_serve.FlexibleArgumentParser.parse_known_args"><code>fastvideo.entrypoints.cli.router_serve.FlexibleArgumentParser.parse_known_args</code></h3>
<pre class="doc-signature"><code>parse_known_args(args = None, namespace = None) -&gt; tuple&#91;argparse.Namespace, list&#91;str&#93;&#93;</code></pre>

<h2 id="fastvideo.entrypoints.cli.router_serve.RouterServeSubcommand"><code>fastvideo.entrypoints.cli.router_serve.RouterServeSubcommand</code></h2>
<pre class="doc-signature"><code>RouterServeSubcommand()</code></pre>
<p>Start the multi-replica WebSocket router.</p>

<details><summary>Source</summary><pre><code>class RouterServeSubcommand(CLISubcommand):
    &quot;&quot;&quot;Start the multi-replica WebSocket router.&quot;&quot;&quot;

    def __init__(self) -&gt; None:
        self.name = &quot;router-serve&quot;
        super().__init__()

    def cmd(self, args: argparse.Namespace) -&gt; None:
        config = _load_router_config(args.config)
        logger.info(
            &quot;router listening on %s:%d (%d replicas, %d primary)&quot;,
            config.host,
            config.port,
            len(config.replicas),
            sum(1 for r in config.replicas if r.primary),
        )
        from fastvideo.entrypoints.streaming.router.main import run_router

        run_router(config)

    def validate(self, args: argparse.Namespace) -&gt; None:
        if not args.config:
            raise ValueError(&quot;fastvideo router-serve requires --config PATH&quot;)
        if not os.path.exists(args.config):
            raise ValueError(f&quot;Router config file not found: &#123;args.config&#125;&quot;)

    def subparser_init(
        self,
        subparsers: argparse._SubParsersAction,
    ) -&gt; FlexibleArgumentParser:
        parser = subparsers.add_parser(
            &quot;router-serve&quot;,
            help=&quot;Start the streaming router (multi-replica load balancer)&quot;,
            usage=&quot;fastvideo router-serve --config ROUTER_CONFIG&quot;,
        )
        parser.add_argument(
            &quot;--config&quot;,
            type=str,
            default=&quot;&quot;,
            required=False,
            help=&quot;Path to a YAML/JSON router config. Required.&quot;,
        )
        return cast(FlexibleArgumentParser, parser)</code></pre></details>
<h3 id="fastvideo.entrypoints.cli.router_serve.RouterServeSubcommand.cmd"><code>fastvideo.entrypoints.cli.router_serve.RouterServeSubcommand.cmd</code></h3>
<pre class="doc-signature"><code>cmd(args: argparse.Namespace) -&gt; None</code></pre>

<details><summary>Source</summary><pre><code>def cmd(self, args: argparse.Namespace) -&gt; None:
    config = _load_router_config(args.config)
    logger.info(
        &quot;router listening on %s:%d (%d replicas, %d primary)&quot;,
        config.host,
        config.port,
        len(config.replicas),
        sum(1 for r in config.replicas if r.primary),
    )
    from fastvideo.entrypoints.streaming.router.main import run_router

    run_router(config)</code></pre></details>
<h3 id="fastvideo.entrypoints.cli.router_serve.RouterServeSubcommand.validate"><code>fastvideo.entrypoints.cli.router_serve.RouterServeSubcommand.validate</code></h3>
<pre class="doc-signature"><code>validate(args: argparse.Namespace) -&gt; None</code></pre>

<details><summary>Source</summary><pre><code>def validate(self, args: argparse.Namespace) -&gt; None:
    if not args.config:
        raise ValueError(&quot;fastvideo router-serve requires --config PATH&quot;)
    if not os.path.exists(args.config):
        raise ValueError(f&quot;Router config file not found: &#123;args.config&#125;&quot;)</code></pre></details>
<h3 id="fastvideo.entrypoints.cli.router_serve.RouterServeSubcommand.subparser_init"><code>fastvideo.entrypoints.cli.router_serve.RouterServeSubcommand.subparser_init</code></h3>
<pre class="doc-signature"><code>subparser_init(subparsers: argparse._SubParsersAction) -&gt; FlexibleArgumentParser</code></pre>

<details><summary>Source</summary><pre><code>def subparser_init(
    self,
    subparsers: argparse._SubParsersAction,
) -&gt; FlexibleArgumentParser:
    parser = subparsers.add_parser(
        &quot;router-serve&quot;,
        help=&quot;Start the streaming router (multi-replica load balancer)&quot;,
        usage=&quot;fastvideo router-serve --config ROUTER_CONFIG&quot;,
    )
    parser.add_argument(
        &quot;--config&quot;,
        type=str,
        default=&quot;&quot;,
        required=False,
        help=&quot;Path to a YAML/JSON router config. Required.&quot;,
    )
    return cast(FlexibleArgumentParser, parser)</code></pre></details>
<h2 id="fastvideo.entrypoints.cli.router_serve.cmd_init"><code>fastvideo.entrypoints.cli.router_serve.cmd_init</code></h2>
<pre class="doc-signature"><code>cmd_init() -&gt; list&#91;CLISubcommand&#93;</code></pre>

<details><summary>Source</summary><pre><code>def cmd_init() -&gt; list&#91;CLISubcommand&#93;:
    return &#91;RouterServeSubcommand()&#93;</code></pre></details>
</div>
