示例#1
0
def create_app():
    app = Vibora(router_strategy=RouterStrategy.CLONE)
    # app.configure_static_files()
    app.add_blueprint(bp_api)
    app.logger = logger

    job_queue = Queue(connection=StrictRedis.from_url(app_config.redis_conn))
    app.components.add(job_queue)

    return app
示例#2
0
    async def test_prefix_with_dynamic_route(self):
        app = Vibora()
        bp = Blueprint()

        @bp.route("/<name>")
        async def home(name: str):
            return JsonResponse({"name": name})

        app.add_blueprint(bp, prefixes={"test": "/test"})
        response = await app.test_client().request("/test/test")
        self.assertEqual(response.json(), {"name": "test"})
示例#3
0
def create_app(config_name):
    app = Vibora()

    @app.handle(Events.AFTER_ENDPOINT)
    async def before_response(response: Response):
        response.headers['x-my-custom-header'] = 'Hello :)'

    app.components.add(config[config_name]())

    app.add_blueprint(api, prefixes={'v1': '/v1'})

    return app
示例#4
0
class WebApp:
    def __init__(self, app):
        self.app = app
        print('\nInitializing Vibora webapp.')
        self.vibora = Vibora(static=StaticHandler(  # Add the statics handler
            paths=self.app.config.statics,
            url_prefix='/static',
            max_cache_size=1 * 1024 * 1024))
        print(f'Added static folders: {self.app.config.statics}')

        # Miyagi app and config should be avaiable in every handler
        self.vibora.components.add(self.app)
        self.vibora.components.add(self.app.config)

        # Make all the Miyagi webapp components
        self._make_gui()
        self._make_json_api()

    def _make_json_api(self):
        print('\nInitializing JsonApi routes:')
        # Import in function for it's a circular import
        from .apis.jsonapi import JsonApi
        self._make_blueprint('json_api', JsonApi)

    def _make_gui(self):
        print('\nInitializing Web frontend:')
        # Import in function for it's a circular import
        from .gui import Gui
        self._make_blueprint('web', Gui)

    def _make_blueprint(self, bp_name: str, bp: MiyagiBlueprint):
        # Make a blueprint
        vibora_bp = Blueprint()
        # Make it accessible in self
        setattr(self, bp_name, vibora_bp)
        # get all the routes in the given MiyagiBlueprint
        for route in bp(self.app).endpoints:
            # Register the route in the new blueprint
            self._add_route(vibora_bp, route)
        # Register the Blueprint in the Vibora App
        self.vibora.add_blueprint(vibora_bp)

    def _add_route(self, blueprint: Blueprint, route: MiyagiRoute):
        print(
            f'Adding route: {self.vibora.url_scheme}://{self.app.config.host}:{self.app.config.port}{route.uri}'
        )
        # Call the Vibora blueprint's decorator
        blueprint.route(route.uri, methods=route.methods)(route.handler)
示例#5
0
class BlueprintsTestCase(TestSuite):
    def setUp(self):
        self.app = Vibora(router_strategy=RouterStrategy.STRICT)

    async def test_simple_add_blueprint__expects_added(self):
        b1 = Blueprint()

        @b1.route('/')
        async def home():
            return Response(b'123')

        self.app.add_blueprint(b1)
        async with self.app.test_client() as client:
            response = await client.request('/')
            self.assertEqual(response.content, b'123')

    async def test_simple_add_blueprint_with_prefix_expects_added(self):
        b1 = Blueprint()

        @b1.route('/')
        async def home():
            return Response(b'123')

        self.app.add_blueprint(b1, prefixes={'home': '/home'})
        async with self.app.test_client() as client:
            response = await client.request('/home/')
            self.assertEqual(response.content, b'123')

    async def test_simple_add_nested_blueprints(self):
        b1 = Blueprint()
        b2 = Blueprint()

        @b2.route('/123')
        async def home():
            return Response(b'123')

        b1.add_blueprint(b2)
        self.app.add_blueprint(b1)
        async with self.app.test_client() as client:
            response = await client.request('/123')
            self.assertEqual(response.content, b'123')

    async def test_simple_add_nested_blueprints_with_prefixes(self):
        b1 = Blueprint()
        b2 = Blueprint()

        @b2.route('/123')
        async def home():
            return Response(b'123')

        b1.add_blueprint(b2, prefixes={'a': '/a', 'b': '/b'})
        self.app.add_blueprint(b1, prefixes={'a': '/a', 'b': '/b'})
        async with self.app.test_client() as client:
            response = await client.request('/a/a/123')
            self.assertEqual(response.content, b'123')
            response = await self.app.test_client().request('/b/b/123')
            self.assertEqual(response.content, b'123')
示例#6
0
class BlueprintsTestCase(TestSuite):
    def setUp(self):
        self.app = Vibora(router_strategy=RouterStrategy.STRICT)

    async def test_simple_add_blueprint__expects_added(self):
        b1 = Blueprint()

        @b1.route("/")
        async def home():
            return Response(b"123")

        self.app.add_blueprint(b1)
        async with self.app.test_client() as client:
            response = await client.request("/")
            self.assertEqual(response.content, b"123")

    async def test_simple_add_blueprint_with_prefix_expects_added(self):
        b1 = Blueprint()

        @b1.route("/")
        async def home():
            return Response(b"123")

        self.app.add_blueprint(b1, prefixes={"home": "/home"})
        async with self.app.test_client() as client:
            response = await client.request("/home/")
            self.assertEqual(response.content, b"123")

    async def test_simple_add_nested_blueprints(self):
        b1 = Blueprint()
        b2 = Blueprint()

        @b2.route("/123")
        async def home():
            return Response(b"123")

        b1.add_blueprint(b2)
        self.app.add_blueprint(b1)
        async with self.app.test_client() as client:
            response = await client.request("/123")
            self.assertEqual(response.content, b"123")

    async def test_simple_add_nested_blueprints_with_prefixes(self):
        b1 = Blueprint()
        b2 = Blueprint()

        @b2.route("/123")
        async def home():
            return Response(b"123")

        b1.add_blueprint(b2, prefixes={"a": "/a", "b": "/b"})
        self.app.add_blueprint(b1, prefixes={"a": "/a", "b": "/b"})
        async with self.app.test_client() as client:
            response = await client.request("/a/a/123")
            self.assertEqual(response.content, b"123")
            response = await self.app.test_client().request("/b/b/123")
            self.assertEqual(response.content, b"123")
示例#7
0
class WebApp:
    def __init__(self, app):
        self.app = app
        print('\nInitializing Vibora webapp.')
        self.vibora = Vibora(
            static=StaticHandler(paths=self.app.config.statics,
                                 url_prefix='/static',
                                 max_cache_size=1 * 1024 * 1024))
        self.vibora.components.add(self.app)
        self.vibora.components.add(self.app.config)
        print(f'Added static folders: {self.app.config.statics}')
        self._make_gui()
        self._make_json_api()

    def _make_json_api(self):
        print('\nInitializing JsonApi routes:')
        from .apis.jsonapi import JsonApi

        self.json_api = Blueprint()
        for route in JsonApi(self.app).endpoints:
            self._add_route(self.json_api, route)
        self.vibora.add_blueprint(self.json_api)

    def _make_gui(self):
        print('\nInitializing Web frontend:')
        from .gui import Gui

        self.web = Blueprint()
        for route in Gui(self.app).pages:
            self._add_route(self.web, route)
        self.vibora.add_blueprint(self.web)

    def _add_route(self, blueprint: Blueprint, route: MiyagiRoute):
        print(
            f'Adding route: {self.vibora.url_scheme}://{self.app.config.host}:{self.app.config.port}{route.uri}'
        )
        blueprint.route(route.uri, methods=route.methods)(route.handler)
示例#8
0
from vibora import Vibora
from vibora.router import RouterStrategy
from .api import api
from .user.views import user_api
from app.user.model import db

app = Vibora(router_strategy=RouterStrategy.CLONE)

app.add_blueprint(user_api, prefixes={'v1': '/v1'})
app.add_blueprint(api, prefixes={'v1': '/v1'})

db.bind(provider='sqlite', filename='database.sqlite', create_db=True)
db.generate_mapping(create_tables=True)
示例#9
0
class HooksTestSuite(TestSuite):
    def setUp(self):
        self.app = Vibora()

    async def test_simple_before_request_with_component(self):
        @self.app.handle(Events.BEFORE_ENDPOINT)
        def before_endpoint(request: Request):
            request.context['status_code'] = 200

        @self.app.route('/')
        async def home(request: Request):
            return Response(b'',
                            status_code=request.context.get(
                                'status_code', 500))

        async with self.app.test_client() as client:
            response = await client.get('/')
            self.assertEqual(response.status_code, 200)

    async def test_before_request_halting(self):
        @self.app.handle(Events.BEFORE_ENDPOINT)
        def before_endpoint():
            return Response(b'', status_code=200)

        @self.app.route('/')
        async def home():
            return Response(b'', status_code=500)

        async with self.app.test_client() as client:
            response = await client.get('/')
            self.assertEqual(response.status_code, 200)

    async def test_before_request_propagation(self):
        @self.app.handle(Events.BEFORE_ENDPOINT)
        def before_endpoint_1(request: Request):
            request.context['counter'] = 1

        @self.app.handle(Events.BEFORE_ENDPOINT)
        def before_endpoint_2(request: Request):
            request.context['counter'] += 1

        @self.app.route('/')
        async def home(request: Request):
            return Response(str(request.context['counter']).encode(),
                            status_code=500)

        async with self.app.test_client() as client:
            response = await client.get('/')
            self.assertEqual(response.content, b'2')

    async def test_before_server_start(self):
        secret = uuid.uuid4().hex.encode()

        class RuntimeConfig:
            def __init__(self):
                self.secret = secret

        @self.app.handle(Events.BEFORE_SERVER_START)
        def before_server_start(app: Vibora):
            app.components.add(RuntimeConfig())

        @self.app.route('/')
        async def home(request: Request):
            return Response(request.app.components.get(RuntimeConfig).secret,
                            status_code=200)

        async with self.app.test_client() as client:
            response = await client.get('/')
            self.assertEqual(secret, response.content)

    async def test_after_server_start(self):
        secret = uuid.uuid4().hex.encode()

        class RuntimeConfig:
            def __init__(self):
                self.secret = secret

        @self.app.route('/')
        async def home(request: Request):
            try:
                return Response(
                    request.app.components.get(RuntimeConfig).secret,
                    status_code=200)
            except MissingComponent:
                return Response(b'', status_code=500)

        @self.app.handle(Events.AFTER_SERVER_START)
        async def before_server_start(app: Vibora):
            await asyncio.sleep(1)
            app.components.add(RuntimeConfig())

        async with self.app.test_client() as client:
            # This must return an internal server error because the component is not registered yet
            # and the server is already online.
            response = await client.get('/')
            self.assertEqual(response.status_code, 500)

        # We wait a little to let the after_server_start hook finish his job.
        await asyncio.sleep(1)

        async with self.app.test_client() as client:
            response = await client.get('/')
            self.assertEqual(response.status_code, 200)
            self.assertEqual(secret, response.content)

    async def test_after_endpoint_modify_response(self):
        @self.app.route('/')
        async def home():
            return Response(b'', status_code=500)

        @self.app.handle(Events.AFTER_ENDPOINT)
        async def after_response(r: Response):
            r.status_code = 200

        async with self.app.test_client() as client:
            response = await client.get('/')
            self.assertEqual(response.status_code, 200)

    async def test_after_response_sent(self):
        class Mock:
            def __init__(self):
                self.test = 'test'

        @self.app.route('/')
        async def home(request: Request):
            try:
                request.app.components.get(Mock)
                return Response(b'Second')
            except Exception as error:
                return Response(str(error).encode(), status_code=500)

        @self.app.handle(Events.AFTER_RESPONSE_SENT)
        async def after_response_sent(app: Vibora):
            try:
                app.components.add(Mock())
            except ValueError:
                pass

        async with self.app.test_client() as client:
            response = await client.get('/')
            self.assertEqual(response.status_code, 500)
            await asyncio.sleep(0)
            response = await client.get('/')
            self.assertEqual(response.status_code, 200)

    async def test_before_server_stop_expects_polite_shutdown(self):
        """
        This test tries to ensure that the server will respect current streaming connections and
        give it some time before closing them so requests are closed abruptly.
        :return:
        """
        @self.app.route('/')
        async def home():
            async def slow_streaming():
                for _ in range(0, 5):
                    yield b'123'
                    await asyncio.sleep(1)

            return StreamingResponse(slow_streaming)

        async with self.app.test_client() as client:
            response = await client.get('/', stream=True)
            # This sends a kill signal to all workers, pretty much like someone is trying to stop the server.
            # Our HTTP client already sent the request but didn't consumed the response yet, the server must
            # respectfully wait for us.
            time.sleep(1)
            self.app.clean_up()
            await response.read_content()
            self.assertEqual(response.content, b'123' * 5)

    async def test_after_response_sent_called_from_blueprint(self):

        b1 = Blueprint()

        class Mock:
            def __init__(self):
                self.test = 'test'

        @b1.route('/')
        async def home(request: Request):
            try:
                request.app.components.get(Mock)
                return Response(b'Second')
            except Exception as error:
                return Response(str(error).encode(), status_code=500)

        @b1.handle(Events.AFTER_RESPONSE_SENT)
        async def after_response_sent(app: Vibora):
            try:
                app.components.add(Mock())
            except ValueError:
                pass

        self.app.add_blueprint(b1, prefixes={'v1': '/v1'})

        async with self.app.test_client() as client:
            response = await client.get('/v1')
            self.assertEqual(response.status_code, 500)
            await asyncio.sleep(0)
            response = await client.get('/v1')
            self.assertEqual(response.status_code, 200)

    async def test_before_response_called_from_blueprint(self):

        b1 = Blueprint()

        class Mock:
            def __init__(self):
                self.test = 'test'

        @b1.handle(Events.BEFORE_SERVER_START)
        async def after_response_sent(app: Vibora):
            try:
                app.components.add(Mock())
            except ValueError:
                pass

        @b1.route('/')
        async def home(mock: Mock):
            return Response(mock.test.encode())

        self.app.add_blueprint(b1, prefixes={'v1': '/v1'})

        async with self.app.test_client() as client:
            response = await client.get('/v1')
            self.assertEqual(response.status_code, 200)
示例#10
0
class BlueprintsTestCase(TestSuite):
    def setUp(self):
        self.app = Vibora()

    async def test_simple_sub_domain_expects_match(self):
        b1 = Blueprint(hosts=['.*'])

        @b1.route('/')
        async def home():
            return Response(b'123')

        self.app.add_blueprint(b1)
        with self.app.test_client() as client:
            response = await client.request('/')
            self.assertEqual(response.content, b'123')

    async def test_exact_match_sub_domain_expects_match(self):
        b1 = Blueprint(hosts=['test.vibora.io'])

        @b1.route('/')
        async def home():
            return Response(b'123')

        self.app.add_blueprint(b1)
        with self.app.test_client() as client:
            response = await client.request('/',
                                            headers={'Host': 'test.vibora.io'})
            self.assertEqual(response.content, b'123')

    async def test_different_sub_domain_expects_404(self):
        b1 = Blueprint(hosts=['test.vibora.io'])

        @b1.route('/')
        async def home():
            return Response(b'123')

        self.app.add_blueprint(b1)
        with self.app.test_client() as client:
            response = await client.request(
                '/', headers={'Host': 'test2.vibora.io'})
            self.assertEqual(response.status_code, 404)

    async def test_sub_domain_working_with_non_hosts_based(self):
        b1 = Blueprint(hosts=['test.vibora.io'])
        b2 = Blueprint()

        @b1.route('/')
        async def home():
            return Response(b'123')

        @b2.route('/test')
        async def home():
            return Response(b'123')

        self.app.add_blueprint(b1)
        self.app.add_blueprint(b2)
        with self.app.test_client() as client:
            response = await client.request('/',
                                            headers={'Host': 'test.vibora.io'})
            self.assertEqual(response.status_code, 200)
            response = await client.request(
                '/', headers={'Host': 'test2.vibora.io'})
            self.assertEqual(response.status_code, 404)
            response = await client.request(
                '/test', headers={'Host': 'anything.should.work'})
            self.assertEqual(response.status_code, 200)
            response = await client.request(
                '/test2', headers={'Host': 'anything.should.404'})
            self.assertEqual(response.status_code, 404)
示例#11
0
class ExceptionsTestCase(TestSuite):
    def setUp(self):
        self.app = Vibora()

    async def test_simple_exception_expects_handled(self):
        @self.app.route("/")
        async def home():
            raise Exception("Vibora ;)")

        @self.app.handle(Exception)
        async def handle_errors():
            return Response(b"Catch!", status_code=500)

        async with self.app.test_client() as client:
            response = await client.get("/")

        self.assertEqual(response.status_code, 500)
        self.assertEqual(response.content, b"Catch!")

    async def test_simple_exception_with_default_handler(self):
        @self.app.route("/")
        async def handle_errors():
            raise Exception("Vibora ;)")

        response = await self.app.test_client().request("/")
        self.assertEqual(response.status_code, 500)

    async def test_different_exception__expects_not_handled(self):
        class NewException(Exception):
            pass

        @self.app.route("/")
        async def handle_errors():
            raise Exception("Vibora ;)")

        @self.app.handle(NewException)
        async def handle_errors2():
            return Response(b"Catch!", status_code=500)

        response = await self.app.test_client().request("/")
        self.assertEqual(response.status_code, 500)
        self.assertNotEqual(response.content, b"Catch!")

    async def test_subclassed_exception__expects_handled(self):
        class ParentException(Exception):
            pass

        class ChildException(ParentException):
            pass

        @self.app.route("/")
        async def handle_errors():
            raise ChildException("Vibora ;)")

        @self.app.handle(ParentException)
        async def handle_errors2():
            return Response(b"Catch!", status_code=500)

        response = await self.app.test_client().request("/")
        self.assertEqual(response.status_code, 500)
        self.assertEqual(response.content, b"Catch!")

    async def test_specific_priority_exception_catch_expects_handled(self):
        class ParentException(Exception):
            pass

        class ChildException(ParentException):
            pass

        @self.app.route("/")
        async def handle_errors():
            raise ChildException("Vibora ;)")

        @self.app.handle(ParentException)
        async def handle_errors2():
            return Response(b"Parent!", status_code=500)

        @self.app.handle(ChildException)
        async def handle_errors3():
            return Response(b"Child!", status_code=500)

        response = await self.app.test_client().request("/")
        self.assertEqual(response.status_code, 500)
        self.assertEqual(response.content, b"Child!")

    async def test_harder_subclass_exception_catch_expects_handled(self):
        class ExceptionA(Exception):
            pass

        class ExceptionB(ExceptionA):
            pass

        class ExceptionC(ExceptionB):
            pass

        @self.app.route("/")
        async def handle_errors():
            raise ExceptionC("Vibora ;)")

        @self.app.handle(ExceptionA)
        async def handle_errors2():
            return Response(b"Wrong!", status_code=500)

        @self.app.handle(ExceptionB)
        async def handle_errors3():
            return Response(b"Correct!", status_code=500)

        response = await self.app.test_client().request("/")
        self.assertEqual(response.status_code, 500)
        self.assertEqual(response.content, b"Correct!")

    async def test_blueprint_exception_propagation(self):
        b1 = Blueprint()

        class ExceptionA(Exception):
            pass

        class ExceptionB(ExceptionA):
            pass

        class ExceptionC(ExceptionB):
            pass

        @b1.route("/")
        async def handle_errors():
            raise ExceptionC("Vibora ;)")

        @self.app.handle(ExceptionA)
        async def handle_errors2():
            return Response(b"Wrong!", status_code=500)

        @self.app.handle(ExceptionB)
        async def handle_errors3():
            return Response(b"Correct!", status_code=500)

        self.app.add_blueprint(b1, prefixes={"": ""})

        response = await self.app.test_client().request("/")
        self.assertEqual(response.status_code, 500)
        self.assertEqual(response.content, b"Correct!")

    async def test_nested_blueprint_exception_propagation(self):
        b1 = Blueprint()
        b2 = Blueprint()

        class ExceptionA(Exception):
            pass

        @b2.route("/")
        async def handle_errors():
            raise ExceptionA("Vibora ;)")

        @self.app.handle(ExceptionA)
        async def handle_errors2():
            return Response(b"Wrong!", status_code=500)

        b1.add_blueprint(b2, prefixes={"": ""})
        self.app.add_blueprint(b1, prefixes={"": ""})

        response = await self.app.test_client().request("/")
        self.assertEqual(response.status_code, 500)
        self.assertEqual(response.content, b"Wrong!")

    async def test_nested_blueprint_exception_propagation_conflicts(self):
        b1 = Blueprint()
        b2 = Blueprint()

        class ExceptionA(Exception):
            pass

        @b2.route("/")
        async def handle_errors():
            raise ExceptionA("Vibora ;)")

        @self.app.handle(ExceptionA)
        async def handle_errors2():
            return Response(b"Wrong!", status_code=500)

        b1.add_blueprint(b2, prefixes={"": ""})
        self.app.add_blueprint(b1, prefixes={"": ""})

        response = await self.app.test_client().request("/")
        self.assertEqual(response.status_code, 500)
        self.assertEqual(response.content, b"Wrong!")

    async def test_multiple_exceptions_at_a_single_handle(self):
        b1 = Blueprint()
        b2 = Blueprint()

        class ExceptionA(Exception):
            pass

        @b2.route("/")
        async def handle_errors():
            raise ExceptionA("Vibora ;)")

        @self.app.handle((IOError, ExceptionA))
        async def handle_errors2():
            return Response(b"Correct!", status_code=500)

        b1.add_blueprint(b2, prefixes={"": ""})
        self.app.add_blueprint(b1, prefixes={"": ""})

        response = await self.app.test_client().request("/")
        self.assertEqual(response.status_code, 500)
        self.assertEqual(response.content, b"Correct!")

    async def test_exception_flow_expects_parent_response(self):
        @self.app.route("/")
        async def handle_errors():
            raise IOError("Vibora ;)")

        @self.app.handle(IOError)
        async def handle_io(request: Request):
            request.context["called"] = True

        @self.app.handle(Exception)
        async def handle_errors2(request: Request):
            return JsonResponse({"called": request.context.get("called")},
                                status_code=500)

        async with self.app.test_client() as client:
            response = await client.request("/")

        self.assertEqual(response.status_code, 500)
        self.assertDictEqual(response.json(), {"called": True})
示例#12
0
class BlueprintsTestCase(TestSuite):
    def setUp(self):
        self.app = Vibora()

    async def test_simple_sub_domain_expects_match(self):
        b1 = Blueprint(hosts=[".*"])

        @b1.route("/")
        async def home():
            return Response(b"123")

        self.app.add_blueprint(b1)
        async with self.app.test_client() as client:
            response = await client.request("/")
            self.assertEqual(response.content, b"123")

    async def test_exact_match_sub_domain_expects_match(self):
        b1 = Blueprint(hosts=["test.vibora.io"])

        @b1.route("/")
        async def home():
            return Response(b"123")

        self.app.add_blueprint(b1)
        async with self.app.test_client() as client:
            response = await client.request("/",
                                            headers={"Host": "test.vibora.io"})
            self.assertEqual(response.content, b"123")

    async def test_different_sub_domain_expects_404(self):
        b1 = Blueprint(hosts=["test.vibora.io"])

        @b1.route("/")
        async def home():
            return Response(b"123")

        self.app.add_blueprint(b1)
        async with self.app.test_client() as client:
            response = await client.request(
                "/", headers={"Host": "test2.vibora.io"})
            self.assertEqual(response.status_code, 404)

    async def test_sub_domain_working_with_non_hosts_based(self):
        b1 = Blueprint(hosts=["test.vibora.io"])
        b2 = Blueprint()

        @b1.route("/")
        async def home():
            return Response(b"123")

        @b2.route("/test")
        async def home2():
            return Response(b"123")

        self.app.add_blueprint(b1)
        self.app.add_blueprint(b2)
        async with self.app.test_client() as client:
            response = await client.request("/",
                                            headers={"Host": "test.vibora.io"})
            self.assertEqual(response.status_code, 200)
            response = await client.request(
                "/", headers={"Host": "test2.vibora.io"})
            self.assertEqual(response.status_code, 404)
            response = await client.request(
                "/test", headers={"Host": "anything.should.work"})
            self.assertEqual(response.status_code, 200)
            response = await client.request(
                "/test2", headers={"Host": "anything.should.404"})
            self.assertEqual(response.status_code, 404)
示例#13
0
文件: run.py 项目: wulfnb/vibora-old
from vibora import Vibora
from vibora.responses import JsonResponse
from samples.blueprints.v1.routes import v1
from samples.blueprints.v2.routes import v2

app = Vibora()


@app.route('/')
def home():
    return JsonResponse({'a': 1})


@app.handle(404)
def handle_anything():
    app.url_for('')
    return JsonResponse({'global': 'handler'})


if __name__ == '__main__':
    v1.add_blueprint(v2, prefixes={'v2': '/v2'})
    app.add_blueprint(v1, prefixes={'v1': '/v1', '': '/'})
    app.add_blueprint(v2, prefixes={'v2': '/v2'})
    app.run(debug=True, port=8000, host='0.0.0.0', workers=1)