Skip to content

Commit

Permalink
Merge pull request #519 from KeepSafe/routes_view
Browse files Browse the repository at this point in the history
Routes view
  • Loading branch information
asvetlov committed Oct 13, 2015
2 parents 12cee27 + 26e8b1e commit 274a588
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 0 deletions.
20 changes: 20 additions & 0 deletions aiohttp/web_urldispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,23 @@ def __repr__(self):
', '.join(sorted(self._allowed_methods))))


class RoutesView:

__slots__ = '_urls'

def __init__(self, urls):
self._urls = urls

def __len__(self):
return len(self._urls)

def __iter__(self):
yield from self._urls

def __contains__(self, route):
return route in self._urls


class UrlDispatcher(AbstractRouter, collections.abc.Mapping):

DYN = re.compile(r'^\{(?P<var>[a-zA-Z][_a-zA-Z0-9]*)\}$')
Expand Down Expand Up @@ -417,6 +434,9 @@ def __contains__(self, name):
def __getitem__(self, name):
return self._routes[name]

def routes(self):
return RoutesView(self._urls)

def register_route(self, route):
assert isinstance(route, Route), 'Instance of Route class is required.'

Expand Down
19 changes: 19 additions & 0 deletions docs/web.rst
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,25 @@ so application developer can use classes if he wants::
That means the handler for ``'/path'`` is applied for every HTTP method.


Route views
-----------

.. versionadded:: 0.18

For look on *all* routes in the router you may use
:meth:`UrlDispatcher.routes` method.

You can iterate over routes in the router table::

for route in app.router.routes():
print(route)

or get router table size::

len(app.router.routes())



Custom conditions for routes lookup
-----------------------------------

Expand Down
20 changes: 20 additions & 0 deletions docs/web_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,26 @@ Router is any object that implements :class:`AbstractRouter` interface.
The method don't raise :exc:`HTTPNotFound` and
:exc:`HTTPMethodNotAllowed` anymore.

.. method:: routes()

The method returns a *view* for *all* registered routes.

The view is an object that allows to:

1. Get size of the router table::

len(app.router.routes())

2. Iterate over registered routes::

for route in app.router.routes():
print(route)

3. Make a check if the route is registered in the router table::

route in app.router.routes()

.. versionadded:: 0.18

.. _aiohttp-web-route:

Expand Down
21 changes: 21 additions & 0 deletions tests/test_urldispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,3 +605,24 @@ def test_static_handle_exception(self):
self.assertIs(exc, fut.exception())
self.assertFalse(loop.add_writer.called)
self.assertFalse(loop.remove_writer.called)

def fill_routes(self):
route1 = self.router.add_route('GET', '/plain', self.make_handler())
route2 = self.router.add_route('GET', '/variable/{name}',
self.make_handler())
route3 = self.router.add_static('/static',
os.path.dirname(aiohttp.__file__))
return route1, route2, route3

def test_routes_view_len(self):
self.fill_routes()
self.assertEqual(3, len(self.router.routes()))

def test_routes_view_iter(self):
routes = self.fill_routes()
self.assertEqual(list(routes), list(self.router.routes()))

def test_routes_view_contains(self):
routes = self.fill_routes()
for route in routes:
self.assertIn(route, self.router.routes())

0 comments on commit 274a588

Please sign in to comment.