scalable-pypeline 1.1.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pypeline/cli/deploy.py ADDED
@@ -0,0 +1,138 @@
1
+ """ Command Line Utilities for Sermos Deployments
2
+ """
3
+ import logging
4
+ import click
5
+ from pypeline.deploy import SermosDeploy
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ @click.group()
11
+ def deployment():
12
+ """ Deployment command group.
13
+ """
14
+
15
+
16
+ @deployment.command()
17
+ @click.option('--pkg-name', required=False, default=None)
18
+ @click.option('--sermos-yaml', required=False, default=None)
19
+ @click.option('--output-file', required=False, default=None)
20
+ def validate(pkg_name: str = None,
21
+ sermos_yaml: str = None,
22
+ output_file: str = None):
23
+ """ Validate a compiled Sermos yaml is ready for deployment.
24
+
25
+ Arguments::
26
+
27
+ pkg-name (optional): Directory name for your Python package.
28
+ e.g. my_package_name If none provided, will check environment
29
+ for `SERMOS_CLIENT_PKG_NAME`. If not found, will exit.
30
+
31
+ sermos-yaml (optional): Path to find your `sermos.yaml`
32
+ configuration file. Defaults to `sermos.yaml`
33
+ """
34
+ # Instantiate SermosDeploy
35
+ sd = SermosDeploy(access_key='fake',
36
+ pkg_name=pkg_name,
37
+ sermos_yaml_filename=sermos_yaml)
38
+
39
+ # Validate deployment
40
+ sd.validate_deployment(output_file=output_file)
41
+ click.echo("Configuration is Valid and ready to Deploy.")
42
+
43
+
44
+ @deployment.command()
45
+ @click.option('--deployment-id', required=False, default=None)
46
+ @click.option('--access-key', required=False, default=None)
47
+ @click.option('--pkg-name', required=False, default=None)
48
+ @click.option('--sermos-yaml', required=False, default=None)
49
+ @click.option('--commit-hash', required=False, default=None)
50
+ @click.option('--base-url', required=False, default=None)
51
+ @click.option('--deploy-branch', required=False, default='main')
52
+ def deploy(deployment_id: str = None,
53
+ access_key: str = None,
54
+ pkg_name: str = None,
55
+ sermos_yaml: str = None,
56
+ commit_hash: str = None,
57
+ base_url: str = None,
58
+ deploy_branch: str = 'main'):
59
+ """ Invoke a Sermos build for your application.
60
+
61
+ Arguments:
62
+
63
+ deployment-id (optional): UUID for Deployment. Find in your Sermos
64
+ Cloud Console. Will look under `SERMOS_DEPLOYMENT_ID` in
65
+ environment if not provided.
66
+
67
+ access-key (optional): Defaults to checking the environment for
68
+ `SERMOS_ACCESS_KEY`. If not found, will exit.
69
+
70
+ pkg-name (optional): Directory name for your Python package.
71
+ e.g. my_package_name If none provided, will check environment
72
+ for `SERMOS_CLIENT_PKG_NAME`. If not found, will exit.
73
+
74
+ sermos-yaml (optional): Path to find your `sermos.yaml`
75
+ configuration file. Defaults to `sermos.yaml`
76
+
77
+ commit-hash (optional): The specific commit hash of your git repo
78
+ to deploy. If not provided, then current HEAD as of invocation
79
+ will be used. This is the default usage, and is useful in the
80
+ case of a CI/CD pipeline such that the Sermos deployment is
81
+ invoked after your integration passes.
82
+
83
+ base-url (optional): Defaults to primary Sermos Cloud base URL.
84
+ Only modify this if there is a specific, known reason to do so.
85
+
86
+ deploy-branch (optional): Defaults to 'main'. Only modify this
87
+ if there is a specific, known reason to do so.
88
+ """
89
+ # Instantiate SermosDeploy
90
+ sd = SermosDeploy(deployment_id=deployment_id,
91
+ access_key=access_key,
92
+ pkg_name=pkg_name,
93
+ sermos_yaml_filename=sermos_yaml,
94
+ commit_hash=commit_hash,
95
+ base_url=base_url,
96
+ deploy_branch=deploy_branch)
97
+
98
+ # Validate deployment
99
+ sd.validate_deployment()
100
+
101
+ # Invoke deployment
102
+ result = sd.invoke_deployment()
103
+ content = result.json()
104
+ if result.status_code < 300:
105
+ click.echo(content['data']['status'])
106
+ else:
107
+ logger.error(f"{content}")
108
+
109
+
110
+ @deployment.command()
111
+ @click.option('--deployment-id', required=False, default=None)
112
+ @click.option('--access-key', required=False, default=None)
113
+ @click.option('--base-url', required=False, default=None)
114
+ def status(deployment_id: str = None,
115
+ access_key: str = None,
116
+ base_url: str = None):
117
+ """ Check on the status of a Sermos build.
118
+
119
+ Arguments:
120
+ deployment-id (optional): UUID for Deployment. Find in your Sermos
121
+ Cloud Console. If not provided, looks in environment under
122
+ `SERMOS_DEPLOYMENT_ID`
123
+ access-key (optional): Defaults to checking the environment for
124
+ `SERMOS_ACCESS_KEY`. If not found, will exit.
125
+ base-url (optional): Defaults to primary Sermos Cloud base URL.
126
+ Only modify this if there is a specific, known reason to do so.
127
+ """
128
+ # Instantiate SermosDeploy
129
+ sd = SermosDeploy(deployment_id=deployment_id,
130
+ access_key=access_key,
131
+ base_url=base_url)
132
+
133
+ # Check deployment status
134
+ result = sd.get_deployment_status()
135
+ try:
136
+ click.echo(result['data']['results'])
137
+ except Exception as e:
138
+ logger.error(f"{result} / {e}")
pypeline/cloud.py ADDED
@@ -0,0 +1,80 @@
1
+ """ Base class for interacting with Sermos Cloud API.
2
+ """
3
+ import json
4
+ import logging
5
+ import requests
6
+ from pypeline.utils.config_utils import get_access_key, get_deployment_id
7
+ from pypeline.constants import DEFAULT_BASE_URL, DEPLOYMENTS_DEPLOY_URL,\
8
+ DEPLOYMENTS_SERVICES_URL
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class SermosCloud():
14
+ """ Primary Sermos Cloud class for interacting with API.
15
+ """
16
+ def __init__(self,
17
+ access_key: str = None,
18
+ base_url: str = None,
19
+ deployment_id: str = None):
20
+ """ Arguments:
21
+ access_key (optional): Access key, issued by Sermos, which is
22
+ tied to a `Deployment`. Defaults to checking the environment
23
+ for `SERMOS_ACCESS_KEY`. If not found, will exit.
24
+ base_url (optional): Defaults to primary Sermos Cloud API
25
+ endpoint (https://cloud.sermos.ai/api/v1/).
26
+ Only modify this if there is a specific, known reason to do so.
27
+ deployment_id: UUID for Deployment. Find in your Sermos
28
+ Cloud Console.
29
+ """
30
+ super(SermosCloud, self).__init__()
31
+ self.access_key = get_access_key(access_key)
32
+ self.base_url = base_url if base_url\
33
+ else DEFAULT_BASE_URL
34
+ try:
35
+ self.deployment_id = get_deployment_id(deployment_id)
36
+ except KeyError:
37
+ self.deployment_id = None # Not always required, so allow None ...
38
+
39
+ self.deploy_url = DEPLOYMENTS_DEPLOY_URL.format(
40
+ self.base_url, self.deployment_id)
41
+ self.services_url = DEPLOYMENTS_SERVICES_URL.format(
42
+ self.base_url, self.deployment_id)
43
+
44
+ # Note: Sermos Cloud's API expects `apikey`
45
+ self.headers = {
46
+ 'Content-Type': 'application/json',
47
+ 'apikey': self.access_key
48
+ }
49
+
50
+ def get(self, url: str, as_dict: bool = False):
51
+ """ Send a GET request to Sermos Cloud
52
+ """
53
+ r = requests.get(url, headers=self.headers)
54
+ if as_dict:
55
+ return r.json()
56
+ return r
57
+
58
+ def get_all(self, url: str, page: int = 0, page_size: int = 15):
59
+ """ Loop through all paginated results from a GET endpoint
60
+ """
61
+ new_results = True
62
+ results = []
63
+ while new_results:
64
+ this_url = f"{url}?page={page}&sort_order=DESC&page_size={page_size}"
65
+ r = requests.get(this_url, headers=self.headers).json()
66
+ new_results = r.get("data", {}).get("results", [])
67
+ results.extend(new_results)
68
+ page += 1
69
+
70
+ return {'data': {'results': results}, 'message': 'All Results'}
71
+
72
+ def post(self, url: str, payload: dict = None, as_dict: bool = False):
73
+ """ Send a POST request to Sermos Cloud
74
+ """
75
+ if payload is None:
76
+ payload = {}
77
+ r = requests.post(url, headers=self.headers, data=json.dumps(payload))
78
+ if as_dict:
79
+ return r.json()
80
+ return r
pypeline/constants.py ADDED
@@ -0,0 +1,139 @@
1
+ """ Sermos Constants
2
+ """
3
+ import os
4
+ from urllib.parse import urljoin
5
+
6
+ API_PATH_V1 = '/api/v1'
7
+
8
+ DEFAULT_RESULT_TTL = 86400 # seconds (1 day)
9
+ DEFAULT_TASK_TTL = 60 # seconds (1 minute)
10
+ DEFAULT_RETRY_TASK_MAX_TTL = 300
11
+ DEFAULT_MAX_RETRY = 10
12
+ DEFAULT_REGULATOR_TASK = 'sermos.celery.task_chain_regulator'
13
+ DEFAULT_SUCCESS_TASK = 'sermos.celery.pipeline_success'
14
+ DEFAULT_RETRY_TASK = 'sermos.celery.pipeline_retry'
15
+
16
+ CHAIN_SUCCESS_MSG = 'Chain built successfully ...'
17
+ CHAIN_FAILURE_MSG = 'Chain failed to build ...'
18
+
19
+ PIPELINE_RUN_WRAPPER_CACHE_KEY = 'sermos_{}_{}' # pipeline_id + execution_id
20
+ PIPELINE_RESULT_CACHE_KEY = 'sermos_result_{}' # execution_id
21
+
22
+ # Pipeline configurations and scheduled task configuration are cached in Redis
23
+ # temporarily (default to CONFIG_REFRESH_RATE (in seconds)).
24
+ # Each pipeline config/schedule config is specific to an individual deployment,
25
+ # however, we cache only with the pipeline_id here because the usage of this
26
+ # cache key is restricted to the redis instance associated with the deployment.
27
+ PIPELINE_CONFIG_CACHE_KEY = 'sermos_pipeline_config_{}' # pipeline_id
28
+ SCHEDULE_CONFIG_CACHE_KEY = 'sermos_schedule_config'
29
+ CONFIG_REFRESH_RATE = int(os.environ.get('CONFIG_REFRESH_RATE', 30)) # seconds
30
+
31
+ # TODO where on earth is this crazy time format coming from?
32
+ SCHEDULE_DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.%f'
33
+
34
+ AUTH_LOCK_KEY = os.environ.get('AUTH_LOCK_KEY', 'sermos-auth-lock')
35
+ AUTH_LOCK_DURATION = int(os.environ.get('AUTH_LOCK_DURATION', 30))
36
+
37
+ STORED_MODEL_KEY = '{}_{}{}'
38
+
39
+ # Yaml path is relative to package
40
+ SERMOS_YAML_PATH = os.environ.get('SERMOS_YAML_PATH', 'sermos.yaml')
41
+ SERMOS_ACCESS_KEY = os.environ.get('SERMOS_ACCESS_KEY', None)
42
+ SERMOS_CLIENT_PKG_NAME = os.environ.get('SERMOS_CLIENT_PKG_NAME', None)
43
+ SERMOS_DEPLOYMENT_ID = os.environ.get('SERMOS_DEPLOYMENT_ID', 'local')
44
+ LOCAL_DEPLOYMENT_VALUE = os.environ.get('LOCAL_DEPLOYMENT_VALUE', 'local')
45
+ DEFAULT_BASE_URL = os.environ.get('SERMOS_BASE_URL', 'https://console.sermos.ai')
46
+ if DEFAULT_BASE_URL != 'local':
47
+ DEFAULT_BASE_URL += '/api/v1/'
48
+ DEPLOYMENTS_URL = "{}deployments/{}"
49
+ DEPLOYMENTS_DEPLOY_URL = "{}deployments/{}/deploy"
50
+ DEPLOYMENTS_SERVICES_URL = "{}deployments/{}/services"
51
+ DEPLOYMENTS_SERVICE_URL = "{}deployments/{}/services/{}"
52
+ DEFAULT_AUTH_URL = urljoin(DEFAULT_BASE_URL, 'auth')
53
+ USING_SERMOS_CLOUD = DEFAULT_BASE_URL != LOCAL_DEPLOYMENT_VALUE
54
+ DEFAULT_CONFIG_RETRIEVAL_PAGE_SIZE = 25
55
+ # Default 'responses' dictionary when decorating endpoints with @api.doc()
56
+ # Extend as necessary.
57
+ API_DOC_RESPONSES = {
58
+ 200: {
59
+ 'code': 200,
60
+ 'description': 'Successful response.'
61
+ },
62
+ 400: {
63
+ 'code': 400,
64
+ 'description': 'Malformed request. Verify payload is correct.'
65
+ },
66
+ 401: {
67
+ 'code': 401,
68
+ 'description':
69
+ 'Unauthorized. Verify your API Key (`accesskey`) header.'
70
+ }
71
+ }
72
+
73
+ # Default 'params' dictionary when decorating endpoints with @api.doc()
74
+ # Extend as necessary.
75
+ API_DOC_PARAMS = {
76
+ 'accesskey': {
77
+ 'in': 'header',
78
+ 'name': 'accesskey',
79
+ 'description': 'Your API Consumer\'s `accesskey`',
80
+ 'type': 'string',
81
+ 'required': True
82
+ }
83
+ }
84
+
85
+ DEFAULT_OPENAPI_CONFIG = (
86
+ ('SWAGGER_UI_DOC_EXPANSION',
87
+ 'list'), ('API_DOCUMENTATION_TITLE',
88
+ 'Sermos API Specs'), ('API_DOCUMENTATION_DESCRIPTION',
89
+ 'Available API Endpoints'),
90
+ ('OPENAPI_VERSION', '3.0.2'), ('OPENAPI_URL_PREFIX',
91
+ '/api/v1'), ('OPENAPI_SWAGGER_APP_NAME',
92
+ 'Sermos - API Reference'),
93
+ ('OPENAPI_SWAGGER_UI_PATH',
94
+ '/docs'), ('OPENAPI_SWAGGER_BASE_TEMPLATE',
95
+ 'swagger/swagger_ui.html'), ('OPENAPI_SWAGGER_URL', '/docs'),
96
+ ('OPENAPI_SWAGGER_UI_URL',
97
+ 'https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.24.2/'),
98
+ ('EXPLAIN_TEMPLATE_LOADING', False))
99
+
100
+ # Rho Auth settings
101
+ DEFAULT_RHOAUTH_CONFIG = (
102
+ ('RHOAUTH_OIDC_CLIENT_ID',
103
+ os.environ.get('RHOAUTH_OIDC_CLIENT_ID',
104
+ os.environ.get('CLIENT_PKG_NAME', '').replace('_', '-'))),
105
+ ('RHOAUTH_OIDC_ISSUER',
106
+ os.environ.get('RHOAUTH_OIDC_ISSUER',
107
+ 'https://auth.rho.ai/auth/realms/sermos')),
108
+ ('RHOAUTH_OIDC_AUTH_ENDPOINT',
109
+ os.environ.get(
110
+ 'RHOAUTH_OIDC_AUTH_ENDPOINT',
111
+ 'https://auth.rho.ai/auth/realms/sermos/protocol/openid-connect/auth')
112
+ ),
113
+ ('RHOAUTH_OIDC_TOKEN_ENDPOINT',
114
+ os.environ.get(
115
+ 'RHOAUTH_OIDC_TOKEN_ENDPOINT',
116
+ 'https://auth.rho.ai/auth/realms/sermos/protocol/openid-connect/token'
117
+ )),
118
+ ('RHOAUTH_OIDC_JWKS_URI_ENDPOINT',
119
+ os.environ.get(
120
+ 'RHOAUTH_OIDC_JWKS_URI_ENDPOINT',
121
+ 'https://auth.rho.ai/auth/realms/sermos/protocol/openid-connect/certs'
122
+ )),
123
+ ('RHOAUTH_OIDC_END_SESSION_ENDPOINT',
124
+ os.environ.get(
125
+ 'RHOAUTH_OIDC_END_SESSION_ENDPOINT',
126
+ 'https://auth.rho.ai/auth/realms/sermos/protocol/openid-connect/logout'
127
+ )), ('RHOAUTH_OIDC_END_SESSION_REDIRECT_URI',
128
+ os.environ.get('RHOAUTH_OIDC_END_SESSION_REDIRECT_URI',
129
+ '/')), ('OAUTHLIB_INSECURE_TRANSPORT',
130
+ os.environ.get('OAUTHLIB_INSECURE_TRANSPORT',
131
+ 1)))
132
+
133
+
134
+ def create_model_key(model_prefix: str,
135
+ model_version: str,
136
+ model_postfix: str = ''):
137
+ """ Ensures we're consistently creating the keys for storing/retrieving.
138
+ """
139
+ return STORED_MODEL_KEY.format(model_prefix, model_version, model_postfix)
pypeline/deploy.py ADDED
@@ -0,0 +1,167 @@
1
+ """ Utilities for deploying applications to Sermos.
2
+
3
+ Example CLI Usage::
4
+
5
+ $ honcho run -e .env sermos deploy
6
+ $ honcho run -e .env sermos status
7
+
8
+ Example Programmatic Usage::
9
+
10
+ from sermos.deploy import SermosDeploy
11
+
12
+ sd = SermosDeploy(
13
+ os.environ.get("SERMOS_ACCESS_KEY", None),
14
+ pkg_name="sermos_demo_client"
15
+ )
16
+
17
+ # To Invoke
18
+ status = sd.invoke_deployment()
19
+ print(status)
20
+
21
+ # To Check Status:
22
+ status = sd.get_deployment_status()
23
+ print(status)
24
+
25
+ """
26
+ import subprocess
27
+ import base64
28
+ import logging
29
+
30
+ from pypeline.utils.module_utils import get_client_pkg_name
31
+ from pypeline.sermos_yaml import load_sermos_config
32
+ from pypeline.cloud import SermosCloud
33
+
34
+ logger = logging.getLogger(__name__)
35
+
36
+
37
+ class SermosDeploy(SermosCloud):
38
+ """ Primary Sermos Deployment class for invocation and status updates.
39
+ """
40
+ def __init__(self,
41
+ deployment_id: str = None,
42
+ access_key: str = None,
43
+ pkg_name: str = None,
44
+ sermos_yaml_filename: str = None,
45
+ commit_hash: str = None,
46
+ base_url: str = None,
47
+ deploy_branch: str = 'main'):
48
+ """ Arguments:
49
+ deployment_id (optional): UUID for Deployment. Find in your
50
+ Sermos Cloud Console.
51
+ access_key (optional): Access key, issued by Sermos, that
52
+ dictates the environment into which this request will be
53
+ deployed. Defaults to checking the environment for
54
+ `SERMOS_ACCESS_KEY`. If not found, will exit.
55
+ pkg_name (optional): Directory name for your Python
56
+ package. e.g. my_package_name . If none provided, will check
57
+ environment for `SERMOS_CLIENT_PKG_NAME`. If not found,
58
+ will exit.
59
+ sermos_yaml_filename (optional): Relative path to find your
60
+ `sermos.yaml` configuration file. Defaults to `sermos.yaml`
61
+ which should be found inside your `pkg_name`
62
+ commit_hash (optional): The specific commit hash of your git
63
+ repo to deploy. If not provided, then current HEAD as of
64
+ invocation will be used. This is the default usage, and is
65
+ useful in the case of a CI/CD pipeline such that the Sermos
66
+ deployment is invoked after your integration passes.
67
+ base_url (optional): Defaults to primary Sermos Cloud base URL.
68
+ Only modify this if there is a specific, known reason to do so.
69
+ deploy_branch (optional): Defaults to 'main'. Only modify this
70
+ if there is a specific, known reason to do so.
71
+
72
+ """
73
+ super().__init__(access_key, base_url, deployment_id)
74
+ self.pkg_name = get_client_pkg_name(pkg_name)
75
+ self.sermos_yaml_filename = sermos_yaml_filename
76
+ self.commit_hash = commit_hash
77
+ self.sermos_yaml = None # Established later, only on `invoke`
78
+ self.encoded_sermos_yaml = None # Established later, only on `invoke`
79
+ self.deploy_payload = None # Established later, only on `invoke`
80
+ self.deploy_branch = deploy_branch
81
+
82
+ def _set_commit_hash(self):
83
+ """ Retrieve the commit hash of the current git state and set to
84
+ current deployment object.
85
+ """
86
+ if self.commit_hash is None:
87
+ self.commit_hash = subprocess.check_output(
88
+ ["git", "rev-parse", "--verify",
89
+ "HEAD"]).strip().decode('utf-8')
90
+
91
+ def _set_encoded_sermos_yaml(self):
92
+ """ Provide the b64 encoded sermos.yaml file as part of request.
93
+ Primarily used to get the custom workers definitions, etc. so
94
+ the deployment endpoint can generate the values.yaml.
95
+ """
96
+ self.sermos_yaml = load_sermos_config(self.pkg_name,
97
+ self.sermos_yaml_filename,
98
+ as_dict=False)
99
+ self.encoded_sermos_yaml = base64.b64encode(
100
+ self.sermos_yaml.encode('utf-8')).decode('utf-8')
101
+
102
+ def _set_deploy_payload(self):
103
+ """ Set the deployment payload correctly.
104
+ """
105
+ self._set_commit_hash()
106
+ self._set_encoded_sermos_yaml()
107
+ self.deploy_payload = {
108
+ "sermos_yaml": self.encoded_sermos_yaml,
109
+ "commit_hash": self.commit_hash,
110
+ "deploy_branch": self.deploy_branch,
111
+ "client_package_name": self.pkg_name
112
+ }
113
+
114
+ def get_deployment_status(self):
115
+ """ Info on a specific deployment
116
+ """
117
+ resp = self.get(self.services_url)
118
+ services = resp.json().get('data', {}).get('results', [])
119
+ status_map = {
120
+ 'data': {
121
+ 'results': []
122
+ },
123
+ 'message': 'Status of all Deployment Services'
124
+ }
125
+ for service in services:
126
+ status_map['data']['results'].append({
127
+ 'service_id':
128
+ service['niceId'],
129
+ 'name':
130
+ service['name'],
131
+ 'status':
132
+ service['status']
133
+ })
134
+ return status_map
135
+
136
+ def validate_deployment(self, output_file: str = None):
137
+ """ Test rendering sermos.yaml and validate.
138
+ """
139
+ # Running this will raise an exception if something is invalid.
140
+ self._set_deploy_payload()
141
+
142
+ if output_file:
143
+ with open(output_file, 'w') as f:
144
+ f.write(self.sermos_yaml)
145
+
146
+ # Additional validation based on logical requirements (validation of
147
+ # the schemaa is handled by Marshmallow but there can be 'valid' entries
148
+ # that would result in a failed deployment, such as an invalid
149
+ # application under appConfig.appPath, for example)
150
+
151
+ return True
152
+
153
+ def invoke_deployment(self):
154
+ """ Invoke a Sermos AI Deployment
155
+
156
+ If no commit_hash was provided, use the "current" commit hash
157
+ of the client package during this invocation.
158
+
159
+ Required convention is that your client's python package
160
+ version number is specified in the file `my_package/__init__.py`
161
+ and is defined as a string assigned to the variable `__version__`,
162
+ e.g. `__version__ = '0.1.0'`
163
+ """
164
+ self._set_deploy_payload()
165
+
166
+ # Make request to your environment's endpoint
167
+ return self.post(self.deploy_url, self.deploy_payload)
pypeline/extensions.py ADDED
@@ -0,0 +1,16 @@
1
+ """ Initialize most extensions used throughout application
2
+ """
3
+ import logging
4
+
5
+ logger = logging.getLogger(__name__)
6
+
7
+ try:
8
+ # Client packages *should* provide a `sermos.yaml` file. This
9
+ # loads the configuration file with the provided name ofthe client
10
+ # package (e.g. sermos_demo_client)
11
+ from pypeline.sermos_yaml import load_client_config_and_version
12
+ sermos_config, sermos_client_version = load_client_config_and_version()
13
+ except Exception as e:
14
+ sermos_config = None
15
+ sermos_client_version = None
16
+ logger.warning("Unable to load client Sermos config ... {}".format(e))
@@ -0,0 +1,28 @@
1
+ """ Sermos' Flask Implementation and Tooling. Convenience imports here.
2
+ """
3
+ import logging
4
+
5
+ logger = logging.getLogger(__name__)
6
+
7
+ try:
8
+ from rho_web.smorest import Blueprint, Api
9
+ from rho_web.response import abort
10
+ except Exception as e:
11
+ logger.error("Unable to import Web services (Blueprint, API, abort)"
12
+ f" ... {e}")
13
+
14
+ try:
15
+ from flask_rhoauth import OpenIDConnect
16
+ except Exception as e:
17
+ oidc = None
18
+ OpenIDConnect = None
19
+ logging.info("Did not initialize oidc ... {}".format(e))
20
+ else:
21
+ if OpenIDConnect is not None:
22
+ oidc = OpenIDConnect()
23
+
24
+ try:
25
+ from pypeline.flask.flask_sermos import FlaskSermos
26
+ except Exception as e:
27
+ logger.exception("Unable to import Sermos services (FlaskSermos)"
28
+ f" ... {e}")
File without changes