router
DuplicatedUriRegisteredError
Raised if duplicated URI is registered.
Router
Operator of routing request to Endpoint
by URI.
register(self, uri, endpoint, version=())
Register combination of URI and Endpoint
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
uri |
Tuple[Union[str, bamboo.location.FlexibleLocation], ...] |
URI pattern of the |
required |
endpoint |
Type[~Endpoint_t] |
|
required |
version |
Union[str, Tuple[str, ...]] |
Version of the |
() |
Exceptions:
Type | Description |
---|---|
DuplicatedUriRegisteredError |
Raised if given URI pattern matches one already registered. |
Source code in bamboo/router.py
def register(
self,
uri: Uri_t,
endpoint: t.Type[Endpoint_t],
version: t.Union[str, t.Tuple[str, ...]] = ()
) -> None:
"""Register combination of URI and `Endpoint`.
Args:
uri: URI pattern of the `Endpoint`.
endpoint: `Endpoint` class to be registered.
version: Version of the `Endpoint`.
Raises:
DuplicatedUriRegisteredError: Raised if given URI pattern
matches one already registered.
"""
for uri_registered in self._raw_uri2endpoint.keys():
if is_duplicated_uri(uri_registered, uri):
raise DuplicatedUriRegisteredError(
"Duplicated URIs were detected.\n"
f"URI pattern 1: {uri_registered}\n"
f"URI pattern 2: {uri}"
)
else:
self._raw_uri2endpoint[uri] = endpoint
if isinstance(version, str):
version = (version,)
if len(version):
uris = [(ver,) + uri for ver in version]
else:
uris = [uri]
for _uri in uris:
if is_flexible_uri(_uri):
self.uris_flexible.append(_uri)
self.uri2endpoint[_uri] = endpoint
search_uris(self, endpoint)
Search URI patterns of specified endpoint
.
endpoint: Endpoint
class whose URI patterns to be retrieved.
Returns:
Type | Description |
---|---|
List[Tuple[Union[str, bamboo.location.FlexibleLocation], ...]] |
Result of searching. |
Source code in bamboo/router.py
def search_uris(self, endpoint: t.Type[Endpoint_t]) -> t.List[Uri_t]:
"""Search URI patterns of specified `endpoint`.
Args:
endpoint: `Endpoint` class whose URI patterns to be retrieved.
Returns:
Result of searching.
"""
return [
uri for uri, point in self.uri2endpoint.items()
if point is endpoint
]
validate(self, uri)
Validate specified uri
and retrieved Endpoint
.
Note
This method returns pair of tuple of flexible locations specified as
parts of URI pattern linked to Endpoint
and its Endpoint
. If any
flexible locations are not included in the URI pattern, then empty
tuple will be returned as a sequence of flexible locations, so if
URI patterns is configured with only static locations, you will get
the empty tuple.
If invalid URI pattern is come, then also empty tuple will be return
as sequence of flexible locations and None
as Endpoint
, or
((), None)
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
uri |
str |
Path of URI. |
required |
Returns:
Type | Description |
---|---|
Tuple[Tuple[str, ...], Optional[Type[~Endpoint_t]]] |
Pair of values of flexible locations and |
Source code in bamboo/router.py
def validate(
self,
uri: str
) -> t.Tuple[t.Tuple[str, ...], t.Optional[t.Type[Endpoint_t]]]:
"""Validate specified `uri` and retrieved `Endpoint`.
Note:
This method returns pair of tuple of flexible locations specified as
parts of URI pattern linked to `Endpoint` and its `Endpoint`. If any
flexible locations are not included in the URI pattern, then empty
tuple will be returned as a sequence of flexible locations, so if
URI patterns is configured with only static locations, you will get
the empty tuple.
If invalid URI pattern is come, then also empty tuple will be return
as sequence of flexible locations and `None` as `Endpoint`, or
`((), None)`.
Args:
uri: Path of URI.
Returns:
Pair of values of flexible locations and `Endpoint` if specified
`uri` is valid.
"""
uri = tuple(uri[1:].split("/"))
if not uri[0]:
uri = ()
endpoint = self.uri2endpoint.get(uri)
if endpoint:
return ((), endpoint)
depth = len(uri)
for flexible in self.uris_flexible:
if len(flexible) != depth:
continue
flexibles_received = []
# Judging each locations
for loc_req, loc_flex in zip(uri, flexible):
if isinstance(loc_flex, FlexibleLocation):
if not loc_flex.is_valid(loc_req):
break
flexibles_received.append(loc_req)
else:
if loc_req != loc_flex:
break
else:
# Correct case
endpoint = self.uri2endpoint.get(flexible)
return (tuple(flexibles_received), endpoint)
# Could not find it
return ((), None)