Skip to content

Conversation

@Vox-Ben
Copy link
Contributor

@Vox-Ben Vox-Ben commented Feb 9, 2026

Description

Creates the SDS access module and integrates it with the controller.

Context

CDG requires the ability to obtain organisation ASIDs and endpoints from SDS. This provides that capability.

Type of changes

  • Refactoring (non-breaking change)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would change existing functionality)
  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • I have followed the code style of the project
  • I have added tests to cover my changes
  • I have updated the documentation accordingly
  • This PR is a result of pair or mob programming
  • Exceptions/Exclusions to coding standards (e.g. #noqa or #NOSONAR) are included within this Pull Request.

Sensitive Information Declaration

To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including PII (Personal Identifiable Information) / PID (Personal Identifiable Data) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter.

  • I confirm that neither PII/PID nor sensitive data are included in this PR and the codebase changes.

@Vox-Ben Vox-Ben requested a review from a team as a code owner February 9, 2026 09:50
@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Trivy gate: no Critical/High vulnerabilities.

Trivy Image Scan Summary

Image: 900119715266.dkr.ecr.eu-west-2.amazonaws.com/whoami:feature-gpcapim-258-sds-access-module

Severity Count
CRITICAL 0
HIGH 0
MEDIUM 0
LOW 1
UNKNOWN 0
Findings (top 50)
Severity ID Package Installed Fixed Source
LOW CVE-2026-1703 pip 25.3 26.0 Python

@github-actions
Copy link

github-actions bot commented Feb 10, 2026

Trivy gate: no Critical/High issues.

Trivy IaC (Terraform) Summary

Severity Count
CRITICAL 0
HIGH 0
MEDIUM 0
LOW 0
UNKNOWN 0
Findings (top 50)
Severity ID Title File

@sonarqubecloud
Copy link

@github-actions
Copy link

Deployment Complete

"urn:nhs:names:services:gpconnect:structured"
":fhir:operation:gpc.getstructuredrecord-1"
from gateway_api.common.common import (
ACCESS_RECORD_STRUCTURED_INTERACTION_ID as ARS_INTERACTION_ID,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Given this is now nicely defined in common, is it better to just rename in this module than alias?

ENDPOINT: Literal["Endpoint"] = "Endpoint"

# Default service interaction ID for GP Connect
DEFAULT_SERVICE_INTERACTION_ID = ACCESS_RECORD_STRUCTURED_INTERACTION_ID
Copy link
Collaborator

Choose a reason for hiding this comment

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

Now that this is imported from common, do we need this intermediate variable?

Comment on lines +116 to +117
self.base_url = base_url.rstrip("/")
self.timeout = timeout
Copy link
Collaborator

Choose a reason for hiding this comment

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

If this is defined locally, or passed from the controller can we be confident that it is already well formated?

Comment on lines +121 to +128
self.stub = SdsFhirApiStub()

# Use stub for now - use environment variable once we have one
# TODO: Put this back to using the environment variable
# if os.environ.get("STUB_SDS", None):
self.get_method: GetCallable = self.stub.get
# else:
# self.get_method: GetCallable = requests.get
Copy link
Collaborator

Choose a reason for hiding this comment

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

No functional change, but I think this is also part of the temporary code to point to the stub, so covered by the same comment.

Suggested change
self.stub = SdsFhirApiStub()
# Use stub for now - use environment variable once we have one
# TODO: Put this back to using the environment variable
# if os.environ.get("STUB_SDS", None):
self.get_method: GetCallable = self.stub.get
# else:
# self.get_method: GetCallable = requests.get
# Use stub for now - use environment variable once we have one
# TODO: Put this back to using the environment variable
# if os.environ.get("STUB_SDS", None):
self.stub = SdsFhirApiStub()
self.get_method: GetCallable = self.stub.get
# else:
# self.get_method: GetCallable = requests.get

asid = self._extract_identifier(device, self.ASID_SYSTEM)
party_key = self._extract_identifier(device, self.PARTYKEY_SYSTEM)

# Step 2: Get Endpoint to obtain endpoint URL
Copy link
Collaborator

Choose a reason for hiding this comment

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

This infers that party_key is only included in the response, and that is being used to determine if the we should also make a request to Endpoint. Is that correct?

timeout=timeout or self.timeout,
)

# TODO: Post-steel-thread we probably want a raise_for_status() here
Copy link
Collaborator

Choose a reason for hiding this comment

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

raise_for_status() may be the proportionate middle ground in steel thread. Let's disucss...

# --------------- internal helpers for result extraction -----------------

@staticmethod
def _extract_first_entry(
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 handling the case where we get more than one entry is more than we needed in Steel Thread, but no harm in handling it here


def test_sds_client_get_org_details_success(
stub: SdsFhirApiStub, # noqa: ARG001
mock_requests_get: dict[str, Any], # noqa: ARG001
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
mock_requests_get: dict[str, Any], # noqa: ARG001
mock_requests_get: dict[str, Any], # noqa: ARG001 retained throughout as this will be required again once temporary code tested class to direct all `get` to stub is removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants