Skip to content

Instantly share code, notes, and snippets.

@asyncee
Created May 23, 2018 07:37
Show Gist options
  • Save asyncee/afff12559e364b0665c89b0e53341c28 to your computer and use it in GitHub Desktop.
Save asyncee/afff12559e364b0665c89b0e53341c28 to your computer and use it in GitHub Desktop.
import inspect
from nameko.extensions import ENTRYPOINT_EXTENSIONS_ATTR
from nameko.web.handlers import HttpRequestHandler
from werkzeug.routing import Map, Rule
class ResolveUrlError(Exception):
pass
class Router:
def __init__(self, service_cls, host=None):
self.service_cls = service_cls
self.host = host
routes = self.get_routes()
self.map = self.url_map(routes)
def get_routes(self):
routes = []
for method_name, method in inspect.getmembers(self.service_cls, inspect.isfunction):
entrypoints = getattr(method, ENTRYPOINT_EXTENSIONS_ATTR, [])
entrypoint_routes = [
(entrypoint.url, method_name, entrypoint.method.split(',')) for entrypoint in entrypoints
if isinstance(entrypoint, HttpRequestHandler)
]
routes.extend(entrypoint_routes)
return routes
def url_map(self, routes):
rules = [Rule(path, endpoint=endpoint, methods=methods) for path, endpoint, methods in routes]
return Map(rules)
def resolve(self, endpoint, host: str = None, **values):
host = self.host or host
if host.startswith('http'):
scheme, host = host.split('://')
else:
scheme = 'http'
adapter = self.map.bind(server_name=host, url_scheme=scheme)
try:
return adapter.build(endpoint, values=values, force_external=True)
except Exception as e:
raise ResolveUrlError(f'Can not resolve url: {endpoint}') from e
# Dependency example
class RouterDependency(DependencyProvider):
def get_dependency(self, worker_ctx):
config = self.container.config.copy()
return http.Router(self.container.service_cls, host=config['HOST'])
# Usage example
class Service:
name = 'service'
router = RouterDependency()
@http('GET', '/a/b/<c>')
def meth(self, request):
pass
def another_method(self):
url = self.router.resolve('meth', c=123)
url = self.router.resolve('meth', host='http://example.com', c=123) # Override host
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment