-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/WP3_first_integration' into 'master'
Developed server side API connection to Service Data (WP3) See merge request caimira/caimira!453
- Loading branch information
Showing
4 changed files
with
171 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import dataclasses | ||
import json | ||
import logging | ||
|
||
from tornado.httpclient import AsyncHTTPClient, HTTPRequest | ||
|
||
LOG = logging.getLogger(__name__) | ||
|
||
|
||
@dataclasses.dataclass | ||
class DataService(): | ||
''' | ||
Responsible for establishing a connection to a | ||
database through a REST API by handling authentication | ||
and fetching data. It utilizes the Tornado web framework | ||
for asynchronous HTTP requests. | ||
''' | ||
# Credentials used for authentication | ||
credentials: dict | ||
|
||
# Host URL for the CAiMIRA Data Service API | ||
host: str = 'https://caimira-data-api.app.cern.ch' | ||
|
||
async def login(self): | ||
client_email = self.credentials["data_service_client_email"] | ||
client_password = self.credentials['data_service_client_password'] | ||
|
||
if (client_email == None or client_password == None): | ||
# If the credentials are not defined, an exception is raised. | ||
raise Exception("DataService credentials not set") | ||
|
||
http_client = AsyncHTTPClient() | ||
headers = {'Content-type': 'application/json'} | ||
json_body = { "email": f"{client_email}", "password": f"{client_password}"} | ||
|
||
response = await http_client.fetch(HTTPRequest( | ||
url=self.host + '/login', | ||
method='POST', | ||
headers=headers, | ||
body=json.dumps(json_body), | ||
), | ||
raise_error=True) | ||
|
||
return json.loads(response.body)['access_token'] | ||
|
||
async def fetch(self, access_token: str): | ||
http_client = AsyncHTTPClient() | ||
headers = {'Authorization': f'Bearer {access_token}'} | ||
|
||
response = await http_client.fetch(HTTPRequest( | ||
url=self.host + '/data', | ||
method='GET', | ||
headers=headers, | ||
), | ||
raise_error=True) | ||
|
||
return json.loads(response.body) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
from dataclasses import dataclass | ||
|
||
import unittest | ||
from unittest.mock import patch, MagicMock | ||
from tornado.httpclient import HTTPError | ||
|
||
from caimira.apps.calculator.data_service import DataService | ||
|
||
@dataclass | ||
class MockResponse: | ||
body: str | ||
|
||
class DataServiceTests(unittest.TestCase): | ||
def setUp(self): | ||
# Set up any necessary test data or configurations | ||
self.credentials = { | ||
"data_service_client_email": "[email protected]", | ||
"data_service_client_password": "password123" | ||
} | ||
self.data_service = DataService(self.credentials) | ||
|
||
@patch('caimira.apps.calculator.data_service.AsyncHTTPClient') | ||
async def test_login_successful(self, mock_http_client): | ||
# Mock successful login response | ||
mock_response = MockResponse('{"access_token": "dummy_token"}') | ||
mock_fetch = MagicMock(return_value=mock_response) | ||
mock_http_client.return_value.fetch = mock_fetch | ||
|
||
# Call the login method | ||
access_token = await self.data_service.login() | ||
|
||
# Assert that the access token is returned correctly | ||
self.assertEqual(access_token, "dummy_token") | ||
|
||
# Verify that the fetch method was called with the expected arguments | ||
mock_fetch.assert_called_once_with( | ||
url='https://caimira-data-api.app.cern.ch/login', | ||
method='POST', | ||
headers={'Content-type': 'application/json'}, | ||
body='{"email": "[email protected]", "password": "password123"}' | ||
) | ||
|
||
@patch('caimira.apps.calculator.data_service.AsyncHTTPClient') | ||
async def test_login_error(self, mock_http_client): | ||
# Mock login error response | ||
mock_fetch = MagicMock(side_effect=HTTPError(500)) | ||
mock_http_client.return_value.fetch = mock_fetch | ||
|
||
# Call the login method | ||
access_token = await self.data_service.login() | ||
|
||
# Assert that the login method returns None in case of an error | ||
self.assertIsNone(access_token) | ||
|
||
@patch('caimira.apps.calculator.data_service.AsyncHTTPClient') | ||
async def test_fetch_successful(self, mock_http_client): | ||
# Mock successful fetch response | ||
mock_response = MockResponse('{"data": "dummy_data"}') | ||
mock_fetch = MagicMock(return_value=mock_response) | ||
mock_http_client.return_value.fetch = mock_fetch | ||
|
||
# Call the fetch method with a mock access token | ||
access_token = "dummy_token" | ||
data = await self.data_service.fetch(access_token) | ||
|
||
# Assert that the data is returned correctly | ||
self.assertEqual(data, {"data": "dummy_data"}) | ||
|
||
# Verify that the fetch method was called with the expected arguments | ||
mock_fetch.assert_called_once_with( | ||
url='https://caimira-data-api.app.cern.ch/data', | ||
method='GET', | ||
headers={'Authorization': 'Bearer dummy_token'} | ||
) | ||
|
||
@patch('caimira.apps.calculator.data_service.AsyncHTTPClient') | ||
async def test_fetch_error(self, mock_http_client): | ||
# Mock fetch error response | ||
mock_fetch = MagicMock(side_effect=HTTPError(404)) | ||
mock_http_client.return_value.fetch = mock_fetch | ||
|
||
# Call the fetch method with a mock access token | ||
access_token = "dummy_token" | ||
data = await self.data_service.fetch(access_token) | ||
|
||
# Assert that the fetch method returns None in case of an error | ||
self.assertIsNone(data) |