docs: def url_for(self, view_name: str, **kwargs):
          '''Build a URL based on a view name and the values provided.
  
          In order to build a URL, all request parameters must be supplied as
          keyword arguments, and each parameter must pass the test for the
          specified parameter type. If these conditions are not met, a
          `URLBuildError` will be thrown.
  
          Keyword arguments that are not request parameters will be included in
          the output URL's query string.
  
          :param view_name: string referencing the view name
          :param \*\*kwargs: keys and values that are used to build request
              parameters and query string arguments.
  
          :return: the built URL
  
          Raises:
              URLBuildError
          '''
          # find the route by the supplied view name
          uri, route = self.router.find_route_by_view_name(view_name)
  
          if not uri or not route:
              raise URLBuildError(
                      'Endpoint with name `{}` was not found'.format(
                          view_name))
  
          if uri != '/' and uri.endswith('/'):
              uri = uri[:-1]
  
          out = uri
  
          # find all the parameters we will need to build in the URL
          matched_params = re.findall(
              self.router.parameter_pattern, uri)
  
          # _method is only a placeholder now, don't know how to support it
          kwargs.pop('_method', None)
          anchor = kwargs.pop('_anchor', '')
          # _external need SERVER_NAME in config or pass _server arg
          external = kwargs.pop('_external', False)
          scheme = kwargs.pop('_scheme', '')
          if scheme and not external:
              raise ValueError('When specifying _scheme, _external must be True')
  
          netloc = kwargs.pop('_server', None)
          if netloc is None and external:
              netloc = self.config.get('SERVER_NAME', '')
  
          for match in matched_params:
              name, _type, pattern = self.router.parse_parameter_string(
                  match)
              # we only want to match against each individual parameter
              specific_pattern = '^{}$'.format(pattern)
              supplied_param = None
  
              if kwargs.get(name):
                  supplied_param = kwargs.get(name)
                  del kwargs[name]
              else:
                  raise URLBuildError(
                      'Required parameter `{}` was not passed to url_for'.format(
                          name))
  
              supplied_param = str(supplied_param)
              # determine if the parameter supplied by the caller passes the test
              # in the URL
              passes_pattern = re.match(specific_pattern, supplied_param)
  
              if not passes_pattern:
                  if _type != str:
                      msg = (
                          'Value "{}" for parameter `{}` does not '
                          'match pattern for type `{}`: {}'.format(
                              supplied_param, name, _type.__name__, pattern))
                  else:
                      msg = (
                          'Value "{}" for parameter `{}` '
                          'does not satisfy pattern {}'.format(
                              supplied_param, name, pattern))
                  raise URLBuildError(msg)
  
              # replace the parameter in the URL with the supplied value
              replacement_regex = '(<{}.*?>)'.format(name)
  
              out = re.sub(
                  replacement_regex, supplied_param, out)
  
          # parse the remainder of the keyword arguments into a querystring
          query_string = urlencode(kwargs, doseq=True) if kwargs else ''
          # scheme://netloc/path;parameters?query#fragment
          out = urlunparse((scheme, netloc, out, '', query_string, anchor))
  
          return out