1 # -*- coding: utf-8 -*-
3 # Copyright 2018 University of Bristol - High Performance Networks Research
7 # Contributors: Anderson Bravalheri, Dimitrios Gkounis, Abubakar Siddique
8 # Muqaddas, Navdeep Uniyal, Reza Nejabati and Dimitra Simeonidou
10 # Licensed under the Apache License, Version 2.0 (the "License"); you may
11 # not use this file except in compliance with the License. You may obtain
12 # a copy of the License at
14 # http://www.apache.org/licenses/LICENSE-2.0
16 # Unless required by applicable law or agreed to in writing, software
17 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
19 # License for the specific language governing permissions and limitations
22 # For those usages not covered by the Apache License, Version 2.0 please
23 # contact with: <highperformance-networks@bristol.ac.uk>
25 # Neither the name of the University of Bristol nor the names of its
26 # contributors may be used to endorse or promote products derived from
27 # this software without specific prior written permission.
29 # This work has been performed in the context of DCMS UK 5G Testbeds
30 # & Trials Programme and in the framework of the Metro-Haul project -
31 # funded by the European Commission under Grant number 761727 through the
32 # Horizon 2020 and 5G-PPP programmes.
35 from types
import MethodType
37 from bottle
import Bottle
41 """Decorator that stores route information, so creating the routes can be
44 This allows methods (OOP) with bottle.
47 method: HTTP verb (e.g. ``'get'``, ``'post'``, ``'put'``, ...)
48 path: URL path that will be handled by the callback
50 def __init__(self
, method
, path
, **kwargs
):
51 kwargs
['method'] = method
.upper()
52 self
.route_info
= (path
, kwargs
)
54 def __call__(self
, function
):
55 function
.route_info
= self
.route_info
59 class BaseHandler(object):
60 """Base class that allows isolated webapp implementation using Bottle,
61 when used in conjunction with the ``route`` decorator.
63 In this context, a ``Handler`` is meant to be a collection of Bottle
64 routes/callbacks related to a specific topic.
66 A ``Handler`` instance can produce a WSGI app that can be mounted or merged
67 inside another more general bottle app.
71 from http_tools.handler import Handler, route
72 from http_tools.errors import ErrorHandler
74 class MyHandler(Handler):
75 plugins = [ErrorHandler()]
76 url_base = '/my/url/base'
78 @route('GET', '/some/path/<var>')
79 def get_var(self, var):
82 app = MyHandler.wsgi_app
83 # ^ Webapp with a `GET /my/url/base/some/path/<var>` route
88 """String representing a path fragment to be prepended to the routes"""
91 """Bottle plugins to be installed when creating the WSGI app"""
95 """Create a WSGI app based on the implemented callbacks"""
103 members
= (getattr(self
, m
) for m
in dir(self
) if m
!= 'wsgi_app')
104 callbacks
= (m
for m
in members
105 if isinstance(m
, MethodType
) and hasattr(m
, 'route_info'))
107 for callback
in callbacks
:
108 path
, kwargs
= callback
.route_info
109 kwargs
.update(callback
=callback
, apply=self
.plugins
)
110 app
.route(self
.url_base
+ path
, **kwargs
)