Skip to content

Add generated Q Business client and integration tests#54

Open
Alan4506 wants to merge 2 commits intoawslabs:developfrom
Alan4506:feat/qbusiness-client
Open

Add generated Q Business client and integration tests#54
Alan4506 wants to merge 2 commits intoawslabs:developfrom
Alan4506:feat/qbusiness-client

Conversation

@Alan4506
Copy link
Copy Markdown
Contributor

@Alan4506 Alan4506 commented Apr 23, 2026

Description of changes:

This PR adds integration tests for the Q Business service client (aws-sdk-qbusiness), covering the following:

  • Non-streaming operation chat_sync
  • Bidirectional event streaming operation chat

The test structure and patterns follow the same conventions established in the Lex Runtime V2 integration tests (PR #51), including session-scoped conftest fixtures for resource setup/teardown and field-level assertions on event types.

Although the PR contains many files, most of them are generated by smithy-python codegen. Please mainly review the integration tests because they are the primary focus of this PR. The Smithy model, generated client code under src/, and pyproject.toml are included for reviewer convenience so that tests can be run locally. The actual client release will be handled by internal release automation (through a separate PR that uploads the model).

Here is the detailed file breakdown:

  • codegen/aws-models/qbusiness.json: Smithy model for the Q Business service.
  • clients/aws-sdk-qbusiness/src/: Generated client code. Included for reviewer convenience only; will be replaced by release automation.
  • clients/aws-sdk-qbusiness/pyproject.toml: Generated package configuration.
  • clients/aws-sdk-qbusiness/README.md: Generated package readme.
  • clients/aws-sdk-qbusiness/tests/__init__.py: Generated test package marker.
  • clients/aws-sdk-qbusiness/tests/test_protocol.py: Generated protocol test.
  • clients/aws-sdk-qbusiness/tests/integration/__init__.py: Defines REGION and create_qbusiness_client() helper shared across integration tests.
  • clients/aws-sdk-qbusiness/tests/integration/conftest.py: Session-scoped pytest fixture that creates a Q Business application, index, and retriever using boto3, and tears them down after. Uses custom botocore waiters since Q Business has no built-in boto3 waiters.
  • clients/aws-sdk-qbusiness/tests/integration/test_non_streaming.py: Tests the chat_sync operation.
  • clients/aws-sdk-qbusiness/tests/integration/test_bidirectional_streaming.py: Tests the chat operation.

Note: The Q Business client cannot be code-generated without the codegen fix in smithy-lang/smithy-python#682, which is still under review.

Note: The Q Business service sends event types (intermediateMessageEvent, intermediateGroupEvent) that are not present in the current model. These are handled as ChatOutputStreamUnknown thanks to a fix in smithy-python. The changes have been merged into the develop branch but have not been released yet. Tests will fail against the published PyPI versions until the next release.

To successfully run the tests locally, follow the steps below:

# Set up your AWS credentials, then:
cd <path-to-smithy-python>
git checkout develop && git pull
make build-py

# Set up and run Q Business integration tests
cd <path-to-aws-sdk-python>/clients/aws-sdk-qbusiness
uv venv .venv && source .venv/bin/activate
uv pip install --group test -e . boto3 --find-links <path-to-smithy-python>/dist
python -m pytest tests/integration

All tests should pass.

This branch will be rebased once the release automation publishes the client.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@Alan4506 Alan4506 requested a review from a team as a code owner April 23, 2026 15:08
Comment on lines +152 to +156
def qbusiness_app():
"""Create a Q Business application for the test session and delete it after."""
app_id = _create_qbusiness_app()
yield app_id
_delete_qbusiness_app(app_id)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If _create_qbusiness_app() fails after the application is created (during index or retriever creation), will _delete_qbusiness_app still run to clean up the application?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Updated the fixture to use try/finally so cleanup runs even if creation fails partway through. _delete_qbusiness_app now accepts None and returns early if no app was created. Since deleting the application cascades to its index and retriever, this handles all partial failure cases.

ChatInputStreamEndOfInputEvent(value=EndOfInputEvent())
)

await asyncio.sleep(1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why is the 1-second sleep needed after sending the input stream? Could you add a comment explaining the reason?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added a comment explaining the sleep. It gives the service time to process input events before we close the stream. The same pattern is used in the transcribe-streaming and bedrock-runtime bidirectional streaming tests (example). Tests will fail if we remove this.

"""Helper to create a QBusinessClient for a given region."""
return QBusinessClient(
config=Config(
endpoint_uri=f"https://qbusiness.{region}.api.aws",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is for my own understanding:

  • Why is the endpoint_uri hardcoded here? Is it not possible to resolve it automatically?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Currently we only have a StandardRegionalEndpointsResolver in smithy-aws-core that resolves {prefix}.{region}.amazonaws.com, but Q Business uses .api.aws instead of .amazonaws.com, so it doesn't work here. See smithy_aws_core/endpoints/standard_regional.py.

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