URL Routing — Werkzeug Documentation (3.1.x)

# URL Routing

When it comes to combining multiple controller or view functions (however you want to call them), you need a dispatcher. A simple way would be applying regular expression tests on `PATH_INFO` and call registered callback functions that return the value.

Werkzeug provides a much more powerful system, similar to Routes. All the objects mentioned on this page must be imported from `werkzeug.routing`, not from `werkzeug`!

## Quickstart

Here is a simple example which could be the URL definition for a blog:

    from werkzeug.routing import Map, Rule, NotFound, RequestRedirect

    url_map = Map([
        Rule('/', endpoint='blog/index'),
        Rule('/<int:year>/', endpoint='blog/archive'),
        Rule('/<int:year>/<int:month>/', endpoint='blog/archive'),
        Rule('/<int:year>/<int:month>/<int:day>/', endpoint='blog/archive'),
        Rule('/<int:year>/<int:month>/<int:day>/<slug>',
             endpoint='blog/show_post'),
        Rule('/about', endpoint='blog/about_me'),
        Rule('/feeds/', endpoint='blog/feeds'),
        Rule('/feeds/<feed_name>.rss', endpoint='blog/show_feed')
    ])

    def application(environ, start_response):
        urls = url_map.bind_to_environ(environ)
        try:
            endpoint, args = urls.match()
        except HTTPException as e:
            return e(environ, start_response)
        start_response('200 OK', [('Content-Type', 'text/plain')])
        return [f'Rule points to {endpoint!r} with arguments {args!r}'.encode()]

So what does that do? First of all we create a new `Map` which stores a bunch of URL rules. Then we pass it a list of `Rule` objects.

Each `Rule` object is instantiated with a string that represents a rule and an endpoint which will be the alias for what view the rule represents. Multiple rules can have the same endpoint, but should have different arguments to allow URL construction.

The format for the URL rules is straightforward, but explained in detail below.

Inside the WSGI application we bind the url_map to the current request which will return a new `MapAdapter`. This url_map adapter can then be used to match or build domains for the current request.

The `MapAdapter.match()` method can then either return a tuple in the form `(endpoint, args)` or raise one of the three exceptions `NotFound`, `MethodNotAllowed`, or `RequestRedirect`. For more details about those exceptions have a look at the documentation of the `MapAdapter.match()` method.

## Rule Format

Rule strings are URL paths with placeholders for variable parts in the format `<converter(arguments):name>`. `converter` and `arguments` (with parentheses) are optional. If no converter is given, the `default` converter is used (`string` by default). The available converters are discussed below.

Rules that end with a slash are “branches”, others are “leaves”. If `strict_slashes` is enabled (the default), visiting a branch URL without a trailing slash will redirect to the URL with a slash appended.

Many HTTP servers merge consecutive slashes into one when receiving requests. If `merge_slashes` is enabled (the default), rules will merge slashes in non-variable parts when matching and building. Visiting a URL with consecutive slashes will redirect to the URL with slashes merged. If you want to disable `merge_slashes` for a `Rule` or `Map`, you’ll also need to configure your web server appropriately.

## Rule Priority

In general, the map matches more specific rules first. Rules are made up of static and variable parts, separated by slash `/`. For a given segment, rules with a static part in that position take priority, and longer static values take priority over shorter. Variable parts are weighted based on the type of data they match.

If you’re using subdomain or host matching, the domain part can use converters as well. The domain part is matched before the path parts. Like the path parts, a static domain part take priority over a variable part.

Rules may end up with the same priority, by having static parts with the same length, and dynamic parts with the same weight, in the same positions. In this case, sorting is stable, so rules added earlier take priority.

The exact way that rules are sorted internally is pretty complicated, but the result should be that you can rely on more specific rules matching before more general ones.

## Built-in Converters

Converters for common types of URL variables are built-in. The available converters can be overridden or extended through `Map.converters`.

class werkzeug.routing.UnicodeConverter(map, minlength=1, maxlength=None, length=None)

  This converter is the default converter and accepts any string but only one path segment. Thus the string can not include a slash.

  This is the default validator.

  Example:

      Rule('/pages/<page>'),
      Rule('/<string(length=2):lang_code>')

  Parameters:

    - map (Map) – the `Map`.

    - minlength (int) – the minimum length of the string. Must be greater or equal 1.

    - maxlength (int | None) – the maximum length of the string.

    - length (int | None) – the exact length of the string.

class werkzeug.routing.PathConverter(map, *args, **kwargs)

  Like the default `UnicodeConverter`, but it also matches slashes. This is useful for wikis and similar applications:

      Rule('/<path:wikipage>')
      Rule('/<path:wikipage>/edit')

  Parameters:

    - map (Map) – the `Map`.

    - args (t.Any)

    - kwargs (t.Any)

class werkzeug.routing.AnyConverter(map, *items)

  Matches one of the items provided. Items can either be Python identifiers or strings:

      Rule('/<any(about, help, imprint, class, "foo,bar"):page_name>')

  Parameters:

    - map (Map) – the `Map`.

    - items (str) – this function accepts the possible items as positional arguments.

  Changelog

  Changed in version 2.2: Value is validated when building a URL.

class werkzeug.routing.IntegerConverter(map, fixed_digits=0, min=None, max=None, signed=False)

  This converter only accepts integer values:

      Rule("/page/<int:page>")

  By default it only accepts unsigned, positive values. The `signed` parameter will enable signed, negative values.

      Rule("/page/<int(signed=True):page>")

  Parameters:

    - map (Map) – The `Map`.

    - fixed_digits (int) – The number of fixed digits in the URL. If you set this to `4` for example, the rule will only match if the URL looks like `/0001/`. The default is variable length.

    - min (int | None) – The minimal value.

    - max (int | None) – The maximal value.

    - signed (bool) – Allow signed (negative) values.

  Changelog

  Added in version 0.15: The `signed` parameter.

class werkzeug.routing.FloatConverter(map, min=None, max=None, signed=False)

  This converter only accepts floating point values:

      Rule("/probability/<float:probability>")

  By default it only accepts unsigned, positive values. The `signed` parameter will enable signed, negative values.

      Rule("/offset/<float(signed=True):offset>")

  Parameters:

    - map (Map) – The `Map`.

    - min (float | None) – The minimal value.

    - max (float | None) – The maximal value.

    - signed (bool) – Allow signed (negative) values.

  Changelog

  Added in version 0.15: The `signed` parameter.

class werkzeug.routing.UUIDConverter(map, *args, **kwargs)

  This converter only accepts UUID strings:

      Rule('/object/<uuid:identifier>')

  Changelog

  Added in version 0.10.

  Parameters:

    - map (Map) – the `Map`.

    - args (t.Any)

    - kwargs (t.Any)

## Maps, Rules and Adapters

class werkzeug.routing.Map(rules=None, default_subdomain='', strict_slashes=True, merge_slashes=True, redirect_defaults=True, converters=None, sort_parameters=False, sort_key=None, host_matching=False)

  The map class stores all the URL rules and some configuration parameters. Some of the configuration values are only stored on the `Map` instance since those affect all rules, others are just defaults and can be overridden for each rule. Note that you have to specify all arguments besides the `rules` as keyword arguments!

  Parameters:

    - rules (t.Iterable[RuleFactory] | None) – sequence of url rules for this map.

    - default_subdomain (str) – The default subdomain for rules without a subdomain defined.

    - strict_slashes (bool) – If a rule ends with a slash but the matched URL does not, redirect to the URL with a trailing slash.

    - merge_slashes (bool) – Merge consecutive slashes when matching or building URLs. Matches will redirect to the normalized URL. Slashes in variable parts are not merged.

    - redirect_defaults (bool) – This will redirect to the default rule if it wasn’t visited that way. This helps creating unique URLs.

    - converters (t.Mapping[str, type[BaseConverter]] | None) – A dict of converters that adds additional converters to the list of converters. If you redefine one converter this will override the original one.

    - sort_parameters (bool) – If set to `True` the url parameters are sorted. See `url_encode` for more details.

    - sort_key (t.Callable[[t.Any], t.Any] | None) – The sort key function for `url_encode`.

    - host_matching (bool) – if set to `True` it enables the host matching feature and disables the subdomain one. If enabled the `host` parameter to rules is used instead of the `subdomain` one.

  Changelog

  Changed in version 3.0: The `charset` and `encoding_errors` parameters were removed.

  Changed in version 1.0: If `url_scheme` is `ws` or `wss`, only WebSocket rules will match.

  Changed in version 1.0: The `merge_slashes` parameter was added.

  Changed in version 0.7: The `encoding_errors` and `host_matching` parameters were added.

  Changed in version 0.5: The `sort_parameters` and `sort_key` parameters were added.

  converters

    The dictionary of converters. This can be modified after the class was created, but will only affect rules added after the modification. If the rules are defined with the list passed to the class, the `converters` parameter to the constructor has to be used instead.

  default_converters = {'any': <class 'werkzeug.routing.converters.AnyConverter'>, 'default': <class 'werkzeug.routing.converters.UnicodeConverter'>, 'float': <class 'werkzeug.routing.converters.FloatConverter'>, 'int': <class 'werkzeug.routing.converters.IntegerConverter'>, 'path': <class 'werkzeug.routing.converters.PathConverter'>, 'string': <class 'werkzeug.routing.converters.UnicodeConverter'>, 'uuid': <class 'werkzeug.routing.converters.UUIDConverter'>}

    A dict of default converters to be used.

  lock_class()

    The type of lock to use when updating.

    Changelog

    Added in version 1.0.

  is_endpoint_expecting(endpoint, *arguments)

    Iterate over all rules and check if the endpoint expects the arguments provided. This is for example useful if you have some URLs that expect a language code and others that do not and you want to wrap the builder a bit so that the current language code is automatically added if not provided but endpoints expect it.

    Parameters:

      - endpoint (Any) – the endpoint to check.

      - arguments (str) – this function accepts one or more arguments as positional arguments. Each one of them is checked.

    Return type:

      bool

  iter_rules(endpoint=None)

    Iterate over all rules or the rules of an endpoint.

    Parameters:

      endpoint (Any | None) – if provided only the rules for that endpoint are returned.

    Returns:

      an iterator

    Return type:

      Iterator[Rule]

  add(rulefactory)

    Add a new rule or factory to the map and bind it. Requires that the rule is not bound to another map.

    Parameters:

      rulefactory (RuleFactory) – a `Rule` or `RuleFactory`

    Return type:

      None

  bind(server_name, script_name=None, subdomain=None, url_scheme='http', default_method='GET', path_info=None, query_args=None)

    Return a new `MapAdapter` with the details specified to the call. Note that `script_name` will default to `'/'` if not further specified or `None`. The `server_name` at least is a requirement because the HTTP RFC requires absolute URLs for redirects and so all redirect exceptions raised by Werkzeug will contain the full canonical URL.

    If no path_info is passed to `match()` it will use the default path info passed to bind. While this doesn’t really make sense for manual bind calls, it’s useful if you bind a map to a WSGI environment which already contains the path info.

    `subdomain` will default to the `default_subdomain` for this map if no defined. If there is no `default_subdomain` you cannot use the subdomain feature.

    Changelog

    Changed in version 1.0: If `url_scheme` is `ws` or `wss`, only WebSocket rules will match.

    Changed in version 0.15: `path_info` defaults to `'/'` if `None`.

    Changed in version 0.8: `query_args` can be a string.

    Changed in version 0.7: Added `query_args`.

    Parameters:

      - server_name (str)

      - script_name (str | None)

      - subdomain (str | None)

      - url_scheme (str)

      - default_method (str)

      - path_info (str | None)

      - query_args (Mapping[str, Any] | str | None)

    Return type:

      MapAdapter

  bind_to_environ(environ, server_name=None, subdomain=None)

    Like `bind()` but you can pass it an WSGI environment and it will fetch the information from that dictionary. Note that because of limitations in the protocol there is no way to get the current subdomain and real `server_name` from the environment. If you don’t provide it, Werkzeug will use `SERVER_NAME` and `SERVER_PORT` (or `HTTP_HOST` if provided) as used `server_name` with disabled subdomain feature.

    If `subdomain` is `None` but an environment and a server name is provided it will calculate the current subdomain automatically. Example: `server_name` is `'example.com'` and the `SERVER_NAME` in the wsgi `environ` is `'staging.dev.example.com'` the calculated subdomain will be `'staging.dev'`.

    If the object passed as environ has an environ attribute, the value of this attribute is used instead. This allows you to pass request objects. Additionally `PATH_INFO` added as a default of the `MapAdapter` so that you don’t have to pass the path info to the match method.

    Changelog

    Changed in version 1.0.0: If the passed server name specifies port 443, it will match if the incoming scheme is `https` without a port.

    Changed in version 1.0.0: A warning is shown when the passed server name does not match the incoming WSGI server name.

    Changed in version 0.8: This will no longer raise a ValueError when an unexpected server name was passed.

    Changed in version 0.5: previously this method accepted a bogus `calculate_subdomain` parameter that did not have any effect. It was removed because of that.

    Parameters:

      - environ (WSGIEnvironment | Request) – a WSGI environment.

      - server_name (str | None) – an optional server name hint (see above).

      - subdomain (str | None) – optionally the current subdomain (see above).

    Return type:

      MapAdapter

  update()

    Called before matching and building to keep the compiled rules in the correct order after things changed.

    Return type:

      None

class werkzeug.routing.MapAdapter(map, server_name, script_name, subdomain, url_scheme, path_info, default_method, query_args=None)

  Returned by `Map.bind()` or `Map.bind_to_environ()` and does the URL matching and building based on runtime information.

  Parameters:

    - map (Map)

    - server_name (str)

    - script_name (str)

    - subdomain (str | None)

    - url_scheme (str)

    - path_info (str)

    - default_method (str)

    - query_args (t.Mapping[str, t.Any] | str | None)

  dispatch(view_func, path_info=None, method=None, catch_http_exceptions=False)

    Does the complete dispatching process. `view_func` is called with the endpoint and a dict with the values for the view. It should look up the view function, call it, and return a response object or WSGI application. http exceptions are not caught by default so that applications can display nicer error messages by just catching them by hand. If you want to stick with the default error messages you can pass it `catch_http_exceptions=True` and it will catch the http exceptions.

    Here a small example for the dispatch usage:

        from werkzeug.wrappers import Request, Response
        from werkzeug.wsgi import responder
        from werkzeug.routing import Map, Rule

        def on_index(request):
            return Response('Hello from the index')

        url_map = Map([Rule('/', endpoint='index')])
        views = {'index': on_index}

        @responder
        def application(environ, start_response):
            request = Request(environ)
            urls = url_map.bind_to_environ(environ)
            return urls.dispatch(lambda e, v: views[e](request, **v),
                                 catch_http_exceptions=True)

    Keep in mind that this method might return exception objects, too, so use `Response.force_type` to get a response object.

    Parameters:

      - view_func (t.Callable[[str, t.Mapping[str, t.Any]], WSGIApplication]) – a function that is called with the endpoint as first argument and the value dict as second. Has to dispatch to the actual view function with this information. (see above)

      - path_info (str | None) – the path info to use for matching. Overrides the path info specified on binding.

      - method (str | None) – the HTTP method used for matching. Overrides the method specified on binding.

      - catch_http_exceptions (bool) – set to `True` to catch any of the werkzeug `HTTPException`s.

    Return type:

      WSGIApplication

  match(path_info: str | None = None, method: str | None = None, return_rule: Literal[False] = False, query_args: Mapping[str, Any] | str | None = None, websocket: bool | None = None) → tuple[Any, Mapping[str, Any]]
  match(path_info: str | None = None, method: str | None = None, return_rule: Literal[True] = True, query_args: Mapping[str, Any] | str | None = None, websocket: bool | None = None) → tuple[Rule, Mapping[str, Any]]

    The usage is simple: you just pass the match method the current path info as well as the method (which defaults to `GET`). The following things can then happen:

    - you receive a `NotFound` exception that indicates that no URL is matching. A `NotFound` exception is also a WSGI application you can call to get a default page not found page (happens to be the same object as `werkzeug.exceptions.NotFound`)

    - you receive a `MethodNotAllowed` exception that indicates that there is a match for this URL but not for the current request method. This is useful for RESTful applications.

    - you receive a `RequestRedirect` exception with a `new_url` attribute. This exception is used to notify you about a request Werkzeug requests from your WSGI application. This is for example the case if you request `/foo` although the correct URL is `/foo/` You can use the `RequestRedirect` instance as response-like object similar to all other subclasses of `HTTPException`.

    - you receive a `WebsocketMismatch` exception if the only match is a WebSocket rule but the bind is an HTTP request, or if the match is an HTTP rule but the bind is a WebSocket request.

    - you get a tuple in the form `(endpoint, arguments)` if there is a match (unless `return_rule` is True, in which case you get a tuple in the form `(rule, arguments)`)

    If the path info is not passed to the match method the default path info of the map is used (defaults to the root URL if not defined explicitly).

    All of the exceptions raised are subclasses of `HTTPException` so they can be used as WSGI responses. They will all render generic error or redirect pages.

    Here is a small example for matching:

        >>> m = Map([
        ...     Rule('/', endpoint='index'),
        ...     Rule('/downloads/', endpoint='downloads/index'),
        ...     Rule('/downloads/<int:id>', endpoint='downloads/show')
        ... ])
        >>> urls = m.bind("example.com", "/")
        >>> urls.match("/", "GET")
        ('index', {})
        >>> urls.match("/downloads/42")
        ('downloads/show', {'id': 42})

    And here is what happens on redirect and missing URLs:

        >>> urls.match("/downloads")
        Traceback (most recent call last):
          ...
        RequestRedirect: http://example.com/downloads/
        >>> urls.match("/missing")
        Traceback (most recent call last):
          ...
        NotFound: 404 Not Found

    Parameters:

      - path_info (str | None) – the path info to use for matching. Overrides the path info specified on binding.

      - method (str | None) – the HTTP method used for matching. Overrides the method specified on binding.

      - return_rule (bool) – return the rule that matched instead of just the endpoint (defaults to `False`).

      - query_args (Mapping[str, Any] | str | None) – optional query arguments that are used for automatic redirects as string or dictionary. It’s currently not possible to use the query arguments for URL matching.

      - websocket (bool | None) – Match WebSocket instead of HTTP requests. A websocket request has a `ws` or `wss` `url_scheme`. This overrides that detection.

    Return type:

      tuple[Any | Rule, Mapping[str, Any]]

    Changelog

    Added in version 1.0: Added `websocket`.

    Changed in version 0.8: `query_args` can be a string.

    Added in version 0.7: Added `query_args`.

    Added in version 0.6: Added `return_rule`.

  test(path_info=None, method=None)

    Test if a rule would match. Works like `match` but returns `True` if the URL matches, or `False` if it does not exist.

    Parameters:

      - path_info (str | None) – the path info to use for matching. Overrides the path info specified on binding.

      - method (str | None) – the HTTP method used for matching. Overrides the method specified on binding.

    Return type:

      bool

  allowed_methods(path_info=None)

    Returns the valid methods that match for a given path.

    Changelog

    Added in version 0.7.

    Parameters:

      path_info (str | None)

    Return type:

      Iterable[str]

  get_host(domain_part)

    Figures out the full host name for the given domain part. The domain part is a subdomain in case host matching is disabled or a full host name.

    Parameters:

      domain_part (str | None)

    Return type:

      str

  make_alias_redirect_url(path, endpoint, values, method, query_args)

    Internally called to make an alias redirect URL.

    Parameters:

      - path (str)

      - endpoint (Any)

      - values (Mapping[str, Any])

      - method (str)

      - query_args (Mapping[str, Any] | str)

    Return type:

      str

  build(endpoint, values=None, method=None, force_external=False, append_unknown=True, url_scheme=None)

    Build a URL by filling in any variable slots in the endpoint’s rule with the provided values.

    This produces relative URLs (path only, no host) by default, which is appropriate for most use cases. When using subdomain or host matching, the URL will be absolute if the endpoint is not on the same host as the current request. If you need an absolute URL no matter what, such as when adding a link to an email, pass `force_external=True`.

    Characters that are not allowed directly in URLs will be percent-encoded using UTF-8.

    Additional values that don’t match any rule parts are added to the query (`?key=value`) part of the URL.

    If a rule is not found, an `BuildError` is raised. Converters may also raise exceptions when preparing a value.

    Unlike matching, building does not perform comprehensive validation of the values, it’s assumed that they are trusted and correct. It’s also possible to build a URL for one endpoint that will be matched by another, or will not match. This is very unlikely to happen or to matter in most applications, especially with testing. If you need a stronger guarantee, you can use a helper to verify that `match(build(endpoint)) == endpoint`.

    Parameters:

      - endpoint (Any) – The endpoint for the rule to build.

      - values (Mapping[str, Any] | None) – Values for the variable parts of the rule, which will be converted using the part’s converter’s `to_url()` method. Keys that don’t match variable parts will be converted to a query string unless `append_unknown` is disabled.

      - method (str | None) – Further match the rule to build by this HTTP method, for when there are multiple rules for the same endpoint that vary based on method.

      - force_external (bool) – Always produce an absolute URL, for external use. If `scheme` is not set, this produces a protocol-relative URL.

      - append_unknown (bool) – Convert values that don’t match any rule parts to a query string. Disable to ignore such values.

      - url_scheme (str | None) – Scheme to use for absolute URLs. Defaults to `url_scheme`.

    Return type:

      str

    Changelog

    Changed in version 2.0: Added the `url_scheme` parameter.

    Added in version 0.6: Added the `append_unknown` parameter.

class werkzeug.routing.Rule(string, defaults=None, subdomain=None, methods=None, build_only=False, endpoint=None, strict_slashes=None, merge_slashes=None, redirect_to=None, alias=False, host=None, websocket=False)

  A Rule represents one URL pattern. There are some options for `Rule` that change the way it behaves and are passed to the `Rule` constructor. Note that besides the rule-string all arguments must be keyword arguments in order to not break the application on Werkzeug upgrades.

  `string`

    Rule strings basically are just normal URL paths with placeholders in the format `<converter(arguments):name>` where the converter and the arguments are optional. If no converter is defined the `default` converter is used which means `string` in the normal configuration.

    URL rules that end with a slash are branch URLs, others are leaves. If you have `strict_slashes` enabled (which is the default), all branch URLs that are matched without a trailing slash will trigger a redirect to the same URL with the missing slash appended.

    The converters are defined on the `Map`.

  `endpoint`

    The endpoint for this rule. This can be anything. A reference to a function, a string, a number etc. The preferred way is using a string because the endpoint is used for URL generation.

  `defaults`

    An optional dict with defaults for other rules with the same endpoint. This is a bit tricky but useful if you want to have unique URLs:

        url_map = Map([
            Rule('/all/', defaults={'page': 1}, endpoint='all_entries'),
            Rule('/all/page/<int:page>', endpoint='all_entries')
        ])

    If a user now visits `http://example.com/all/page/1` they will be redirected to `http://example.com/all/`. If `redirect_defaults` is disabled on the `Map` instance this will only affect the URL generation.

  `subdomain`

    The subdomain rule string for this rule. If not specified the rule only matches for the `default_subdomain` of the map. If the map is not bound to a subdomain this feature is disabled.

    Can be useful if you want to have user profiles on different subdomains and all subdomains are forwarded to your application:

        url_map = Map([
            Rule('/', subdomain='<username>', endpoint='user/homepage'),
            Rule('/stats', subdomain='<username>', endpoint='user/stats')
        ])

  `methods`

    A sequence of http methods this rule applies to. If not specified, all methods are allowed. For example this can be useful if you want different endpoints for `POST` and `GET`. If methods are defined and the path matches but the method matched against is not in this list or in the list of another rule for that path the error raised is of the type `MethodNotAllowed` rather than `NotFound`. If `GET` is present in the list of methods and `HEAD` is not, `HEAD` is added automatically.

  `strict_slashes`

    Override the `Map` setting for `strict_slashes` only for this rule. If not specified the `Map` setting is used.

  `merge_slashes`

    Override `Map.merge_slashes` for this rule.

  `build_only`

    Set this to True and the rule will never match but will create a URL that can be build. This is useful if you have resources on a subdomain or folder that are not handled by the WSGI application (like static data)

  `redirect_to`

    If given this must be either a string or callable. In case of a callable it’s called with the url adapter that triggered the match and the values of the URL as keyword arguments and has to return the target for the redirect, otherwise it has to be a string with placeholders in rule syntax:

        def foo_with_slug(adapter, id):
            # ask the database for the slug for the old id.  this of
            # course has nothing to do with werkzeug.
            return f'foo/{Foo.get_slug_for_id(id)}'

        url_map = Map([
            Rule('/foo/<slug>', endpoint='foo'),
            Rule('/some/old/url/<slug>', redirect_to='foo/<slug>'),
            Rule('/other/old/url/<int:id>', redirect_to=foo_with_slug)
        ])

    When the rule is matched the routing system will raise a `RequestRedirect` exception with the target for the redirect.

    Keep in mind that the URL will be joined against the URL root of the script so don’t use a leading slash on the target URL unless you really mean root of that domain.

  `alias`

    If enabled this rule serves as an alias for another rule with the same endpoint and arguments.

  `host`

    If provided and the URL map has host matching enabled this can be used to provide a match rule for the whole host. This also means that the subdomain feature is disabled.

  `websocket`

    If `True`, this rule is only matches for WebSocket (`ws://`, `wss://`) requests. By default, rules will only match for HTTP requests.

  Changelog

  Changed in version 2.1: Percent-encoded newlines (`%0a`), which are decoded by WSGI servers, are considered when routing instead of terminating the match early.

  Added in version 1.0: Added `websocket`.

  Added in version 1.0: Added `merge_slashes`.

  Added in version 0.7: Added `alias` and `host`.

  Changed in version 0.6.1: `HEAD` is added to `methods` if `GET` is present.

  Parameters:

    - string (str)

    - defaults (t.Mapping[str, t.Any] | None)

    - subdomain (str | None)

    - methods (t.Iterable[str] | None)

    - build_only (bool)

    - endpoint (t.Any | None)

    - strict_slashes (bool | None)

    - merge_slashes (bool | None)

    - redirect_to (str | t.Callable[..., str] | None)

    - alias (bool)

    - host (str | None)

    - websocket (bool)

  empty()

    Return an unbound copy of this rule.

    This can be useful if want to reuse an already bound URL for another map. See `get_empty_kwargs` to override what keyword arguments are provided to the new copy.

    Return type:

      Rule

## Rule Factories

class werkzeug.routing.RuleFactory

  As soon as you have more complex URL setups it’s a good idea to use rule factories to avoid repetitive tasks. Some of them are builtin, others can be added by subclassing `RuleFactory` and overriding `get_rules`.

  get_rules(map)

    Subclasses of `RuleFactory` have to override this method and return an iterable of rules.

    Parameters:

      map (Map)

    Return type:

      t.Iterable[Rule]

class werkzeug.routing.Subdomain(subdomain, rules)

  All URLs provided by this factory have the subdomain set to a specific domain. For example if you want to use the subdomain for the current language this can be a good setup:

      url_map = Map([
          Rule('/', endpoint='#select_language'),
          Subdomain('<string(length=2):lang_code>', [
              Rule('/', endpoint='index'),
              Rule('/about', endpoint='about'),
              Rule('/help', endpoint='help')
          ])
      ])

  All the rules except for the `'#select_language'` endpoint will now listen on a two letter long subdomain that holds the language code for the current request.

  Parameters:

    - subdomain (str)

    - rules (t.Iterable[RuleFactory])

class werkzeug.routing.Submount(path, rules)

  Like `Subdomain` but prefixes the URL rule with a given string:

      url_map = Map([
          Rule('/', endpoint='index'),
          Submount('/blog', [
              Rule('/', endpoint='blog/index'),
              Rule('/entry/<entry_slug>', endpoint='blog/show')
          ])
      ])

  Now the rule `'blog/show'` matches `/blog/entry/<entry_slug>`.

  Parameters:

    - path (str)

    - rules (t.Iterable[RuleFactory])

class werkzeug.routing.EndpointPrefix(prefix, rules)

  Prefixes all endpoints (which must be strings for this factory) with another string. This can be useful for sub applications:

      url_map = Map([
          Rule('/', endpoint='index'),
          EndpointPrefix('blog/', [Submount('/blog', [
              Rule('/', endpoint='index'),
              Rule('/entry/<entry_slug>', endpoint='show')
          ])])
      ])

  Parameters:

    - prefix (str)

    - rules (t.Iterable[RuleFactory])

## Rule Templates

class werkzeug.routing.RuleTemplate(rules)

  Returns copies of the rules wrapped and expands string templates in the endpoint, rule, defaults or subdomain sections.

  Here a small example for such a rule template:

      from werkzeug.routing import Map, Rule, RuleTemplate

      resource = RuleTemplate([
          Rule('/$name/', endpoint='$name.list'),
          Rule('/$name/<int:id>', endpoint='$name.show')
      ])

      url_map = Map([resource(name='user'), resource(name='page')])

  When a rule template is called the keyword arguments are used to replace the placeholders in all the string parameters.

  Parameters:

    rules (t.Iterable[Rule])

## Custom Converters

You can add custom converters that add behaviors not provided by the built-in converters. To make a custom converter, subclass `BaseConverter` then pass the new class to the `Map` `converters` parameter, or add it to `url_map.converters`.

The converter should have a `regex` attribute with a regular expression to match with. If the converter can take arguments in a URL rule, it should accept them in its `__init__` method. The entire regex expression will be matched as a group and used as the value for conversion.

If a custom converter can match a forward slash, `/`, it should have the attribute `part_isolating` set to `False`. This will ensure that rules using the custom converter are correctly matched.

It can implement a `to_python` method to convert the matched string to some other object. This can also do extra validation that wasn’t possible with the `regex` attribute, and should raise a `werkzeug.routing.ValidationError` in that case. Raising any other errors will cause a 500 error.

It can implement a `to_url` method to convert a Python object to a string when building a URL. Any error raised here will be converted to a `werkzeug.routing.BuildError` and eventually cause a 500 error.

This example implements a `BooleanConverter` that will match the strings `"yes"`, `"no"`, and `"maybe"`, returning a random value for `"maybe"`.

    from random import randrange
    from werkzeug.routing import BaseConverter, ValidationError

    class BooleanConverter(BaseConverter):
        regex = r"(?:yes|no|maybe)"

        def __init__(self, url_map, maybe=False):
            super().__init__(url_map)
            self.maybe = maybe

        def to_python(self, value):
            if value == "maybe":
                if self.maybe:
                    return not randrange(2)
                raise ValidationError
            return value == 'yes'

        def to_url(self, value):
            return "yes" if value else "no"

    from werkzeug.routing import Map, Rule

    url_map = Map([
        Rule("/vote/<bool:werkzeug_rocks>", endpoint="vote"),
        Rule("/guess/<bool(maybe=True):foo>", endpoint="guess")
    ], converters={'bool': BooleanConverter})

If you want to change the default converter, assign a different converter to the `"default"` key.

## Host Matching

Changelog

Added in version 0.7.

Starting with Werkzeug 0.7 it’s also possible to do matching on the whole host names instead of just the subdomain. To enable this feature you need to pass `host_matching=True` to the `Map` constructor and provide the `host` argument to all routes:

    url_map = Map([
        Rule('/', endpoint='www_index', host='www.example.com'),
        Rule('/', endpoint='help_index', host='help.example.com')
    ], host_matching=True)

Variable parts are of course also possible in the host section:

    url_map = Map([
        Rule('/', endpoint='www_index', host='www.example.com'),
        Rule('/', endpoint='user_index', host='<user>.example.com')
    ], host_matching=True)

## WebSockets

Changelog

Added in version 1.0.

If a `Rule` is created with `websocket=True`, it will only match if the `Map` is bound to a request with a `url_scheme` of `ws` or `wss`.

Note

Werkzeug has no further WebSocket support beyond routing. This functionality is mostly of use to ASGI projects.

    url_map = Map([
        Rule("/ws", endpoint="comm", websocket=True),
    ])
    adapter = map.bind("example.org", "/ws", url_scheme="ws")
    assert adapter.match() == ("comm", {})

If the only match is a WebSocket rule and the bind is HTTP (or the only match is HTTP and the bind is WebSocket) a `WebsocketMismatch` (derives from `BadRequest`) exception is raised.

As WebSocket URLs have a different scheme, rules are always built with a scheme and host, `force_external=True` is implied.

    url = adapter.build("comm")
    assert url == "ws://example.org/ws"