From 660c47d4878ae82f64424e42b816f85b93613ec1 Mon Sep 17 00:00:00 2001 From: Krishna Kumar Date: Sat, 20 Jan 2024 18:46:39 -0600 Subject: [PATCH] Authenticate and generate token for AgavePy --- .github/workflows/build-test.yml | 2 +- README.md | 4 +++ dapi/__init__.py | 2 ++ dapi/auth/__init__.py | 1 + dapi/auth/auth.py | 30 +++++++++++++++++++++ dapi/jobs/__init__.py | 2 +- pyproject.toml | 2 +- tests/auth/test_auth.py | 46 ++++++++++++++++++++++++++++++++ 8 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 dapi/auth/__init__.py create mode 100644 dapi/auth/auth.py create mode 100644 tests/auth/test_auth.py diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index a7b784a..f1edc4f 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -6,7 +6,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11"] + python-version: ["3.9"] poetry-version: ["1.6.1"] os: [ubuntu-latest] runs-on: ${{ matrix.os }} diff --git a/README.md b/README.md index 5e27237..1776098 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,10 @@ To run the unit test poetry run pytest -v ``` +## Known Issues + +The project only works on `Python 3.9` due to AgavePy Issue [#125](https://github.com/TACC/agavepy/issues/125). + ## License diff --git a/dapi/__init__.py b/dapi/__init__.py index cd4afbd..7d609d2 100644 --- a/dapi/__init__.py +++ b/dapi/__init__.py @@ -15,4 +15,6 @@ ``` """ +from . import auth +from . import db from . import jobs diff --git a/dapi/auth/__init__.py b/dapi/auth/__init__.py new file mode 100644 index 0000000..2d80ca4 --- /dev/null +++ b/dapi/auth/__init__.py @@ -0,0 +1 @@ +from .auth import init diff --git a/dapi/auth/auth.py b/dapi/auth/auth.py new file mode 100644 index 0000000..7cbd19c --- /dev/null +++ b/dapi/auth/auth.py @@ -0,0 +1,30 @@ +from agavepy.agave import Agave +from collections.abc import Mapping + + +def init(username, password): + """ + Initialize an Agave object with a new client and an active token. + + Args: + username (str): The username. + password (str): The password. + + Returns: + object: The Agave object. + """ + # Authenticate with Agave + ag = Agave( + base_url="https://agave.designsafe-ci.org", username=username, password=password + ) + # Create a new client + new_client = ag.clients_create() + # create a new ag object with the new client, at this point ag will have a new token + ag = Agave( + base_url="https://agave.designsafe-ci.org", + username=username, + password=password, + api_key=new_client["api_key"], + api_secret=new_client["api_secret"], + ) + return ag diff --git a/dapi/jobs/__init__.py b/dapi/jobs/__init__.py index 9c59b84..065a079 100644 --- a/dapi/jobs/__init__.py +++ b/dapi/jobs/__init__.py @@ -1,5 +1,5 @@ """ -`dapi` is a library that simplifies the process of submitting, running, and monitoring [TAPIS v2 / AgavePy](https://agavepy.readthedocs.io/en/latest/index.html) jobs on [DesignSafe](https://designsafe-ci.org) via [Jupyter Notebooks](https://jupyter.designsafe-ci.org). +`dapi` job submodule simplifies the process of submitting, running, and monitoring [TAPIS v2 / AgavePy](https://agavepy.readthedocs.io/en/latest/index.html) jobs on [DesignSafe](https://designsafe-ci.org) via [Jupyter Notebooks](https://jupyter.designsafe-ci.org). ## Features diff --git a/pyproject.toml b/pyproject.toml index b53ab56..cdfbf92 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ readme = "README.md" packages = [{include = "dapi"}] [tool.poetry.dependencies] -python = "^3.9" +python = "3.9.*" tqdm = "^4.66.1" agavepy = ">0.9.5" exceptiongroup = "^1.1.3" diff --git a/tests/auth/test_auth.py b/tests/auth/test_auth.py new file mode 100644 index 0000000..46255ab --- /dev/null +++ b/tests/auth/test_auth.py @@ -0,0 +1,46 @@ +import unittest +from unittest.mock import patch, MagicMock +from dapi.auth.auth import init + + +class TestAuthInit(unittest.TestCase): + @patch("dapi.auth.auth.Agave") + def test_init_success(self, mock_agave): + # Setup + username = "test_user" + password = "test_password" + mock_agave_obj = MagicMock() + mock_agave.return_value = mock_agave_obj + mock_agave_obj.clients_create.return_value = { + "api_key": "test_api_key", + "api_secret": "test_api_secret", + } + + # Execute + result = init(username, password) + + # Verify + mock_agave.assert_called_with( + base_url="https://agave.designsafe-ci.org", + username=username, + password=password, + api_key="test_api_key", + api_secret="test_api_secret", + ) + self.assertIsInstance(result, MagicMock) + + @patch("dapi.auth.auth.Agave") + def test_init_invalid_credentials(self, mock_agave): + # Setup + username = "invalid_user" + password = "invalid_password" + mock_agave.side_effect = Exception("Invalid credentials") + + # Execute & Verify + with self.assertRaises(Exception): + init(username, password) + + +# This allows running the test from the command line +if __name__ == "__main__": + unittest.main()