aboutsummaryrefslogtreecommitdiffstats
path: root/functest/api/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'functest/api/server.py')
-rw-r--r--functest/api/server.py103
1 files changed, 103 insertions, 0 deletions
diff --git a/functest/api/server.py b/functest/api/server.py
new file mode 100644
index 00000000..1d47b0dc
--- /dev/null
+++ b/functest/api/server.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+"""
+Used to launch Functest RestApi
+
+"""
+
+import inspect
+import logging
+import socket
+from urlparse import urljoin
+import pkg_resources
+
+from flask import Flask
+from flask_restful import Api
+
+from functest.api.base import ApiResource
+from functest.api.common import api_utils
+from functest.api.database.db import BASE
+from functest.api.database.db import DB_SESSION
+from functest.api.database.db import ENGINE
+from functest.api.database.v1 import models
+from functest.api.urls import URLPATTERNS
+
+
+LOGGER = logging.getLogger(__name__)
+
+APP = Flask(__name__)
+API = Api(APP)
+
+
+@APP.teardown_request
+def shutdown_session(exception=None): # pylint: disable=unused-argument
+ """
+ To be called at the end of each request whether it is successful
+ or an exception is raised
+ """
+ DB_SESSION.remove()
+
+
+def get_resource(resource_name):
+ """ Obtain the required resource according to resource name """
+ name = ''.join(resource_name.split('_'))
+ return next((r for r in api_utils.itersubclasses(ApiResource)
+ if r.__name__.lower() == name))
+
+
+def get_endpoint(url):
+ """ Obtain the endpoint of url """
+ address = socket.gethostbyname(socket.gethostname())
+ return urljoin('http://{}:5000'.format(address), url)
+
+
+def api_add_resource():
+ """
+ The resource has multiple URLs and you can pass multiple URLs to the
+ add_resource() method on the Api object. Each one will be routed to
+ your Resource
+ """
+ for url_pattern in URLPATTERNS:
+ try:
+ API.add_resource(
+ get_resource(url_pattern.target), url_pattern.url,
+ endpoint=get_endpoint(url_pattern.url))
+ except StopIteration:
+ LOGGER.error('url resource not found: %s', url_pattern.url)
+
+
+def init_db():
+ """
+ Import all modules here that might define models so that
+ they will be registered properly on the metadata, and then
+ create a database
+ """
+ def func(subcls):
+ """ To check the subclasses of BASE"""
+ try:
+ if issubclass(subcls[1], BASE):
+ return True
+ except TypeError:
+ pass
+ return False
+ # pylint: disable=bad-builtin
+ subclses = filter(func, inspect.getmembers(models, inspect.isclass))
+ LOGGER.debug('Import models: %s', [subcls[1] for subcls in subclses])
+ BASE.metadata.create_all(bind=ENGINE)
+
+
+def main():
+ """Entry point"""
+ logging.config.fileConfig(pkg_resources.resource_filename(
+ 'functest', 'ci/logging.ini'))
+ LOGGER.info('Starting Functest server')
+ api_add_resource()
+ init_db()
+ APP.run(host='0.0.0.0')