Test Failed
Push — master ( e380d0...f5671d )
by W
02:58
created

st2api/st2api/app.py (1 issue)

1
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
from oslo_config import cfg
17
18
from st2api import config as st2api_config
19
from st2common import log as logging
20
from st2common.middleware.streaming import StreamingMiddleware
21
from st2common.middleware.error_handling import ErrorHandlingMiddleware
22
from st2common.middleware.cors import CorsMiddleware
23
from st2common.middleware.request_id import RequestIDMiddleware
24
from st2common.middleware.logging import LoggingMiddleware
25
from st2common.middleware.instrumentation import RequestInstrumentationMiddleware
26
from st2common.middleware.instrumentation import ResponseInstrumentationMiddleware
27
from st2common.router import Router
28
from st2common.util.monkey_patch import monkey_patch
29
from st2common.constants.system import VERSION_STRING
30
from st2common.service_setup import setup as common_setup
31
from st2common.util import spec_loader
32
from st2api.validation import validate_rbac_is_correctly_configured
33
34
LOG = logging.getLogger(__name__)
35
36
37
def setup_app(config={}):
0 ignored issues
show
Bug Best Practice introduced by
The default value {} might cause unintended side-effects.

Objects as default values are only created once in Python and not on each invocation of the function. If the default object is modified, this modification is carried over to the next invocation of the method.

# Bad:
# If array_param is modified inside the function, the next invocation will
# receive the modified object.
def some_function(array_param=[]):
    # ...

# Better: Create an array on each invocation
def some_function(array_param=None):
    array_param = array_param or []
    # ...
Loading history...
38
    LOG.info('Creating st2api: %s as OpenAPI app.', VERSION_STRING)
39
40
    is_gunicorn = config.get('is_gunicorn', False)
41
    if is_gunicorn:
42
        # Note: We need to perform monkey patching in the worker. If we do it in
43
        # the master process (gunicorn_config.py), it breaks tons of things
44
        # including shutdown
45
        monkey_patch()
46
47
        st2api_config.register_opts()
48
        # This should be called in gunicorn case because we only want
49
        # workers to connect to db, rabbbitmq etc. In standalone HTTP
50
        # server case, this setup would have already occurred.
51
        common_setup(service='api', config=st2api_config, setup_db=True,
52
                     register_mq_exchanges=True,
53
                     register_signal_handlers=True,
54
                     register_internal_trigger_types=True,
55
                     run_migrations=True,
56
                     config_args=config.get('config_args', None))
57
58
    # Additional pre-run time checks
59
    validate_rbac_is_correctly_configured()
60
61
    router = Router(debug=cfg.CONF.api.debug, auth=cfg.CONF.auth.enable,
62
                    is_gunicorn=is_gunicorn)
63
64
    spec = spec_loader.load_spec('st2common', 'openapi.yaml.j2')
65
    transforms = {
66
        '^/api/v1/$': ['/v1'],
67
        '^/api/v1/': ['/', '/v1/'],
68
        '^/api/v1/executions': ['/actionexecutions', '/v1/actionexecutions'],
69
        '^/api/exp/': ['/exp/']
70
    }
71
    router.add_spec(spec, transforms=transforms)
72
73
    app = router.as_wsgi
74
75
    # Order is important. Check middleware for detailed explanation.
76
    app = StreamingMiddleware(app, path_whitelist=['/v1/executions/*/output*'])
77
    app = ErrorHandlingMiddleware(app)
78
    app = CorsMiddleware(app)
79
    app = LoggingMiddleware(app, router)
80
    app = ResponseInstrumentationMiddleware(app, service_name='api')
81
    app = RequestIDMiddleware(app)
82
    app = RequestInstrumentationMiddleware(app, service_name='api')
83
84
    return app
85