From 6cc612107552a17c2b402d8d66da35fba70020cb Mon Sep 17 00:00:00 2001 From: Luis Aleixo Date: Fri, 16 Jun 2023 16:02:47 +0200 Subject: [PATCH] developed server side API connection to Service Data (WP3) --- app-config/calculator-app/app.sh | 3 ++ caimira/apps/calculator/__init__.py | 55 +++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/app-config/calculator-app/app.sh b/app-config/calculator-app/app.sh index 6a808f8c..15c94234 100755 --- a/app-config/calculator-app/app.sh +++ b/app-config/calculator-app/app.sh @@ -23,6 +23,9 @@ if [[ "$APP_NAME" == "calculator-app" ]]; then export "EXTRA_PAGES"="$EXTRA_PAGES" + export "DATA_SERVICE_CLIENT_EMAIL"="$DATA_SERVICE_CLIENT_EMAIL" + export "DATA_SERVICE_CLIENT_PASSWORD"="$DATA_SERVICE_CLIENT_PASSWORD" + echo "Starting the caimira webservice with: python -m caimira.apps.calculator ${args[@]}" python -m caimira.apps.calculator "${args[@]}" elif [[ "$APP_NAME" == "caimira-voila" ]]; then diff --git a/caimira/apps/calculator/__init__.py b/caimira/apps/calculator/__init__.py index b7e11c4c..49bd3b0c 100644 --- a/caimira/apps/calculator/__init__.py +++ b/caimira/apps/calculator/__init__.py @@ -44,6 +44,9 @@ LOG = logging.getLogger(__name__) class BaseRequestHandler(RequestHandler): + # Host URL for the CAiMIRA Data Service API + host: str = 'https://caimira-data-api.app.cern.ch' + async def prepare(self): """Called at the beginning of a request before `get`/`post`/etc.""" @@ -60,6 +63,47 @@ class BaseRequestHandler(RequestHandler): else: self.current_user = AnonymousUser() + async def data_service_connection(self): + client_email = self.settings["data_service_client_email"] + client_password = self.settings['data_service_client_password'] + + if (client_email == None or client_password == None): + # If the credentials are not defined, we skip the API Integration + return self.send_error(401) + + http_client = AsyncHTTPClient() + headers = {'Content-type': 'application/json'} + json_body = { "email": f"{client_email}", "password": f"{client_password}"} + + try: + response = await http_client.fetch(HTTPRequest( + url=self.host + '/login', + method='POST', + headers=headers, + body=json.dumps(json_body), + ), + raise_error=True) + except Exception as e: + print("Something went wrong: %s" % e) + + return json.loads(response.body)['access_token'] + + async def data_service_fetcher(self, access_token: str): + http_client = AsyncHTTPClient() + headers = {'Authorization': f'Bearer {access_token}'} + + try: + response = await http_client.fetch(HTTPRequest( + url=self.host + '/data', + method='GET', + headers=headers, + ), + raise_error=True) + except Exception as e: + print("Something went wrong: %s" % e) + + return json.loads(response.body) + def write_error(self, status_code: int, **kwargs) -> None: template = self.settings["template_environment"].get_template( "error.html.j2") @@ -105,6 +149,13 @@ class ConcentrationModel(BaseRequestHandler): pprint(requested_model_config) start = datetime.datetime.now() + # Data Service API Integration + try: + access_token = await self.data_service_connection() + service_data = await self.data_service_fetcher(access_token) + except Exception as e: + print("Something went wrong with the data service: %s" % e) + try: form = model_generator.FormData.from_dict(requested_model_config) except Exception as err: @@ -435,6 +486,10 @@ def make_app( arve_client_secret=os.environ.get('ARVE_CLIENT_SECRET', None), arve_api_key=os.environ.get('ARVE_API_KEY', None), + # Data Service API Credentials + data_service_client_email = os.environ.get('DATA_SERVICE_CLIENT_EMAIL', ''), + data_service_client_password = os.environ.get('DATA_SERVICE_CLIENT_PASSWORD', ''), + # Process parallelism controls. There is a balance between serving a single report # requests quickly or serving multiple requests concurrently. # The defaults are: handle one report at a time, and allow parallelism