routes.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. from functools import wraps
  2. import inspect
  3. from starlette import routing, requests
  4. from . import globals
  5. def add_route(self, route):
  6. """
  7. :param route: starlette route including a path and a function to be called
  8. :return:
  9. """
  10. globals.app.routes.insert(0, route)
  11. def get(self, path: str):
  12. """
  13. Use as a decorator for a function like @ui.get('/another/route/{id}').
  14. :param path: string that starts with a '/'
  15. :return:
  16. """
  17. *_, converters = routing.compile_path(path)
  18. def decorator(func):
  19. @wraps(func)
  20. def decorated(request: requests.Request):
  21. args = {name: converter.convert(request.path_params.get(name)) for name, converter in converters.items()}
  22. parameters = inspect.signature(func).parameters
  23. for key in parameters:
  24. if parameters[key].annotation.__name__ == 'bool':
  25. args[key] = bool(args[key])
  26. if parameters[key].annotation.__name__ == 'int':
  27. args[key] = int(args[key])
  28. elif parameters[key].annotation.__name__ == 'float':
  29. args[key] = float(args[key])
  30. elif parameters[key].annotation.__name__ == 'complex':
  31. args[key] = complex(args[key])
  32. if 'request' in parameters and 'request' not in args:
  33. args['request'] = request
  34. return func(**args)
  35. self.add_route(routing.Route(path, decorated))
  36. return decorated
  37. return decorator