Skip to content

Conversation

@JoshuaSBrown
Copy link
Collaborator

@JoshuaSBrown JoshuaSBrown commented Nov 5, 2025

Ticket

#1724

Description

How Has This Been Tested?

Artifacts (if appropriate):

Tasks

  • - A description of the PR has been provided, and a diagram included if it is a new feature.
  • - Formatter has been run
  • - CHANGELOG comment has been added
  • - Labels have been assigned to the pr
  • - A reviwer has been added
  • - A user has been assigned to work on the pr
  • - If new feature a unit test has been added

Summary by Sourcery

Add end-to-end support for authentication and repository creation in the mock core server and Python client, integrate mock core server into the build and CI pipelines, and add Python integration tests.

New Features:

  • Implement handlers for AuthenticateByPasswordRequest, AuthenticateByTokenRequest, GetAuthStatusRequest, and RepoCreateRequest in the mock core server
  • Expose manualAuthByPassword, manualAuthByToken, getAuthStatus, and repoCreate operations in the Python client

Enhancements:

  • Pre-populate session authentication keys and add detailed logging in AuthenticationManager
  • Centralize mock constants (credentials, tokens, repository metadata) in MockGlobals

Build:

  • Add BUILD_MOCK_CORE_SERVER option and integrate mock core server into CMake build and install targets
  • Include Dockerfile and install scripts for building and running the mock core server

CI:

  • Add GitLab CI jobs for building, image checking, and retagging the core-mock Docker image

Tests:

  • Add Python pytest-based integration tests for MessageLib and CommandLib
  • Include CMake support for running Python integration tests and update mock server test fixtures

Chores:

  • Rename mock core key files from mock-datafed-core-key to datafed-mock-core-key across scripts and code

@JoshuaSBrown JoshuaSBrown requested a review from nedvedba November 5, 2025 21:07
@JoshuaSBrown JoshuaSBrown self-assigned this Nov 5, 2025
@JoshuaSBrown JoshuaSBrown added Component: Python API Relates to Python API Type: Test Related to unit or integration testing labels Nov 5, 2025
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Nov 5, 2025

Reviewer's Guide

This PR extends the mock core server to handle password/token authentication and repo creation messages, integrates the mock core build into CMake and GitLab CI, adds Docker support, and introduces Python client integration tests for MessageLib and CommandLib.

Class diagram for updated mock core server authentication and repo creation

classDiagram
    class MockCoreServer {
        +handlePasswordAuth()
        +handleTokenAuth()
        +handleRepoCreate()
    }
    class AuthenticationManager {
        +verifyPassword()
        +verifyToken()
    }
    class ClientWorker {
        +processMessage()
        +processRepoCreate()
    }
    MockCoreServer --> AuthenticationManager : uses
    MockCoreServer --> ClientWorker : uses
Loading

File-Level Changes

Change Details Files
Extend mock core server with new message handlers and implementations
  • Injected IMockCoreServer reference in ClientWorker
  • Registered handlers for AuthenticateByPassword, AuthenticateByToken, GetAuthStatus, RepoCreate
  • Implemented procAuthenticateByPasswordRequest, procAuthenticateByTokenRequest, procGetAuthStatusRequest, procRepoCreate
  • Seeded AuthenticationManager with a session key and added logging for key lookup
tests/mock_core/source/ClientWorker.cpp
tests/mock_core/source/ClientWorker.hpp
tests/mock_core/source/AuthenticationManager.cpp
tests/mock_core/source/AuthenticationManager.hpp
tests/mock_core/source/MockGlobals.cpp
tests/mock_core/source/MockGlobals.hpp
Update CMake to build and install mock core server
  • Added BUILD_MOCK_CORE_SERVER option and conditional inclusion of mock_core
  • Configured CMakeLists in root, tests, and python package for integration tests
  • Set INSTALL_MOCK_CORE_SERVER variable
CMakeLists.txt
tests/CMakeLists.txt
python/datafed_pkg/CMakeLists.txt
Add GitLab CI jobs for mock core build and image checks
  • Introduced run-core-mock-build-job in stage_build.yml
  • Added check-core-mock-image in stage_image_check.yml
  • Added build_core_mock_image.yml and force_build_core_mock_image.yml under .gitlab/build
.gitlab/stage_build.yml
.gitlab/stage_image_check.yml
.gitlab/build/build_core_mock_image.yml
.gitlab/build/force_build_core_mock_image.yml
Provide Docker support and install scripts for mock core server
  • Created Dockerfile under tests/mock_core/docker to build mock-core image
  • Added entrypoint.sh for container startup logic
  • Added install_mock_core.sh to move and generate keys
tests/mock_core/docker/Dockerfile
tests/mock_core/docker/entrypoint.sh
scripts/install_mock_core.sh
Introduce Python integration tests for the Python client
  • Added test_MessageLib.py and test_CommandLib.py for API integration tests
  • Created mock_defaults.py to supply consistent test values
  • Added CMakeLists.txt for Python integration tests under tests/integration
python/datafed_pkg/tests/integration/test_MessageLib.py
python/datafed_pkg/tests/integration/test_CommandLib.py
python/datafed_pkg/tests/integration/mock_defaults.py
python/datafed_pkg/tests/integration/CMakeLists.txt

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `python/datafed_pkg/tests/integration/test_MessageLib.py:60-69` </location>
<code_context>
+class TestConnectionEstablishment:
</code_context>

<issue_to_address>
**suggestion (testing):** Missing tests for connection failures due to network issues.

Add tests simulating scenarios like unreachable server or blocked port to verify proper error handling and messaging.
</issue_to_address>

### Comment 2
<location> `python/datafed_pkg/tests/integration/test_MessageLib.py:188-197` </location>
<code_context>
+    def test_manual_auth_by_password_success(self, temp_key_files):
</code_context>

<issue_to_address>
**suggestion (testing):** No test for authentication with empty or None credentials.

Add tests for manual authentication with empty or None values for username, password, and token to verify proper handling of these cases.

Suggested implementation:

```python
    def test_manual_auth_by_password_success(self, temp_key_files):
        """Test successful manual authentication by password."""
        print(f"Test: Server public key: {temp_key_files['server_key']}")
        print(f"Test: Client public key: {Defaults.mock_python_client_public_key}")
        print(f"Test: Client private key: {Defaults.mock_python_client_private_key}")
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,

    def test_manual_auth_by_password_empty_username(self, temp_key_files):
        """Test manual authentication with empty username."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_password("", "valid_password")

    def test_manual_auth_by_password_empty_password(self, temp_key_files):
        """Test manual authentication with empty password."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_password("valid_username", "")

    def test_manual_auth_by_password_none_username(self, temp_key_files):
        """Test manual authentication with None username."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_password(None, "valid_password")

    def test_manual_auth_by_password_none_password(self, temp_key_files):
        """Test manual authentication with None password."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_password("valid_username", None)

    def test_manual_auth_by_token_empty_token(self, temp_key_files):
        """Test manual authentication with empty token."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_token("")

    def test_manual_auth_by_token_none_token(self, temp_key_files):
        """Test manual authentication with None token."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_token(None)

```

- If `authenticate_by_password` or `authenticate_by_token` do not raise exceptions for invalid input, you may need to adjust the assertion to check for a failed authentication result instead.
- Ensure `pytest` is imported at the top of the file if not already present: `import pytest`
- If your API uses a different error handling mechanism, adapt the test to match the expected behavior (e.g., check for return value or error code).
</issue_to_address>

### Comment 3
<location> `python/datafed_pkg/tests/integration/test_MessageLib.py:264-273` </location>
<code_context>
+            server_pub_key=temp_key_files['server_key'],
+        )
+    
+    def test_send_recv_synchronous(self, api_client):
+        """Test synchronous send/receive."""
+        # Create a test request (using GetAuthStatusRequest as example)
+        request = anon.GetAuthStatusRequest()
+        
+        # Send and receive
+        reply, msg_type = api_client.sendRecv(request)
+        
+        assert reply is not None
+        assert msg_type is not None
+    
+    def test_send_recv_with_custom_timeout(self, api_client):
+        """Test send/receive with custom timeout."""
+        request = anon.GetAuthStatusRequest()
</code_context>

<issue_to_address>
**suggestion (testing):** No test for message sending with invalid or malformed requests.

Add a test that sends a malformed or invalid request to verify the client properly handles errors.
</issue_to_address>

### Comment 4
<location> `python/datafed_pkg/tests/integration/test_MessageLib.py:252-261` </location>
<code_context>
+class TestMessaging:
</code_context>

<issue_to_address>
**suggestion (testing):** No test for timeout and retry logic in message sending.

Please add tests to cover scenarios where the server does not respond, ensuring timeout and retry logic are properly handled.

Suggested implementation:

```python
class TestMessaging:
    """Test message sending and receiving functionality."""

    @pytest.fixture
    def api_client(self, temp_key_files):
        """Create an API client for testing."""
        return MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
        )

    def test_message_send_timeout(self, api_client, mocker):
        """Test that message sending times out when server does not respond."""
        # Mock the internal send method to simulate no response (timeout)
        mocker.patch.object(api_client, "_send_message", side_effect=TimeoutError("Server did not respond"))

        with pytest.raises(TimeoutError, match="Server did not respond"):
            api_client.send_message("test_topic", "test_payload")

    def test_message_send_retry_logic(self, api_client, mocker):
        """Test that message sending retries on timeout and eventually fails after max retries."""
        # Simulate timeout for each retry attempt
        max_retries = 3
        mocker.patch.object(api_client, "_send_message", side_effect=TimeoutError("Server did not respond"))
        mocker.patch.object(api_client, "max_retries", max_retries)

        with pytest.raises(TimeoutError, match="Server did not respond"):
            api_client.send_message("test_topic", "test_payload")

        # Optionally, check that _send_message was called max_retries + 1 times (initial + retries)
        assert api_client._send_message.call_count == max_retries + 1

```

- Ensure that `api_client.send_message` and the internal `_send_message` method exist and implement timeout and retry logic. If not, you will need to add or adjust these methods in the MessageLib.API class.
- The `max_retries` attribute should be present in the API client. If not, add it or adjust the test accordingly.
- The `mocker` fixture is provided by pytest-mock. Make sure pytest-mock is installed and available in your test environment.
- Adjust the topic/payload and error types to match your actual implementation if they differ.
</issue_to_address>

### Comment 5
<location> `python/datafed_pkg/tests/integration/test_CommandLib.py:77-86` </location>
<code_context>
+class TestCommandLibRepo:
</code_context>

<issue_to_address>
**suggestion (testing):** No negative tests for repoCreate (e.g., missing required fields, invalid values).

Add tests for repoCreate to cover cases with missing or invalid fields to verify proper input validation and error handling.
</issue_to_address>

### Comment 6
<location> `python/datafed_pkg/tests/integration/test_CommandLib.py:114-116` </location>
<code_context>
+        assert repo.address == repo_create_options['address']
+        assert repo.endpoint == repo_create_options['endpoint']
+        assert repo.admin == repo_create_options['admins']
+        assert repo.type == repo_create_options['type']
+
+if __name__ == "__main__":
+    pytest.main([__file__, "-v"])
</code_context>

<issue_to_address>
**suggestion (testing):** No test for repoCreate with duplicate repo_id.

Add a test case for creating a repository with a duplicate ID and verify that the API responds correctly.
</issue_to_address>

### Comment 7
<location> `doc_source/source/dev/testing.rst:86-87` </location>
<code_context>
+=========================================
+
+The python client integration tests can be run by running a mock core service
+in either directly on the host, or by building it in an container and running
+the container.
+
</code_context>

<issue_to_address>
**issue (typo):** Change 'in an container' to 'in a container' for correct grammar.

Use 'in a container' for proper grammar.

```suggestion
in either directly on the host, or by building it in a container and running
the container.
```
</issue_to_address>

### Comment 8
<location> `doc_source/source/dev/testing.rst:90-91` </location>
<code_context>
+the container.
+
+If using CMake and Ctest to run the tests it will build the mock core service
+and run it outside of a container.  The guide below demonstrates the
+alternative or running the mock core service in a container.
+
+1. Build and Run python client against Mock Core Server
</code_context>

<issue_to_address>
**issue (typo):** Change 'alternative or running' to 'alternative of running' for correct phrasing.

Use 'alternative of running' for correct grammar.

```suggestion
and run it outside of a container.  The guide below demonstrates the
alternative of running the mock core service in a container.
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 188 to 196
def test_manual_auth_by_password_success(self, temp_key_files):
"""Test successful manual authentication by password."""
print(f"Test: Server public key: {temp_key_files['server_key']}")
print(f"Test: Client public key: {Defaults.mock_python_client_public_key}")
print(f"Test: Client private key: {Defaults.mock_python_client_private_key}")
api = MessageLib.API(
server_host=Defaults.mock_core_server_host,
server_port=Defaults.mock_core_server_port,
server_pub_key=temp_key_files['server_key'],
manual_auth=True,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): No test for authentication with empty or None credentials.

Add tests for manual authentication with empty or None values for username, password, and token to verify proper handling of these cases.

Suggested implementation:

    def test_manual_auth_by_password_success(self, temp_key_files):
        """Test successful manual authentication by password."""
        print(f"Test: Server public key: {temp_key_files['server_key']}")
        print(f"Test: Client public key: {Defaults.mock_python_client_public_key}")
        print(f"Test: Client private key: {Defaults.mock_python_client_private_key}")
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,

    def test_manual_auth_by_password_empty_username(self, temp_key_files):
        """Test manual authentication with empty username."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_password("", "valid_password")

    def test_manual_auth_by_password_empty_password(self, temp_key_files):
        """Test manual authentication with empty password."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_password("valid_username", "")

    def test_manual_auth_by_password_none_username(self, temp_key_files):
        """Test manual authentication with None username."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_password(None, "valid_password")

    def test_manual_auth_by_password_none_password(self, temp_key_files):
        """Test manual authentication with None password."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_password("valid_username", None)

    def test_manual_auth_by_token_empty_token(self, temp_key_files):
        """Test manual authentication with empty token."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_token("")

    def test_manual_auth_by_token_none_token(self, temp_key_files):
        """Test manual authentication with None token."""
        api = MessageLib.API(
            server_host=Defaults.mock_core_server_host,
            server_port=Defaults.mock_core_server_port,
            server_pub_key=temp_key_files['server_key'],
            manual_auth=True,
            client_pub_key=Defaults.mock_python_client_public_key,
            client_priv_key=Defaults.mock_python_client_private_key,
        )
        with pytest.raises(Exception):
            api.authenticate_by_token(None)
  • If authenticate_by_password or authenticate_by_token do not raise exceptions for invalid input, you may need to adjust the assertion to check for a failed authentication result instead.
  • Ensure pytest is imported at the top of the file if not already present: import pytest
  • If your API uses a different error handling mechanism, adapt the test to match the expected behavior (e.g., check for return value or error code).

Comment on lines 77 to 84
class TestCommandLibRepo:
"""Test various connection establishment scenarios."""

def test_successful_connection_with_key_files(self, command_lib_options, repo_create_options):
"""Test successful connection using key files."""
api = CommandLib.API(command_lib_options)

api.loginByPassword(Defaults.mock_authenticated_test_user, Defaults.test_user_password)

result = api.repoCreate(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): No negative tests for repoCreate (e.g., missing required fields, invalid values).

Add tests for repoCreate to cover cases with missing or invalid fields to verify proper input validation and error handling.

Comment on lines 114 to 116
assert repo.type == repo_create_options['type']

if __name__ == "__main__":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): No test for repoCreate with duplicate repo_id.

Add a test case for creating a repository with a duplicate ID and verify that the API responds correctly.

Comment on lines +86 to +87
in either directly on the host, or by building it in an container and running
the container.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (typo): Change 'in an container' to 'in a container' for correct grammar.

Use 'in a container' for proper grammar.

Suggested change
in either directly on the host, or by building it in an container and running
the container.
in either directly on the host, or by building it in a container and running
the container.

Comment on lines +90 to +91
and run it outside of a container. The guide below demonstrates the
alternative or running the mock core service in a container.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (typo): Change 'alternative or running' to 'alternative of running' for correct phrasing.

Use 'alternative of running' for correct grammar.

Suggested change
and run it outside of a container. The guide below demonstrates the
alternative or running the mock core service in a container.
and run it outside of a container. The guide below demonstrates the
alternative of running the mock core service in a container.

Comment on lines +36 to +44
COPY ./common ${BUILD_DIR}/common
COPY ./CMakeLists.txt ${BUILD_DIR}
COPY ./scripts/generate_datafed.sh ${BUILD_DIR}/scripts/
COPY ./scripts/install_mock_core.sh ${BUILD_DIR}/scripts/
COPY ./cmake ${BUILD_DIR}/cmake
COPY ./tests/mock_core/docker/entrypoint.sh ${BUILD_DIR}/tests/mock_core/docker/
COPY ./tests/mock ${BUILD_DIR}/tests/mock
COPY ./tests/mock_core/source ${BUILD_DIR}/tests/mock_core/source/
COPY ./tests/CMakeLists.txt ${BUILD_DIR}/tests/CMakeLists.txt
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these could be reordered to be more optimal but since no operations are happening in between I don't think it's necessary.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion!

@JoshuaSBrown JoshuaSBrown changed the title 1724 daps feature python client support task and direct response allocation create [DAPS-1724] - feature python client support task and direct response allocation create Nov 18, 2025
@JoshuaSBrown JoshuaSBrown force-pushed the 1724-DAPS-feature-python-client-support-task-and-direct-response-allocation-create branch from 0569ffb to 2d137bc Compare December 2, 2025 13:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component: Python API Relates to Python API Type: Test Related to unit or integration testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants