This is page 382 of 384. Use http://codebase.md/awslabs/mcp?page={x} to view the full context.
# Directory Structure
```
├── .devcontainer
│ └── devcontainer.json
├── .github
│ ├── actions
│ │ ├── build-and-push-container-image
│ │ │ └── action.yml
│ │ └── clear-space-ubuntu-latest-agressively
│ │ └── action.yml
│ ├── codecov.yml
│ ├── CODEOWNERS
│ ├── dependabot.yml
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.yml
│ │ ├── documentation.yml
│ │ ├── feature_request.yml
│ │ ├── rfc.yml
│ │ └── support_awslabs_mcp_servers.yml
│ ├── pull_request_template.md
│ ├── SECURITY
│ ├── SUPPORT
│ └── workflows
│ ├── aws-api-mcp-upgrade-version.yml
│ ├── bandit-requirements.txt
│ ├── bandit.yml
│ ├── cfn_nag.yml
│ ├── check-gh-pages-builds.yml
│ ├── check-license-header-hash.txt
│ ├── check-license-header.json
│ ├── check-license-header.yml
│ ├── checkov.yml
│ ├── codeql.yml
│ ├── dependency-review-action.yml
│ ├── detect-secrets-requirements.txt
│ ├── gh-pages.yml
│ ├── merge-prevention.yml
│ ├── powershell.yml
│ ├── pre-commit-requirements.txt
│ ├── pre-commit.yml
│ ├── pull-request-lint.yml
│ ├── python.yml
│ ├── RELEASE_INSTRUCTIONS.md
│ ├── release-initiate-branch.yml
│ ├── release-merge-tag.yml
│ ├── release.py
│ ├── release.yml
│ ├── scanners.yml
│ ├── scorecard-analysis.yml
│ ├── semgrep-requirements.txt
│ ├── semgrep.yml
│ ├── stale.yml
│ ├── trivy.yml
│ └── typescript.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .python-version
├── .ruff.toml
├── .secrets.baseline
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── DESIGN_GUIDELINES.md
├── DEVELOPER_GUIDE.md
├── docs
│ └── images
│ └── root-readme
│ ├── cline-api-provider-filled.png
│ ├── cline-chat-interface.png
│ ├── cline-custom-instructions.png
│ ├── cline-select-aws-profile.png
│ ├── cline-select-bedrock.png
│ ├── configure-mcp-servers.png
│ ├── install-cline-extension.png
│ ├── mcp-servers-installed.png
│ └── select-mcp-servers.png
├── docusaurus
│ ├── .gitignore
│ ├── docs
│ │ ├── installation.md
│ │ ├── intro.md
│ │ ├── samples
│ │ │ ├── index.md
│ │ │ ├── mcp-integration-with-kb.md
│ │ │ ├── mcp-integration-with-nova-canvas.md
│ │ │ └── stepfunctions-tool-mcp-server.md
│ │ ├── servers
│ │ │ ├── amazon-bedrock-agentcore-mcp-server.md
│ │ │ ├── amazon-keyspaces-mcp-server.md
│ │ │ ├── amazon-mq-mcp-server.md
│ │ │ ├── amazon-neptune-mcp-server.md
│ │ │ ├── amazon-qbusiness-anonymous-mcp-server.md
│ │ │ ├── amazon-qindex-mcp-server.md
│ │ │ ├── amazon-sns-sqs-mcp-server.md
│ │ │ ├── aurora-dsql-mcp-server.md
│ │ │ ├── aws-api-mcp-server.md
│ │ │ ├── aws-appsync-mcp-server.md
│ │ │ ├── aws-bedrock-custom-model-import-mcp-server.md
│ │ │ ├── aws-bedrock-data-automation-mcp-server.md
│ │ │ ├── aws-dataprocessing-mcp-server.md
│ │ │ ├── aws-diagram-mcp-server.md
│ │ │ ├── aws-documentation-mcp-server.md
│ │ │ ├── aws-healthomics-mcp-server.md
│ │ │ ├── aws-iot-sitewise-mcp-server.md
│ │ │ ├── aws-knowledge-mcp-server.md
│ │ │ ├── aws-location-mcp-server.md
│ │ │ ├── aws-msk-mcp-server.md
│ │ │ ├── aws-pricing-mcp-server.md
│ │ │ ├── aws-serverless-mcp-server.md
│ │ │ ├── aws-support-mcp-server.md
│ │ │ ├── bedrock-kb-retrieval-mcp-server.md
│ │ │ ├── billing-cost-management-mcp-server.md
│ │ │ ├── ccapi-mcp-server.md
│ │ │ ├── cdk-mcp-server.md
│ │ │ ├── cfn-mcp-server.md
│ │ │ ├── cloudtrail-mcp-server.md
│ │ │ ├── cloudwatch-appsignals-mcp-server.md
│ │ │ ├── cloudwatch-mcp-server.md
│ │ │ ├── code-doc-gen-mcp-server.md
│ │ │ ├── core-mcp-server.md
│ │ │ ├── cost-explorer-mcp-server.md
│ │ │ ├── documentdb-mcp-server.md
│ │ │ ├── dynamodb-mcp-server.md
│ │ │ ├── ecs-mcp-server.md
│ │ │ ├── eks-mcp-server.md
│ │ │ ├── elasticache-mcp-server.md
│ │ │ ├── finch-mcp-server.md
│ │ │ ├── frontend-mcp-server.md
│ │ │ ├── git-repo-research-mcp-server.md
│ │ │ ├── healthlake-mcp-server.md
│ │ │ ├── iam-mcp-server.md
│ │ │ ├── kendra-index-mcp-server.md
│ │ │ ├── lambda-tool-mcp-server.md
│ │ │ ├── memcached-mcp-server.md
│ │ │ ├── mysql-mcp-server.md
│ │ │ ├── nova-canvas-mcp-server.md
│ │ │ ├── openapi-mcp-server.md
│ │ │ ├── postgres-mcp-server.md
│ │ │ ├── prometheus-mcp-server.md
│ │ │ ├── redshift-mcp-server.md
│ │ │ ├── s3-tables-mcp-server.md
│ │ │ ├── stepfunctions-tool-mcp-server.md
│ │ │ ├── syntheticdata-mcp-server.md
│ │ │ ├── terraform-mcp-server.md
│ │ │ ├── timestream-for-influxdb-mcp-server.md
│ │ │ ├── valkey-mcp-server.md
│ │ │ └── well-architected-security-mcp-server.mdx
│ │ └── vibe_coding.md
│ ├── docusaurus.config.ts
│ ├── package-lock.json
│ ├── package.json
│ ├── README.md
│ ├── sidebars.ts
│ ├── src
│ │ ├── components
│ │ │ ├── HomepageFeatures
│ │ │ │ └── styles.module.css
│ │ │ └── ServerCards
│ │ │ ├── index.tsx
│ │ │ └── styles.module.css
│ │ ├── css
│ │ │ ├── custom.css
│ │ │ └── doc-override.css
│ │ └── pages
│ │ ├── index.module.css
│ │ └── servers.tsx
│ ├── static
│ │ ├── .nojekyll
│ │ ├── assets
│ │ │ ├── icons
│ │ │ │ ├── activity.svg
│ │ │ │ ├── book-open.svg
│ │ │ │ ├── cpu.svg
│ │ │ │ ├── database.svg
│ │ │ │ ├── dollar-sign.svg
│ │ │ │ ├── help-circle.svg
│ │ │ │ ├── key.svg
│ │ │ │ ├── server.svg
│ │ │ │ ├── share-2.svg
│ │ │ │ ├── tool.svg
│ │ │ │ └── zap.svg
│ │ │ └── server-cards.json
│ │ └── img
│ │ ├── aws-logo.svg
│ │ └── logo.png
│ └── tsconfig.json
├── LICENSE
├── NOTICE
├── README.md
├── samples
│ ├── mcp-integration-with-kb
│ │ ├── .env.example
│ │ ├── .python-version
│ │ ├── assets
│ │ │ └── simplified-mcp-flow-diagram.png
│ │ ├── clients
│ │ │ └── client_server.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── user_interfaces
│ │ │ └── chat_bedrock_st.py
│ │ └── uv.lock
│ ├── mcp-integration-with-nova-canvas
│ │ ├── .env.example
│ │ ├── .python-version
│ │ ├── clients
│ │ │ └── client_server.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── user_interfaces
│ │ │ └── image_generator_st.py
│ │ └── uv.lock
│ ├── README.md
│ └── stepfunctions-tool-mcp-server
│ ├── README.md
│ └── sample_state_machines
│ ├── customer-create
│ │ └── app.py
│ ├── customer-id-from-email
│ │ └── app.py
│ ├── customer-info-from-id
│ │ └── app.py
│ └── template.yml
├── src
│ ├── amazon-bedrock-agentcore-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_bedrock_agentcore_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── cache.py
│ │ │ ├── doc_fetcher.py
│ │ │ ├── indexer.py
│ │ │ ├── text_processor.py
│ │ │ └── url_validator.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── SECURITY.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_cache.py
│ │ │ ├── test_config.py
│ │ │ ├── test_doc_fetcher.py
│ │ │ ├── test_indexer.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_server.py
│ │ │ ├── test_text_processor.py
│ │ │ └── test_url_validator.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-kendra-index-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_kendra_index_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── util.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-keyspaces-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_keyspaces_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── config.py
│ │ │ ├── consts.py
│ │ │ ├── llm_context.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── services.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_client.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_query_analysis_service.py
│ │ │ ├── test_server.py
│ │ │ └── test_services.py
│ │ └── uv.lock
│ ├── amazon-mq-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_mq_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_service_mcp_generator.py
│ │ │ ├── consts.py
│ │ │ ├── rabbitmq
│ │ │ │ ├── __init__.py
│ │ │ │ ├── admin.py
│ │ │ │ ├── connection.py
│ │ │ │ ├── doc
│ │ │ │ │ ├── rabbitmq_broker_sizing_guide.md
│ │ │ │ │ ├── rabbitmq_performance_optimization_best_practice.md
│ │ │ │ │ ├── rabbitmq_production_deployment_guidelines.md
│ │ │ │ │ ├── rabbitmq_quorum_queue_migration_guide.md
│ │ │ │ │ └── rabbitmq_setup_best_practice.md
│ │ │ │ ├── handlers.py
│ │ │ │ └── module.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── example
│ │ │ └── sample_mcp_q_cli.json
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── rabbitmq
│ │ │ │ ├── __init__.py
│ │ │ │ ├── conftest.py
│ │ │ │ ├── test_admin.py
│ │ │ │ ├── test_connection.py
│ │ │ │ ├── test_handlers.py
│ │ │ │ └── test_module.py
│ │ │ ├── test_aws_service_mcp_generator.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-neptune-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_neptune_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── exceptions.py
│ │ │ ├── graph_store
│ │ │ │ ├── __init__.py
│ │ │ │ ├── analytics.py
│ │ │ │ ├── base.py
│ │ │ │ └── database.py
│ │ │ ├── models.py
│ │ │ ├── neptune.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_analytics.py
│ │ │ ├── test_database.py
│ │ │ ├── test_exceptions.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_neptune.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-qbusiness-anonymous-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_qbusiness_anonymous_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── clients.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── amazon-qindex-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_qindex_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── clients.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_clients.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ └── uv.lock
│ ├── amazon-sns-sqs-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── amazon_sns_sqs_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ ├── consts.py
│ │ │ ├── generator.py
│ │ │ ├── server.py
│ │ │ ├── sns.py
│ │ │ └── sqs.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── print_tools.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── test_common.py
│ │ │ ├── test_generator.py
│ │ │ ├── test_server.py
│ │ │ ├── test_sns.py
│ │ │ └── test_sqs.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aurora-dsql-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aurora_dsql_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── mutable_sql_detector.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_connection_reuse.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_profile_option.py
│ │ │ ├── test_readonly_enforcement.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-api-mcp-server
│ │ ├── .gitattributes
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_api_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agent_scripts
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── manager.py
│ │ │ │ │ ├── models.py
│ │ │ │ │ └── registry
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── application-failure-troubleshooting.script.md
│ │ │ │ │ ├── cloudtral-mutli-region-setup.script.md
│ │ │ │ │ ├── create_amazon_aurora_db_cluster_with_instances.script.md
│ │ │ │ │ ├── lambda-timeout-debugging.script.md
│ │ │ │ │ ├── scripts_format.md
│ │ │ │ │ └── troubleshoot-permissions-with-cloudtrail-events.script.md
│ │ │ │ ├── aws
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── driver.py
│ │ │ │ │ ├── pagination.py
│ │ │ │ │ ├── regions.py
│ │ │ │ │ ├── service.py
│ │ │ │ │ └── services.py
│ │ │ │ ├── common
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── command_metadata.py
│ │ │ │ │ ├── command.py
│ │ │ │ │ ├── config.py
│ │ │ │ │ ├── errors.py
│ │ │ │ │ ├── file_operations.py
│ │ │ │ │ ├── file_system_controls.py
│ │ │ │ │ ├── helpers.py
│ │ │ │ │ ├── models.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── data
│ │ │ │ │ └── api_metadata.json
│ │ │ │ ├── metadata
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── read_only_operations_list.py
│ │ │ │ ├── parser
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── custom_validators
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── botocore_param_validator.py
│ │ │ │ │ │ ├── ec2_validator.py
│ │ │ │ │ │ └── ssm_validator.py
│ │ │ │ │ ├── interpretation.py
│ │ │ │ │ ├── lexer.py
│ │ │ │ │ └── parser.py
│ │ │ │ ├── py.typed
│ │ │ │ └── security
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_api_customization.json
│ │ │ │ └── policy.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── CONTRIBUTING.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── agent_scripts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_manager.py
│ │ │ │ └── test_registry
│ │ │ │ ├── another_valid_script.script.md
│ │ │ │ ├── test_script.script.md
│ │ │ │ └── valid_script.script.md
│ │ │ ├── aws
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_driver.py
│ │ │ │ ├── test_pagination.py
│ │ │ │ ├── test_service.py
│ │ │ │ └── test_services.py
│ │ │ ├── common
│ │ │ │ ├── test_command.py
│ │ │ │ ├── test_config.py
│ │ │ │ ├── test_file_operations.py
│ │ │ │ ├── test_file_system_controls.py
│ │ │ │ ├── test_file_validation.py
│ │ │ │ └── test_helpers.py
│ │ │ ├── fixtures.py
│ │ │ ├── history_handler.py
│ │ │ ├── metadata
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_read_only_operations_list.py
│ │ │ ├── parser
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_file_path_detection.py
│ │ │ │ ├── test_lexer.py
│ │ │ │ ├── test_parser_customizations.py
│ │ │ │ └── test_parser.py
│ │ │ ├── test_security_policy.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-appsync-mcp-server
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_appsync_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── decorators.py
│ │ │ ├── helpers.py
│ │ │ ├── operations
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_api_cache.py
│ │ │ │ ├── create_api_key.py
│ │ │ │ ├── create_api.py
│ │ │ │ ├── create_channel_namespace.py
│ │ │ │ ├── create_datasource.py
│ │ │ │ ├── create_domain_name.py
│ │ │ │ ├── create_function.py
│ │ │ │ ├── create_graphql_api.py
│ │ │ │ ├── create_resolver.py
│ │ │ │ └── create_schema.py
│ │ │ ├── server.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_api_cache.py
│ │ │ │ ├── create_api_key.py
│ │ │ │ ├── create_api.py
│ │ │ │ ├── create_channel_namespace.py
│ │ │ │ ├── create_datasource.py
│ │ │ │ ├── create_domain_name.py
│ │ │ │ ├── create_function.py
│ │ │ │ ├── create_graphql_api.py
│ │ │ │ ├── create_resolver.py
│ │ │ │ └── create_schema.py
│ │ │ └── validators.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_all_create_tools_write_protection.py
│ │ │ ├── test_create_api_cache.py
│ │ │ ├── test_create_api_key.py
│ │ │ ├── test_create_api.py
│ │ │ ├── test_create_channel_namespace.py
│ │ │ ├── test_create_datasource_tool.py
│ │ │ ├── test_create_datasource.py
│ │ │ ├── test_create_domain_name.py
│ │ │ ├── test_create_function.py
│ │ │ ├── test_create_graphql_api.py
│ │ │ ├── test_create_resolver.py
│ │ │ ├── test_create_schema_tool.py
│ │ │ ├── test_create_schema.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_server.py
│ │ │ ├── test_validators.py
│ │ │ └── test_write_operation.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-bedrock-custom-model-import-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_bedrock_custom_model_import_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── llm_context.py
│ │ │ ├── models.py
│ │ │ ├── prompts.py
│ │ │ ├── server.py
│ │ │ ├── services
│ │ │ │ ├── __init__.py
│ │ │ │ ├── imported_model_service.py
│ │ │ │ └── model_import_service.py
│ │ │ ├── tools
│ │ │ │ ├── create_model_import_job.py
│ │ │ │ ├── delete_imported_model.py
│ │ │ │ ├── get_imported_model.py
│ │ │ │ ├── get_model_import_job.py
│ │ │ │ ├── list_imported_models.py
│ │ │ │ └── list_model_import_jobs.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws.py
│ │ │ ├── config.py
│ │ │ ├── consts.py
│ │ │ └── matching.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── services
│ │ │ │ ├── test_imported_model_service.py
│ │ │ │ └── test_model_import_service.py
│ │ │ ├── test_client.py
│ │ │ ├── test_init.py
│ │ │ ├── test_llm_context.py
│ │ │ ├── test_prompts.py
│ │ │ ├── test_server.py
│ │ │ ├── tools
│ │ │ │ ├── test_create_model_import_job.py
│ │ │ │ ├── test_delete_imported_model.py
│ │ │ │ ├── test_get_imported_model.py
│ │ │ │ ├── test_get_model_import_job.py
│ │ │ │ ├── test_list_imported_models.py
│ │ │ │ └── test_list_model_import_jobs.py
│ │ │ └── utils
│ │ │ ├── test_aws.py
│ │ │ ├── test_config.py
│ │ │ └── test_matching.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-bedrock-data-automation-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_bedrock_data_automation_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── helpers.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-dataprocessing-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_dataprocessing_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ └── glue_data_catalog
│ │ │ │ ├── __init__.py
│ │ │ │ ├── data_catalog_database_manager.py
│ │ │ │ ├── data_catalog_handler.py
│ │ │ │ └── data_catalog_table_manager.py
│ │ │ ├── handlers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── athena_data_catalog_handler.py
│ │ │ │ │ ├── athena_query_handler.py
│ │ │ │ │ └── athena_workgroup_handler.py
│ │ │ │ ├── commons
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── common_resource_handler.py
│ │ │ │ ├── emr
│ │ │ │ │ ├── emr_ec2_cluster_handler.py
│ │ │ │ │ ├── emr_ec2_instance_handler.py
│ │ │ │ │ └── emr_ec2_steps_handler.py
│ │ │ │ └── glue
│ │ │ │ ├── __init__.py
│ │ │ │ ├── crawler_handler.py
│ │ │ │ ├── data_catalog_handler.py
│ │ │ │ ├── glue_commons_handler.py
│ │ │ │ ├── glue_etl_handler.py
│ │ │ │ ├── interactive_sessions_handler.py
│ │ │ │ └── worklows_handler.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena_models.py
│ │ │ │ ├── common_resource_models.py
│ │ │ │ ├── data_catalog_models.py
│ │ │ │ ├── emr_models.py
│ │ │ │ └── glue_models.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws_helper.py
│ │ │ ├── consts.py
│ │ │ ├── logging_helper.py
│ │ │ └── mutable_sql_detector.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ └── glue_data_catalog
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_data_catalog_database_manager.py
│ │ │ │ ├── test_data_catalog_handler.py
│ │ │ │ └── test_data_catalog_table_manager.py
│ │ │ ├── handlers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── athena
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── test_athena_data_catalog_handler.py
│ │ │ │ │ ├── test_athena_query_handler.py
│ │ │ │ │ ├── test_athena_workgroup_handler.py
│ │ │ │ │ └── test_custom_tags_athena.py
│ │ │ │ ├── commons
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── test_common_resource_handler.py
│ │ │ │ ├── emr
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── test_custom_tags_emr.py
│ │ │ │ │ ├── test_emr_ec2_cluster_handler.py
│ │ │ │ │ ├── test_emr_ec2_instance_handler.py
│ │ │ │ │ └── test_emr_ec2_steps_handler.py
│ │ │ │ └── glue
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_crawler_handler.py
│ │ │ │ ├── test_custom_tags_glue.py
│ │ │ │ ├── test_data_catalog_handler.py
│ │ │ │ ├── test_glue_commons_handler.py
│ │ │ │ ├── test_glue_etl_handler.py
│ │ │ │ ├── test_glue_interactive_sessions_handler.py
│ │ │ │ └── test_glue_workflows_handler.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_athena_models.py
│ │ │ │ ├── test_common_resource_models.py
│ │ │ │ ├── test_data_catalog_models.py
│ │ │ │ ├── test_emr_models.py
│ │ │ │ ├── test_glue_models.py
│ │ │ │ ├── test_interactive_sessions_models.py
│ │ │ │ └── test_workflows_models.py
│ │ │ ├── test_init.py
│ │ │ ├── test_server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── test_aws_helper.py
│ │ │ ├── test_custom_tags.py
│ │ │ └── test_logging_helper.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-diagram-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_diagram_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── diagrams_tools.py
│ │ │ ├── models.py
│ │ │ ├── scanner.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── resources
│ │ │ │ ├── __init__.py
│ │ │ │ └── example_diagrams
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_example.py
│ │ │ │ ├── flow_example.py
│ │ │ │ └── sequence_example.py
│ │ │ ├── test_diagrams.py
│ │ │ ├── test_models.py
│ │ │ ├── test_sarif_fix.py
│ │ │ ├── test_scanner.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-documentation-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_documentation_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── models.py
│ │ │ ├── server_aws_cn.py
│ │ │ ├── server_aws.py
│ │ │ ├── server_utils.py
│ │ │ ├── server.py
│ │ │ └── util.py
│ │ ├── basic-usage.gif
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── constants.py
│ │ │ ├── resources
│ │ │ │ └── lambda_sns_raw.html
│ │ │ ├── test_aws_cn_get_available_services_live.py
│ │ │ ├── test_aws_cn_read_documentation_live.py
│ │ │ ├── test_aws_read_documentation_live.py
│ │ │ ├── test_aws_recommend_live.py
│ │ │ ├── test_aws_search_live.py
│ │ │ ├── test_metadata_handling.py
│ │ │ ├── test_models.py
│ │ │ ├── test_server_aws_cn.py
│ │ │ ├── test_server_aws.py
│ │ │ ├── test_server_utils.py
│ │ │ ├── test_server.py
│ │ │ └── test_util.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-healthomics-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_healthomics_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── helper_tools.py
│ │ │ │ ├── run_analysis.py
│ │ │ │ ├── troubleshooting.py
│ │ │ │ ├── workflow_analysis.py
│ │ │ │ ├── workflow_execution.py
│ │ │ │ ├── workflow_linting.py
│ │ │ │ └── workflow_management.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws_utils.py
│ │ │ ├── s3_utils.py
│ │ │ └── validation_utils.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── docs
│ │ │ └── workflow_linting.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_aws_utils.py
│ │ │ ├── test_consts.py
│ │ │ ├── test_helper_tools.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_run_analysis.py
│ │ │ ├── test_s3_utils.py
│ │ │ ├── test_server.py
│ │ │ ├── test_troubleshooting.py
│ │ │ ├── test_workflow_analysis.py
│ │ │ ├── test_workflow_execution.py
│ │ │ ├── test_workflow_linting.py
│ │ │ ├── test_workflow_management.py
│ │ │ └── test_workflow_tools.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-iot-sitewise-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_iot_sitewise_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── asset_hierarchy.py
│ │ │ │ ├── data_exploration.py
│ │ │ │ └── data_ingestion.py
│ │ │ ├── server.py
│ │ │ ├── tool_metadata.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── sitewise_access.py
│ │ │ │ ├── sitewise_asset_models.py
│ │ │ │ ├── sitewise_assets.py
│ │ │ │ ├── sitewise_data.py
│ │ │ │ └── sitewise_gateways.py
│ │ │ └── validation.py
│ │ ├── CHANGELOG.md
│ │ ├── DEVELOPMENT.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ └── wind_farm_example.py
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_server.py
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_server.py
│ │ │ ├── test_sitewise_access.py
│ │ │ ├── test_sitewise_asset_models.py
│ │ │ ├── test_sitewise_assets.py
│ │ │ ├── test_sitewise_data.py
│ │ │ ├── test_sitewise_gateways.py
│ │ │ └── test_validation.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-knowledge-mcp-server
│ │ └── README.md
│ ├── aws-location-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_location_server
│ │ │ ├── __init__.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_server_integration.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-msk-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_msk_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── tools
│ │ │ ├── __init__.py
│ │ │ ├── common_functions
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client_manager.py
│ │ │ │ └── common_functions.py
│ │ │ ├── logs_and_telemetry
│ │ │ │ ├── __init__.py
│ │ │ │ ├── cluster_metrics_tools.py
│ │ │ │ ├── list_customer_iam_access.py
│ │ │ │ └── metric_config.py
│ │ │ ├── mutate_cluster
│ │ │ │ ├── __init__.py
│ │ │ │ ├── batch_associate_scram_secret.py
│ │ │ │ ├── batch_disassociate_scram_secret.py
│ │ │ │ ├── create_cluster_v2.py
│ │ │ │ ├── put_cluster_policy.py
│ │ │ │ ├── reboot_broker.py
│ │ │ │ ├── update_broker_count.py
│ │ │ │ ├── update_broker_storage.py
│ │ │ │ ├── update_broker_type.py
│ │ │ │ ├── update_cluster_configuration.py
│ │ │ │ ├── update_monitoring.py
│ │ │ │ └── update_security.py
│ │ │ ├── mutate_config
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_configuration.py
│ │ │ │ ├── tag_resource.py
│ │ │ │ ├── untag_resource.py
│ │ │ │ └── update_configuration.py
│ │ │ ├── mutate_vpc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_vpc_connection.py
│ │ │ │ ├── delete_vpc_connection.py
│ │ │ │ └── reject_client_vpc_connection.py
│ │ │ ├── read_cluster
│ │ │ │ ├── __init__.py
│ │ │ │ ├── describe_cluster_operation.py
│ │ │ │ ├── describe_cluster.py
│ │ │ │ ├── get_bootstrap_brokers.py
│ │ │ │ ├── get_cluster_policy.py
│ │ │ │ ├── get_compatible_kafka_versions.py
│ │ │ │ ├── list_client_vpc_connections.py
│ │ │ │ ├── list_cluster_operations.py
│ │ │ │ ├── list_nodes.py
│ │ │ │ └── list_scram_secrets.py
│ │ │ ├── read_config
│ │ │ │ ├── __init__.py
│ │ │ │ ├── describe_configuration_revision.py
│ │ │ │ ├── describe_configuration.py
│ │ │ │ ├── list_configuration_revisions.py
│ │ │ │ └── list_tags_for_resource.py
│ │ │ ├── read_global
│ │ │ │ ├── __init__.py
│ │ │ │ ├── list_clusters.py
│ │ │ │ ├── list_configurations.py
│ │ │ │ ├── list_kafka_versions.py
│ │ │ │ └── list_vpc_connections.py
│ │ │ ├── read_vpc
│ │ │ │ ├── __init__.py
│ │ │ │ └── describe_vpc_connection.py
│ │ │ └── static_tools
│ │ │ ├── __init__.py
│ │ │ └── cluster_best_practices.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_client_manager.py
│ │ │ ├── test_cluster_metrics_tools.py
│ │ │ ├── test_common_functions.py
│ │ │ ├── test_create_cluster_v2.py
│ │ │ ├── test_create_configuration.py
│ │ │ ├── test_create_vpc_connection.py
│ │ │ ├── test_delete_vpc_connection.py
│ │ │ ├── test_describe_cluster_operation.py
│ │ │ ├── test_describe_cluster.py
│ │ │ ├── test_describe_configuration_revision.py
│ │ │ ├── test_describe_configuration.py
│ │ │ ├── test_describe_vpc_connection.py
│ │ │ ├── test_get_bootstrap_brokers.py
│ │ │ ├── test_get_cluster_policy.py
│ │ │ ├── test_get_compatible_kafka_versions.py
│ │ │ ├── test_init.py
│ │ │ ├── test_list_client_vpc_connections.py
│ │ │ ├── test_list_cluster_operations.py
│ │ │ ├── test_list_clusters.py
│ │ │ ├── test_list_configuration_revisions.py
│ │ │ ├── test_list_configurations.py
│ │ │ ├── test_list_customer_iam_access.py
│ │ │ ├── test_list_kafka_versions.py
│ │ │ ├── test_list_nodes.py
│ │ │ ├── test_list_scram_secrets.py
│ │ │ ├── test_list_tags_for_resource.py
│ │ │ ├── test_list_vpc_connections.py
│ │ │ ├── test_logs_and_telemetry.py
│ │ │ ├── test_main.py
│ │ │ ├── test_mutate_cluster_init.py
│ │ │ ├── test_mutate_cluster_success_cases.py
│ │ │ ├── test_mutate_cluster.py
│ │ │ ├── test_mutate_config_init.py
│ │ │ ├── test_mutate_vpc_init.py
│ │ │ ├── test_read_cluster_init_updated.py
│ │ │ ├── test_read_cluster_init.py
│ │ │ ├── test_read_config_init.py
│ │ │ ├── test_read_global_init.py
│ │ │ ├── test_read_vpc_init.py
│ │ │ ├── test_reject_client_vpc_connection.py
│ │ │ ├── test_server.py
│ │ │ ├── test_static_tools_init.py
│ │ │ ├── test_tag_resource.py
│ │ │ ├── test_tool_descriptions.py
│ │ │ ├── test_untag_resource.py
│ │ │ └── test_update_configuration.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-pricing-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_pricing_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── cdk_analyzer.py
│ │ │ ├── consts.py
│ │ │ ├── helpers.py
│ │ │ ├── models.py
│ │ │ ├── pricing_client.py
│ │ │ ├── pricing_transformer.py
│ │ │ ├── report_generator.py
│ │ │ ├── server.py
│ │ │ ├── static
│ │ │ │ ├── __init__.py
│ │ │ │ ├── COST_REPORT_TEMPLATE.md
│ │ │ │ └── patterns
│ │ │ │ ├── __init__.py
│ │ │ │ └── BEDROCK.md
│ │ │ └── terraform_analyzer.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_cdk_analyzer.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_pricing_client.py
│ │ │ ├── test_pricing_transformer.py
│ │ │ ├── test_report_generator.py
│ │ │ ├── test_server.py
│ │ │ └── test_terraform_analyzer.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── aws-serverless-mcp-server
│ │ ├── .pre-commit.config.yaml
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_serverless_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── models.py
│ │ │ ├── resources
│ │ │ │ ├── __init__.py
│ │ │ │ ├── deployment_details.py
│ │ │ │ ├── deployment_list.py
│ │ │ │ ├── template_details.py
│ │ │ │ └── template_list.py
│ │ │ ├── server.py
│ │ │ ├── template
│ │ │ │ ├── __init__.py
│ │ │ │ ├── registry.py
│ │ │ │ ├── renderer.py
│ │ │ │ └── templates
│ │ │ │ ├── backend.j2
│ │ │ │ ├── frontend.j2
│ │ │ │ ├── fullstack.j2
│ │ │ │ └── README.md
│ │ │ ├── tools
│ │ │ │ ├── common
│ │ │ │ │ └── base_tool.py
│ │ │ │ ├── guidance
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── deploy_serverless_app_help.py
│ │ │ │ │ ├── get_iac_guidance.py
│ │ │ │ │ ├── get_lambda_event_schemas.py
│ │ │ │ │ ├── get_lambda_guidance.py
│ │ │ │ │ └── get_serverless_templates.py
│ │ │ │ ├── sam
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── sam_build.py
│ │ │ │ │ ├── sam_deploy.py
│ │ │ │ │ ├── sam_init.py
│ │ │ │ │ ├── sam_local_invoke.py
│ │ │ │ │ └── sam_logs.py
│ │ │ │ ├── schemas
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── describe_schema.py
│ │ │ │ │ ├── list_registries.py
│ │ │ │ │ └── search_schema.py
│ │ │ │ └── webapps
│ │ │ │ ├── __init__.py
│ │ │ │ ├── configure_domain.py
│ │ │ │ ├── deploy_webapp.py
│ │ │ │ ├── get_metrics.py
│ │ │ │ ├── update_webapp_frontend.py
│ │ │ │ ├── utils
│ │ │ │ │ ├── deploy_service.py
│ │ │ │ │ ├── frontend_uploader.py
│ │ │ │ │ └── startup_script_generator.py
│ │ │ │ └── webapp_deployment_help.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── aws_client_helper.py
│ │ │ ├── cloudformation.py
│ │ │ ├── const.py
│ │ │ ├── deployment_manager.py
│ │ │ ├── github.py
│ │ │ └── process.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_cloudformation.py
│ │ │ ├── test_configure_domain.py
│ │ │ ├── test_deploy_serverless_app_help.py
│ │ │ ├── test_deploy_service.py
│ │ │ ├── test_deploy_webapp.py
│ │ │ ├── test_deployment_details.py
│ │ │ ├── test_deployment_help.py
│ │ │ ├── test_deployment_list.py
│ │ │ ├── test_deployment_manager.py
│ │ │ ├── test_frontend_uploader.py
│ │ │ ├── test_get_iac_guidance.py
│ │ │ ├── test_get_lambda_event_schemas.py
│ │ │ ├── test_get_lambda_guidance.py
│ │ │ ├── test_get_metrics.py
│ │ │ ├── test_get_serverless_templates.py
│ │ │ ├── test_github.py
│ │ │ ├── test_models.py
│ │ │ ├── test_process.py
│ │ │ ├── test_sam_build.py
│ │ │ ├── test_sam_deploy.py
│ │ │ ├── test_sam_init.py
│ │ │ ├── test_sam_local_invoke.py
│ │ │ ├── test_sam_logs.py
│ │ │ ├── test_schemas.py
│ │ │ ├── test_server.py
│ │ │ ├── test_startup_script_generator.py
│ │ │ ├── test_template_details.py
│ │ │ ├── test_template_list.py
│ │ │ ├── test_template_registry.py
│ │ │ ├── test_template_renderer.py
│ │ │ └── test_update_webapp_frontend.py
│ │ └── uv.lock
│ ├── aws-support-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── aws_support_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── consts.py
│ │ │ ├── debug_helper.py
│ │ │ ├── errors.py
│ │ │ ├── formatters.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftests.py
│ │ │ ├── test_aws_support_mcp_server.py
│ │ │ └── test_models.py
│ │ └── uv.lock
│ ├── bedrock-kb-retrieval-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── bedrock_kb_retrieval_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── knowledgebases
│ │ │ │ ├── __init__.py
│ │ │ │ ├── clients.py
│ │ │ │ ├── discovery.py
│ │ │ │ └── retrieval.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_clients.py
│ │ │ ├── test_discovery.py
│ │ │ ├── test_env_config.py
│ │ │ ├── test_models.py
│ │ │ ├── test_retrieval.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── billing-cost-management-mcp-server
│ │ ├── __init__.py
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── billing_cost_management_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── models.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── decorator.py
│ │ │ │ ├── graviton_migration.py
│ │ │ │ ├── README.md
│ │ │ │ ├── savings_plans.py
│ │ │ │ └── types.py
│ │ │ ├── server.py
│ │ │ ├── templates
│ │ │ │ └── recommendation_templates
│ │ │ │ ├── ebs_volume.template
│ │ │ │ ├── ec2_asg.template
│ │ │ │ ├── ec2_instance.template
│ │ │ │ ├── ecs_service.template
│ │ │ │ ├── idle.template
│ │ │ │ ├── lambda_function.template
│ │ │ │ ├── rds_database.template
│ │ │ │ ├── reserved_instances.template
│ │ │ │ └── savings_plans.template
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_pricing_operations.py
│ │ │ │ ├── aws_pricing_tools.py
│ │ │ │ ├── budget_tools.py
│ │ │ │ ├── compute_optimizer_tools.py
│ │ │ │ ├── cost_anomaly_tools.py
│ │ │ │ ├── cost_comparison_tools.py
│ │ │ │ ├── cost_explorer_operations.py
│ │ │ │ ├── cost_explorer_tools.py
│ │ │ │ ├── cost_optimization_hub_helpers.py
│ │ │ │ ├── cost_optimization_hub_tools.py
│ │ │ │ ├── free_tier_usage_tools.py
│ │ │ │ ├── recommendation_details_tools.py
│ │ │ │ ├── ri_performance_tools.py
│ │ │ │ ├── sp_performance_tools.py
│ │ │ │ ├── storage_lens_tools.py
│ │ │ │ └── unified_sql_tools.py
│ │ │ └── utilities
│ │ │ ├── __init__.py
│ │ │ ├── aws_service_base.py
│ │ │ ├── constants.py
│ │ │ ├── logging_utils.py
│ │ │ └── sql_utils.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── requirements.txt
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_prompts.py
│ │ │ ├── README.md
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── fixtures.py
│ │ │ │ ├── test_aws_pricing_tools.py
│ │ │ │ ├── test_budget_tools.py
│ │ │ │ ├── test_compute_optimizer_tools.py
│ │ │ │ ├── test_cost_anomaly_tools_enhanced.py
│ │ │ │ ├── test_cost_anomaly_tools.py
│ │ │ │ ├── test_cost_comparison_tools.py
│ │ │ │ ├── test_cost_explorer_operations.py
│ │ │ │ ├── test_cost_explorer_tools.py
│ │ │ │ ├── test_cost_optimization_hub_helpers.py
│ │ │ │ ├── test_cost_optimization_hub_tools.py
│ │ │ │ ├── test_free_tier_usage_tools_new.py
│ │ │ │ ├── test_recommendation_details_tools.py
│ │ │ │ ├── test_ri_performance_tools.py
│ │ │ │ ├── test_sp_performance_tools.py
│ │ │ │ ├── test_storage_lens_tools.py
│ │ │ │ └── test_unified_sql_tools.py
│ │ │ └── utilities
│ │ │ ├── test_aws_service_base.py
│ │ │ └── test_sql_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── ccapi-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── ccapi_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_client.py
│ │ │ ├── cloud_control_utils.py
│ │ │ ├── context.py
│ │ │ ├── errors.py
│ │ │ ├── iac_generator.py
│ │ │ ├── impl
│ │ │ │ ├── __init__.py
│ │ │ │ ├── tools
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── explanation.py
│ │ │ │ │ ├── infrastructure_generation.py
│ │ │ │ │ ├── resource_operations.py
│ │ │ │ │ ├── security_scanning.py
│ │ │ │ │ └── session_management.py
│ │ │ │ └── utils
│ │ │ │ ├── __init__.py
│ │ │ │ └── validation.py
│ │ │ ├── infrastructure_generator.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ └── models.py
│ │ │ ├── schema_manager.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ └── __init__.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_aws_client.py
│ │ │ ├── test_checkov_install.py
│ │ │ ├── test_cloud_control_utils.py
│ │ │ ├── test_context.py
│ │ │ ├── test_errors.py
│ │ │ ├── test_explanation.py
│ │ │ ├── test_iac_generator.py
│ │ │ ├── test_infrastructure_generation.py
│ │ │ ├── test_infrastructure_generator.py
│ │ │ ├── test_models.py
│ │ │ ├── test_resource_operations.py
│ │ │ ├── test_schema_manager.py
│ │ │ ├── test_security_scanning.py
│ │ │ ├── test_server.py
│ │ │ ├── test_session_management.py
│ │ │ └── test_validation.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cdk-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cdk_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── __init__.py
│ │ │ │ ├── resources.py
│ │ │ │ ├── search_utils.py
│ │ │ │ ├── server.py
│ │ │ │ └── tools.py
│ │ │ ├── data
│ │ │ │ ├── __init__.py
│ │ │ │ ├── cdk_nag_parser.py
│ │ │ │ ├── construct_descriptions.py
│ │ │ │ ├── genai_cdk_loader.py
│ │ │ │ ├── lambda_layer_parser.py
│ │ │ │ ├── lambda_powertools_loader.py
│ │ │ │ ├── schema_generator.py
│ │ │ │ └── solutions_constructs_parser.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ ├── __init__.py
│ │ │ ├── CDK_GENERAL_GUIDANCE.md
│ │ │ ├── CDK_NAG_GUIDANCE.md
│ │ │ └── lambda_powertools
│ │ │ ├── bedrock.md
│ │ │ ├── cdk.md
│ │ │ ├── dependencies.md
│ │ │ ├── index.md
│ │ │ ├── insights.md
│ │ │ ├── logging.md
│ │ │ ├── metrics.md
│ │ │ └── tracing.md
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── core
│ │ │ │ ├── test_resources_enhanced.py
│ │ │ │ ├── test_resources.py
│ │ │ │ ├── test_search_utils.py
│ │ │ │ ├── test_server.py
│ │ │ │ └── test_tools.py
│ │ │ └── data
│ │ │ ├── test_cdk_nag_parser.py
│ │ │ ├── test_genai_cdk_loader.py
│ │ │ ├── test_lambda_powertools_loader.py
│ │ │ ├── test_schema_generator.py
│ │ │ └── test_solutions_constructs_parser.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cfn-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cfn_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_client.py
│ │ │ ├── cloud_control_utils.py
│ │ │ ├── context.py
│ │ │ ├── errors.py
│ │ │ ├── iac_generator.py
│ │ │ ├── schema_manager.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_aws_client.py
│ │ │ ├── test_cloud_control_utils.py
│ │ │ ├── test_errors.py
│ │ │ ├── test_iac_generator.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_schema_manager.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cloudtrail-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cloudtrail_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── tools.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ └── test_tools.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cloudwatch-appsignals-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cloudwatch_appsignals_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── audit_presentation_utils.py
│ │ │ ├── audit_utils.py
│ │ │ ├── aws_clients.py
│ │ │ ├── canary_utils.py
│ │ │ ├── server.py
│ │ │ ├── service_audit_utils.py
│ │ │ ├── service_tools.py
│ │ │ ├── sli_report_client.py
│ │ │ ├── slo_tools.py
│ │ │ ├── trace_tools.py
│ │ │ └── utils.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_audit_presentation_utils.py
│ │ │ ├── test_audit_utils.py
│ │ │ ├── test_aws_profile.py
│ │ │ ├── test_canary_utils.py
│ │ │ ├── test_initialization.py
│ │ │ ├── test_server_audit_functions.py
│ │ │ ├── test_server_audit_tools.py
│ │ │ ├── test_server.py
│ │ │ ├── test_service_audit_utils.py
│ │ │ ├── test_service_tools_operations.py
│ │ │ ├── test_sli_report_client.py
│ │ │ ├── test_slo_tools.py
│ │ │ └── test_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cloudwatch-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cloudwatch_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── cloudwatch_alarms
│ │ │ │ ├── models.py
│ │ │ │ └── tools.py
│ │ │ ├── cloudwatch_logs
│ │ │ │ ├── models.py
│ │ │ │ └── tools.py
│ │ │ ├── cloudwatch_metrics
│ │ │ │ ├── data
│ │ │ │ │ └── metric_metadata.json
│ │ │ │ ├── models.py
│ │ │ │ └── tools.py
│ │ │ ├── common.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── cloudwatch_alarms
│ │ │ │ ├── test_active_alarms.py
│ │ │ │ ├── test_alarm_history_integration.py
│ │ │ │ ├── test_alarm_history.py
│ │ │ │ └── test_alarms_error_handling.py
│ │ │ ├── cloudwatch_logs
│ │ │ │ ├── test_logs_error_handling.py
│ │ │ │ ├── test_logs_models.py
│ │ │ │ └── test_logs_server.py
│ │ │ ├── cloudwatch_metrics
│ │ │ │ ├── test_metrics_error_handling.py
│ │ │ │ ├── test_metrics_models.py
│ │ │ │ ├── test_metrics_server.py
│ │ │ │ └── test_validation_error.py
│ │ │ ├── test_common_and_server.py
│ │ │ ├── test_init.py
│ │ │ └── test_main.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── code-doc-gen-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── code_doc_gen_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── doc_generator.py
│ │ │ ├── models.py
│ │ │ ├── repomix_manager.py
│ │ │ └── templates.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_doc_generator_edge_cases.py
│ │ │ ├── test_doc_generator.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_repomix_manager_scenarios.py
│ │ │ ├── test_repomix_manager.py
│ │ │ ├── test_repomix_statistics.py
│ │ │ ├── test_server_extended.py
│ │ │ ├── test_server.py
│ │ │ └── test_templates.py
│ │ └── uv.lock
│ ├── core-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── core_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ ├── __init__.py
│ │ │ └── PROMPT_UNDERSTANDING.md
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_response_types.py
│ │ │ ├── test_server.py
│ │ │ └── test_static.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── cost-explorer-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── cost_explorer_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── comparison_handler.py
│ │ │ ├── constants.py
│ │ │ ├── cost_usage_handler.py
│ │ │ ├── forecasting_handler.py
│ │ │ ├── helpers.py
│ │ │ ├── metadata_handler.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── utility_handler.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_comparison_handler.py
│ │ │ ├── test_cost_usage_handler.py
│ │ │ ├── test_forecasting_handler.py
│ │ │ ├── test_helpers.py
│ │ │ ├── test_metadata_handler.py
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ └── test_utility_handler.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── documentdb-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ └── documentdb_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── analytic_tools.py
│ │ │ ├── config.py
│ │ │ ├── connection_tools.py
│ │ │ ├── db_management_tools.py
│ │ │ ├── query_tools.py
│ │ │ ├── server.py
│ │ │ └── write_tools.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_analytic_tools.py
│ │ │ ├── test_connection_tools.py
│ │ │ ├── test_db_management_tools.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_query_tools.py
│ │ │ └── test_write_tools.py
│ │ └── uv.lock
│ ├── dynamodb-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── dynamodb_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ ├── database_analysis_queries.py
│ │ │ ├── database_analyzers.py
│ │ │ ├── prompts
│ │ │ │ └── dynamodb_architect.md
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── evals
│ │ │ │ ├── dynamic_evaluators.py
│ │ │ │ ├── evaluation_registry.py
│ │ │ │ ├── logging_config.py
│ │ │ │ ├── multiturn_evaluator.py
│ │ │ │ ├── README.md
│ │ │ │ ├── scenarios.py
│ │ │ │ └── test_dspy_evals.py
│ │ │ ├── test_dynamodb_server.py
│ │ │ └── test_source_db_integration.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── ecs-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── ecs_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── api
│ │ │ │ ├── __init__.py
│ │ │ │ ├── containerize.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── ecs_troubleshooting.py
│ │ │ │ ├── infrastructure.py
│ │ │ │ ├── resource_management.py
│ │ │ │ ├── status.py
│ │ │ │ └── troubleshooting_tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── detect_image_pull_failures.py
│ │ │ │ ├── fetch_cloudformation_status.py
│ │ │ │ ├── fetch_network_configuration.py
│ │ │ │ ├── fetch_service_events.py
│ │ │ │ ├── fetch_task_failures.py
│ │ │ │ ├── fetch_task_logs.py
│ │ │ │ ├── get_ecs_troubleshooting_guidance.py
│ │ │ │ └── utils.py
│ │ │ ├── main.py
│ │ │ ├── modules
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws_knowledge_proxy.py
│ │ │ │ ├── containerize.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── deployment_status.py
│ │ │ │ ├── infrastructure.py
│ │ │ │ ├── resource_management.py
│ │ │ │ └── troubleshooting.py
│ │ │ ├── templates
│ │ │ │ ├── ecr_infrastructure.json
│ │ │ │ └── ecs_infrastructure.json
│ │ │ └── utils
│ │ │ ├── arn_parser.py
│ │ │ ├── aws.py
│ │ │ ├── config.py
│ │ │ ├── docker.py
│ │ │ ├── security.py
│ │ │ ├── templates.py
│ │ │ └── time_utils.py
│ │ ├── DEVELOPMENT.md
│ │ ├── pyproject.toml
│ │ ├── pyrightconfig.json
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── integ
│ │ │ │ └── mcp-inspector
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── run-tests.sh
│ │ │ │ └── scenarios
│ │ │ │ ├── 01_comprehensive_troubleshooting
│ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ ├── 03_cleanup.sh
│ │ │ │ │ ├── description.txt
│ │ │ │ │ └── utils
│ │ │ │ │ ├── mcp_helpers.sh
│ │ │ │ │ └── validation_helpers.sh
│ │ │ │ └── 02_test_knowledge_proxy_tools
│ │ │ │ ├── 01_create.sh
│ │ │ │ ├── 02_validate.sh
│ │ │ │ ├── 03_cleanup.sh
│ │ │ │ ├── description.txt
│ │ │ │ └── utils
│ │ │ │ ├── knowledge_validation_helpers.sh
│ │ │ │ └── mcp_knowledge_helpers.sh
│ │ │ ├── llm_testing
│ │ │ │ ├── invalid_cfn_template.yaml
│ │ │ │ ├── README.md
│ │ │ │ ├── run_tests.sh
│ │ │ │ ├── scenarios
│ │ │ │ │ ├── 01_cloudformation_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 04_evaluation.md
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 02_service_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 04_evaluation.md
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 03_task_exit_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 04_evaluation.md
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 04_network_configuration_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ ├── 05_resource_constraint_failure
│ │ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ │ └── description.txt
│ │ │ │ │ └── 06_load_balancer_failure
│ │ │ │ │ ├── 01_create.sh
│ │ │ │ │ ├── 02_validate.sh
│ │ │ │ │ ├── 03_prompts.txt
│ │ │ │ │ ├── 05_cleanup.sh
│ │ │ │ │ └── description.txt
│ │ │ │ ├── SCRIPT_IMPROVEMENTS.md
│ │ │ │ └── utils
│ │ │ │ ├── aws_helpers.sh
│ │ │ │ └── evaluation_template.md
│ │ │ └── unit
│ │ │ ├── __init__.py
│ │ │ ├── api
│ │ │ │ ├── conftest.py
│ │ │ │ ├── test_delete_api.py
│ │ │ │ ├── test_ecs_troubleshooting.py
│ │ │ │ ├── test_resource_management_api.py
│ │ │ │ └── troubleshooting_tools
│ │ │ │ └── test_fetch_network_configuration.py
│ │ │ ├── conftest.py
│ │ │ ├── modules
│ │ │ │ ├── test_aws_knowledge_proxy.py
│ │ │ │ └── test_resource_management_module.py
│ │ │ ├── test_aws_role_utils.py
│ │ │ ├── test_aws_utils.py
│ │ │ ├── test_containerize.py
│ │ │ ├── test_delete.py
│ │ │ ├── test_docker_utils.py
│ │ │ ├── test_docker_with_role.py
│ │ │ ├── test_image_pull_failure_extended.py
│ │ │ ├── test_image_pull_failure.py
│ │ │ ├── test_infrastructure_role.py
│ │ │ ├── test_infrastructure.py
│ │ │ ├── test_integration.py
│ │ │ ├── test_main.py
│ │ │ ├── test_resource_management_api_operation.py
│ │ │ ├── test_resource_management_tool.py
│ │ │ ├── test_resource_management.py
│ │ │ ├── test_security_integration.py
│ │ │ ├── test_status_pytest.py
│ │ │ ├── test_status.py
│ │ │ ├── troubleshooting_tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── conftest.py
│ │ │ │ ├── test_detect_image_pull_failures.py
│ │ │ │ ├── test_fetch_cloudformation_status.py
│ │ │ │ ├── test_fetch_service_events.py
│ │ │ │ ├── test_fetch_task_failures.py
│ │ │ │ ├── test_fetch_task_logs.py
│ │ │ │ ├── test_get_ecs_troubleshooting_guidance.py
│ │ │ │ ├── test_is_ecr_image_security.py
│ │ │ │ └── test_utils.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── async_test_utils.py
│ │ │ ├── test_arn_parser.py
│ │ │ ├── test_config.py
│ │ │ ├── test_docker.py
│ │ │ ├── test_response_sanitization.py
│ │ │ ├── test_security_extended.py
│ │ │ ├── test_security.py
│ │ │ ├── test_templates.py
│ │ │ └── test_time_utils.py
│ │ └── uv.lock
│ ├── eks-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── eks_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_helper.py
│ │ │ ├── cloudwatch_handler.py
│ │ │ ├── cloudwatch_metrics_guidance_handler.py
│ │ │ ├── consts.py
│ │ │ ├── data
│ │ │ │ └── eks_cloudwatch_metrics_guidance.json
│ │ │ ├── eks_kb_handler.py
│ │ │ ├── eks_stack_handler.py
│ │ │ ├── iam_handler.py
│ │ │ ├── insights_handler.py
│ │ │ ├── k8s_apis.py
│ │ │ ├── k8s_client_cache.py
│ │ │ ├── k8s_handler.py
│ │ │ ├── logging_helper.py
│ │ │ ├── models.py
│ │ │ ├── scripts
│ │ │ │ └── update_eks_cloudwatch_metrics_guidance.py
│ │ │ ├── server.py
│ │ │ ├── templates
│ │ │ │ ├── eks-templates
│ │ │ │ │ └── eks-with-vpc.yaml
│ │ │ │ └── k8s-templates
│ │ │ │ ├── deployment.yaml
│ │ │ │ └── service.yaml
│ │ │ └── vpc_config_handler.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_aws_helper.py
│ │ │ ├── test_cloudwatch_handler.py
│ │ │ ├── test_cloudwatch_metrics_guidance_handler.py
│ │ │ ├── test_eks_kb_handler.py
│ │ │ ├── test_eks_stack_handler.py
│ │ │ ├── test_iam_handler.py
│ │ │ ├── test_init.py
│ │ │ ├── test_insights_handler.py
│ │ │ ├── test_k8s_apis.py
│ │ │ ├── test_k8s_client_cache.py
│ │ │ ├── test_k8s_handler.py
│ │ │ ├── test_logging_helper.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_server.py
│ │ │ └── test_vpc_config_handler.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── elasticache-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── elasticache_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common
│ │ │ │ ├── __init__.py
│ │ │ │ ├── connection.py
│ │ │ │ ├── decorators.py
│ │ │ │ └── server.py
│ │ │ ├── context.py
│ │ │ ├── main.py
│ │ │ └── tools
│ │ │ ├── __init__.py
│ │ │ ├── cc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── connect.py
│ │ │ │ ├── create.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── describe.py
│ │ │ │ ├── modify.py
│ │ │ │ ├── parsers.py
│ │ │ │ └── processors.py
│ │ │ ├── ce
│ │ │ │ ├── __init__.py
│ │ │ │ └── get_cost_and_usage.py
│ │ │ ├── cw
│ │ │ │ ├── __init__.py
│ │ │ │ └── get_metric_statistics.py
│ │ │ ├── cwlogs
│ │ │ │ ├── __init__.py
│ │ │ │ ├── create_log_group.py
│ │ │ │ ├── describe_log_groups.py
│ │ │ │ ├── describe_log_streams.py
│ │ │ │ ├── filter_log_events.py
│ │ │ │ └── get_log_events.py
│ │ │ ├── firehose
│ │ │ │ ├── __init__.py
│ │ │ │ └── list_delivery_streams.py
│ │ │ ├── misc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── batch_apply_update_action.py
│ │ │ │ ├── batch_stop_update_action.py
│ │ │ │ ├── describe_cache_engine_versions.py
│ │ │ │ ├── describe_engine_default_parameters.py
│ │ │ │ ├── describe_events.py
│ │ │ │ └── describe_service_updates.py
│ │ │ ├── rg
│ │ │ │ ├── __init__.py
│ │ │ │ ├── complete_migration.py
│ │ │ │ ├── connect.py
│ │ │ │ ├── create.py
│ │ │ │ ├── delete.py
│ │ │ │ ├── describe.py
│ │ │ │ ├── modify.py
│ │ │ │ ├── parsers.py
│ │ │ │ ├── processors.py
│ │ │ │ ├── start_migration.py
│ │ │ │ └── test_migration.py
│ │ │ └── serverless
│ │ │ ├── __init__.py
│ │ │ ├── connect.py
│ │ │ ├── create.py
│ │ │ ├── delete.py
│ │ │ ├── describe.py
│ │ │ ├── models.py
│ │ │ └── modify.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_connection.py
│ │ │ ├── test_decorators.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── tools
│ │ │ ├── cc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_connect_additional.py
│ │ │ │ ├── test_connect_coverage_additional.py
│ │ │ │ ├── test_connect_coverage.py
│ │ │ │ ├── test_connect.py
│ │ │ │ ├── test_create_additional.py
│ │ │ │ ├── test_create.py
│ │ │ │ ├── test_delete.py
│ │ │ │ ├── test_describe.py
│ │ │ │ ├── test_modify.py
│ │ │ │ ├── test_parsers.py
│ │ │ │ └── test_processors.py
│ │ │ ├── ce
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_get_cost_and_usage.py
│ │ │ ├── cw
│ │ │ │ └── test_get_metric_statistics.py
│ │ │ ├── cwlogs
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_create_log_group.py
│ │ │ │ ├── test_describe_log_groups.py
│ │ │ │ ├── test_describe_log_streams.py
│ │ │ │ ├── test_filter_log_events.py
│ │ │ │ └── test_get_log_events.py
│ │ │ ├── firehose
│ │ │ │ └── test_list_delivery_streams.py
│ │ │ ├── misc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_batch_apply_update_action.py
│ │ │ │ ├── test_batch_stop_update_action.py
│ │ │ │ ├── test_describe_cache_engine_versions.py
│ │ │ │ ├── test_describe_engine_default_parameters.py
│ │ │ │ ├── test_describe_events.py
│ │ │ │ └── test_describe_service_updates.py
│ │ │ ├── rg
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_complete_migration.py
│ │ │ │ ├── test_connect_additional.py
│ │ │ │ ├── test_connect_coverage_additional.py
│ │ │ │ ├── test_connect_optional_fields.py
│ │ │ │ ├── test_connect_partial_coverage.py
│ │ │ │ ├── test_connect.py
│ │ │ │ ├── test_create.py
│ │ │ │ ├── test_delete.py
│ │ │ │ ├── test_describe.py
│ │ │ │ ├── test_modify.py
│ │ │ │ ├── test_parsers.py
│ │ │ │ ├── test_processors.py
│ │ │ │ ├── test_start_migration.py
│ │ │ │ └── test_test_migration.py
│ │ │ └── serverless
│ │ │ ├── test_connect_additional.py
│ │ │ ├── test_connect_coverage_additional.py
│ │ │ ├── test_connect_optional_fields.py
│ │ │ ├── test_connect.py
│ │ │ ├── test_create.py
│ │ │ ├── test_delete.py
│ │ │ ├── test_describe.py
│ │ │ └── test_modify.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── finch-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── finch_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── build.py
│ │ │ ├── common.py
│ │ │ ├── ecr.py
│ │ │ ├── push.py
│ │ │ └── vm.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_cli_flags.py
│ │ │ ├── test_logging_configuration.py
│ │ │ ├── test_server.py
│ │ │ ├── test_utils_build.py
│ │ │ ├── test_utils_common.py
│ │ │ ├── test_utils_ecr.py
│ │ │ ├── test_utils_push.py
│ │ │ └── test_utils_vm.py
│ │ └── uv.lock
│ ├── frontend-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── frontend_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── server.py
│ │ │ ├── static
│ │ │ │ └── react
│ │ │ │ ├── essential-knowledge.md
│ │ │ │ └── troubleshooting.md
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ └── file_utils.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_file_utils.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ └── uv.lock
│ ├── git-repo-research-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── git_repo_research_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── defaults.py
│ │ │ ├── embeddings.py
│ │ │ ├── github_search.py
│ │ │ ├── indexer.py
│ │ │ ├── models.py
│ │ │ ├── repository.py
│ │ │ ├── search.py
│ │ │ ├── server.py
│ │ │ └── utils.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_errors_repository.py
│ │ │ ├── test_github_search_edge_cases.py
│ │ │ ├── test_graphql_github_search.py
│ │ │ ├── test_local_repository.py
│ │ │ ├── test_repository_utils.py
│ │ │ ├── test_rest_github_search.py
│ │ │ ├── test_search.py
│ │ │ ├── test_server.py
│ │ │ └── test_url_repository.py
│ │ └── uv.lock
│ ├── healthlake-mcp-server
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── healthlake_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── fhir_operations.py
│ │ │ ├── main.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── CONTRIBUTING.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ ├── mcp_config.json
│ │ │ └── README.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_fhir_client_comprehensive.py
│ │ │ ├── test_fhir_error_scenarios.py
│ │ │ ├── test_fhir_operations.py
│ │ │ ├── test_integration_mock_based.py
│ │ │ ├── test_main_edge_cases.py
│ │ │ ├── test_main.py
│ │ │ ├── test_mcp_integration_coverage.py
│ │ │ ├── test_models_edge_cases.py
│ │ │ ├── test_models.py
│ │ │ ├── test_readonly_mode.py
│ │ │ ├── test_server_core.py
│ │ │ ├── test_server_error_handling.py
│ │ │ ├── test_server_mcp_handlers.py
│ │ │ ├── test_server_toolhandler.py
│ │ │ └── test_server_validation.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── iam-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── iam_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_client.py
│ │ │ ├── context.py
│ │ │ ├── errors.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── DESIGN_COMPLIANCE.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ ├── get_policy_document_example.py
│ │ │ └── inline_policy_demo.py
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── run_tests.sh
│ │ ├── tests
│ │ │ ├── test_context.py
│ │ │ ├── test_errors.py
│ │ │ ├── test_inline_policies.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── lambda-tool-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── lambda_tool_mcp_server
│ │ │ ├── __init__.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── examples
│ │ │ ├── README.md
│ │ │ └── sample_functions
│ │ │ ├── customer-create
│ │ │ │ └── app.py
│ │ │ ├── customer-id-from-email
│ │ │ │ └── app.py
│ │ │ ├── customer-info-from-id
│ │ │ │ └── app.py
│ │ │ └── template.yml
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_format_lambda_response.py
│ │ │ ├── test_integration_coverage.py
│ │ │ ├── test_integration.py
│ │ │ ├── test_register_lambda_functions.py
│ │ │ ├── test_schema_integration.py
│ │ │ ├── test_server_coverage_additional.py
│ │ │ ├── test_server_coverage.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── mcp-lambda-handler
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ └── mcp_lambda_handler
│ │ │ ├── __init__.py
│ │ │ ├── mcp_lambda_handler.py
│ │ │ ├── session.py
│ │ │ └── types.py
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ └── test_lambda_handler.py
│ │ └── uv.lock
│ ├── memcached-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── memcached_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common
│ │ │ │ ├── config.py
│ │ │ │ ├── connection.py
│ │ │ │ └── server.py
│ │ │ ├── context.py
│ │ │ ├── main.py
│ │ │ └── tools
│ │ │ └── cache.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── ELASTICACHECONNECT.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_cache_readonly.py
│ │ │ ├── test_cache.py
│ │ │ ├── test_connection.py
│ │ │ ├── test_init.py
│ │ │ └── test_main.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── mysql-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── mysql_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── mutable_sql_detector.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── nova-canvas-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── nova_canvas_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ ├── novacanvas.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_models.py
│ │ │ ├── test_novacanvas.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── openapi-mcp-server
│ │ ├── .coveragerc
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── AUTHENTICATION.md
│ │ ├── AWS_BEST_PRACTICES.md
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── openapi_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── api
│ │ │ │ ├── __init__.py
│ │ │ │ └── config.py
│ │ │ ├── auth
│ │ │ │ ├── __init__.py
│ │ │ │ ├── api_key_auth.py
│ │ │ │ ├── auth_cache.py
│ │ │ │ ├── auth_errors.py
│ │ │ │ ├── auth_factory.py
│ │ │ │ ├── auth_protocol.py
│ │ │ │ ├── auth_provider.py
│ │ │ │ ├── base_auth.py
│ │ │ │ ├── basic_auth.py
│ │ │ │ ├── bearer_auth.py
│ │ │ │ ├── cognito_auth.py
│ │ │ │ └── register.py
│ │ │ ├── patch
│ │ │ │ └── __init__.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── generators
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── operation_prompts.py
│ │ │ │ │ └── workflow_prompts.py
│ │ │ │ ├── models.py
│ │ │ │ └── prompt_manager.py
│ │ │ ├── server.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── cache_provider.py
│ │ │ ├── config.py
│ │ │ ├── error_handler.py
│ │ │ ├── http_client.py
│ │ │ ├── metrics_provider.py
│ │ │ ├── openapi_validator.py
│ │ │ └── openapi.py
│ │ ├── CHANGELOG.md
│ │ ├── DEPLOYMENT.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── OBSERVABILITY.md
│ │ ├── pyproject.toml
│ │ ├── pyrightconfig.json
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── api
│ │ │ │ └── test_config.py
│ │ │ ├── auth
│ │ │ │ ├── test_api_key_auth.py
│ │ │ │ ├── test_auth_cache.py
│ │ │ │ ├── test_auth_errors.py
│ │ │ │ ├── test_auth_factory_caching.py
│ │ │ │ ├── test_auth_factory_coverage.py
│ │ │ │ ├── test_auth_factory.py
│ │ │ │ ├── test_auth_protocol_additional.py
│ │ │ │ ├── test_auth_protocol_boost.py
│ │ │ │ ├── test_auth_protocol_coverage.py
│ │ │ │ ├── test_auth_protocol_extended.py
│ │ │ │ ├── test_auth_protocol_improved.py
│ │ │ │ ├── test_auth_protocol.py
│ │ │ │ ├── test_auth_provider_additional.py
│ │ │ │ ├── test_base_auth_coverage.py
│ │ │ │ ├── test_base_auth.py
│ │ │ │ ├── test_basic_auth.py
│ │ │ │ ├── test_bearer_auth.py
│ │ │ │ ├── test_cognito_auth_additional_coverage.py
│ │ │ │ ├── test_cognito_auth_boost_coverage.py
│ │ │ │ ├── test_cognito_auth_client_credentials.py
│ │ │ │ ├── test_cognito_auth_coverage_boost.py
│ │ │ │ ├── test_cognito_auth_exceptions.py
│ │ │ │ ├── test_cognito_auth.py
│ │ │ │ ├── test_register_coverage.py
│ │ │ │ └── test_register.py
│ │ │ ├── prompts
│ │ │ │ ├── standalone
│ │ │ │ │ ├── test_operation_prompt.py
│ │ │ │ │ ├── test_prompt_arguments.py
│ │ │ │ │ └── test_secure_operation_prompt.py
│ │ │ │ ├── test_mcp_prompt_manager_integration.py
│ │ │ │ ├── test_mcp_prompt_manager.py
│ │ │ │ ├── test_models_dict_method.py
│ │ │ │ ├── test_operation_prompts_extended.py
│ │ │ │ ├── test_prompt_manager_additional.py
│ │ │ │ ├── test_prompt_manager_comprehensive.py
│ │ │ │ ├── test_prompt_manager_coverage.py
│ │ │ │ └── test_prompt_registration.py
│ │ │ ├── README.md
│ │ │ ├── test_api_name.py
│ │ │ ├── test_cache_coverage_89.py
│ │ │ ├── test_client.py
│ │ │ ├── test_coverage_boost.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main_extended.py
│ │ │ ├── test_main.py
│ │ │ ├── test_openapi_coverage_89.py
│ │ │ ├── test_server_auth_errors.py
│ │ │ ├── test_server_coverage_boost_2.py
│ │ │ ├── test_server_coverage_boost.py
│ │ │ ├── test_server_exception_handling.py
│ │ │ ├── test_server_extended.py
│ │ │ ├── test_server_httpx_version.py
│ │ │ ├── test_server_part1.py
│ │ │ ├── test_server_route_logging.py
│ │ │ ├── test_server_signal_handlers.py
│ │ │ ├── test_server.py
│ │ │ └── utils
│ │ │ ├── test_cache_provider.py
│ │ │ ├── test_error_handler_boost.py
│ │ │ ├── test_error_handler_extended.py
│ │ │ ├── test_error_handler_fix.py
│ │ │ ├── test_error_handler.py
│ │ │ ├── test_http_client_comprehensive.py
│ │ │ ├── test_http_client_extended.py
│ │ │ ├── test_http_client_extended2.py
│ │ │ ├── test_http_client_import_error.py
│ │ │ ├── test_http_client.py
│ │ │ ├── test_metrics_provider_decorators.py
│ │ │ ├── test_metrics_provider_extended2.py
│ │ │ ├── test_metrics_provider_prometheus.py
│ │ │ ├── test_metrics_provider.py
│ │ │ ├── test_openapi_validator.py
│ │ │ └── test_openapi.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── postgres-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── postgres_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── connection
│ │ │ │ ├── __init__.py
│ │ │ │ ├── abstract_db_connection.py
│ │ │ │ ├── db_connection_singleton.py
│ │ │ │ ├── psycopg_pool_connection.py
│ │ │ │ └── rds_api_connection.py
│ │ │ ├── mutable_sql_detector.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_psycopg_connector.py
│ │ │ ├── test_server.py
│ │ │ └── test_singleton.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── prometheus-mcp-server
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── prometheus_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_aws_credentials.py
│ │ │ ├── test_config_manager.py
│ │ │ ├── test_consts.py
│ │ │ ├── test_coverage_gaps.py
│ │ │ ├── test_coverage_improvement.py
│ │ │ ├── test_final_coverage.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_models.py
│ │ │ ├── test_prometheus_client.py
│ │ │ ├── test_prometheus_connection.py
│ │ │ ├── test_security_validator.py
│ │ │ ├── test_server_coverage.py
│ │ │ ├── test_tools.py
│ │ │ └── test_workspace_config.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── redshift-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── redshift_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── consts.py
│ │ │ ├── models.py
│ │ │ ├── redshift.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_redshift.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── s3-tables-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── s3_tables_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── constants.py
│ │ │ ├── database.py
│ │ │ ├── engines
│ │ │ │ ├── __init__.py
│ │ │ │ └── pyiceberg.py
│ │ │ ├── file_processor
│ │ │ │ ├── __init__.py
│ │ │ │ ├── csv.py
│ │ │ │ ├── parquet.py
│ │ │ │ └── utils.py
│ │ │ ├── models.py
│ │ │ ├── namespaces.py
│ │ │ ├── resources.py
│ │ │ ├── s3_operations.py
│ │ │ ├── server.py
│ │ │ ├── table_buckets.py
│ │ │ ├── tables.py
│ │ │ └── utils.py
│ │ ├── CHANGELOG.md
│ │ ├── CONTEXT.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_csv.py
│ │ │ ├── test_database.py
│ │ │ ├── test_file_processor_utils.py
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ ├── test_namespaces.py
│ │ │ ├── test_parquet.py
│ │ │ ├── test_pyiceberg.py
│ │ │ ├── test_resources.py
│ │ │ ├── test_s3_operations.py
│ │ │ ├── test_server.py
│ │ │ ├── test_table_buckets.py
│ │ │ ├── test_tables.py
│ │ │ └── test_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── stepfunctions-tool-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── stepfunctions_tool_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── aws_helper.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── test_aws_helper.py
│ │ │ ├── test_create_state_machine_tool.py
│ │ │ ├── test_filter_state_machines_by_tag.py
│ │ │ ├── test_format_state_machine_response.py
│ │ │ ├── test_get_schema_arn_from_state_machine_arn.py
│ │ │ ├── test_get_schema_from_registry.py
│ │ │ ├── test_invoke_express_state_machine_impl.py
│ │ │ ├── test_invoke_standard_state_machine_impl.py
│ │ │ ├── test_main.py
│ │ │ ├── test_register_state_machines.py
│ │ │ ├── test_sanitize_tool_name.py
│ │ │ ├── test_server.py
│ │ │ └── test_validate_state_machine_name.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── syntheticdata-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── syntheticdata_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── pandas_interpreter.py
│ │ │ ├── server.py
│ │ │ └── storage
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── loader.py
│ │ │ └── s3.py
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── test_constants.py
│ │ │ ├── test_pandas_interpreter.py
│ │ │ ├── test_server.py
│ │ │ └── test_storage
│ │ │ ├── __init__.py
│ │ │ ├── test_loader.py
│ │ │ └── test_s3.py
│ │ └── uv.lock
│ ├── terraform-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── terraform_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── impl
│ │ │ │ ├── resources
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── terraform_aws_provider_resources_listing.py
│ │ │ │ │ └── terraform_awscc_provider_resources_listing.py
│ │ │ │ └── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── execute_terraform_command.py
│ │ │ │ ├── execute_terragrunt_command.py
│ │ │ │ ├── run_checkov_scan.py
│ │ │ │ ├── search_aws_provider_docs.py
│ │ │ │ ├── search_awscc_provider_docs.py
│ │ │ │ ├── search_specific_aws_ia_modules.py
│ │ │ │ ├── search_user_provided_module.py
│ │ │ │ └── utils.py
│ │ │ ├── models
│ │ │ │ ├── __init__.py
│ │ │ │ └── models.py
│ │ │ ├── scripts
│ │ │ │ ├── generate_aws_provider_resources.py
│ │ │ │ ├── generate_awscc_provider_resources.py
│ │ │ │ └── scrape_aws_terraform_best_practices.py
│ │ │ ├── server.py
│ │ │ └── static
│ │ │ ├── __init__.py
│ │ │ ├── AWS_PROVIDER_RESOURCES.md
│ │ │ ├── AWS_TERRAFORM_BEST_PRACTICES.md
│ │ │ ├── AWSCC_PROVIDER_RESOURCES.md
│ │ │ ├── MCP_INSTRUCTIONS.md
│ │ │ └── TERRAFORM_WORKFLOW_GUIDE.md
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── .gitignore
│ │ │ ├── conftest.py
│ │ │ ├── README.md
│ │ │ ├── test_command_impl.py
│ │ │ ├── test_execute_terraform_command.py
│ │ │ ├── test_execute_terragrunt_command.py
│ │ │ ├── test_models.py
│ │ │ ├── test_parameter_annotations.py
│ │ │ ├── test_resources.py
│ │ │ ├── test_run_checkov_scan.py
│ │ │ ├── test_search_user_provided_module.py
│ │ │ ├── test_server.py
│ │ │ ├── test_tool_implementations.py
│ │ │ ├── test_utils_additional.py
│ │ │ └── test_utils.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── timestream-for-influxdb-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── timestream_for_influxdb_mcp_server
│ │ │ ├── __init__.py
│ │ │ └── server.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_init.py
│ │ │ ├── test_main.py
│ │ │ └── test_server.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ ├── valkey-mcp-server
│ │ ├── .gitignore
│ │ ├── .python-version
│ │ ├── awslabs
│ │ │ ├── __init__.py
│ │ │ └── valkey_mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── common
│ │ │ │ ├── __init__.py
│ │ │ │ ├── config.py
│ │ │ │ ├── connection.py
│ │ │ │ └── server.py
│ │ │ ├── context.py
│ │ │ ├── main.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── bitmap.py
│ │ │ │ ├── hash.py
│ │ │ │ ├── hyperloglog.py
│ │ │ │ ├── json.py
│ │ │ │ ├── list.py
│ │ │ │ ├── misc.py
│ │ │ │ ├── server_management.py
│ │ │ │ ├── set.py
│ │ │ │ ├── sorted_set.py
│ │ │ │ ├── stream.py
│ │ │ │ └── string.py
│ │ │ └── version.py
│ │ ├── CHANGELOG.md
│ │ ├── docker-healthcheck.sh
│ │ ├── Dockerfile
│ │ ├── ELASTICACHECONNECT.md
│ │ ├── LICENSE
│ │ ├── NOTICE
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_bitmap.py
│ │ │ ├── test_config.py
│ │ │ ├── test_connection.py
│ │ │ ├── test_hash.py
│ │ │ ├── test_hyperloglog.py
│ │ │ ├── test_init.py
│ │ │ ├── test_json_additional.py
│ │ │ ├── test_json_readonly.py
│ │ │ ├── test_json.py
│ │ │ ├── test_list_additional.py
│ │ │ ├── test_list_readonly.py
│ │ │ ├── test_list.py
│ │ │ ├── test_main.py
│ │ │ ├── test_misc.py
│ │ │ ├── test_server_management.py
│ │ │ ├── test_set_readonly.py
│ │ │ ├── test_set.py
│ │ │ ├── test_sorted_set_additional.py
│ │ │ ├── test_sorted_set_readonly.py
│ │ │ ├── test_sorted_set.py
│ │ │ ├── test_stream_additional.py
│ │ │ ├── test_stream_readonly.py
│ │ │ ├── test_stream.py
│ │ │ └── test_string.py
│ │ ├── uv-requirements.txt
│ │ └── uv.lock
│ └── well-architected-security-mcp-server
│ ├── .python-version
│ ├── awslabs
│ │ └── well_architected_security_mcp_server
│ │ ├── __init__.py
│ │ ├── consts.py
│ │ ├── server.py
│ │ └── util
│ │ ├── __init__.py
│ │ ├── network_security.py
│ │ ├── prompt_utils.py
│ │ ├── resource_utils.py
│ │ ├── security_services.py
│ │ └── storage_security.py
│ ├── PROMPT_TEMPLATE.md
│ ├── pyproject.toml
│ ├── README.md
│ ├── tests
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── README.md
│ │ ├── test_access_analyzer_fix.py
│ │ ├── test_network_security_additional.py
│ │ ├── test_network_security.py
│ │ ├── test_prompt_utils_coverage.py
│ │ ├── test_prompt_utils.py
│ │ ├── test_resource_utils_fix.py
│ │ ├── test_resource_utils.py
│ │ ├── test_security_services_additional.py
│ │ ├── test_security_services_coverage.py
│ │ ├── test_security_services.py
│ │ ├── test_server_additional.py
│ │ ├── test_server_coverage.py
│ │ ├── test_server_prompts.py
│ │ ├── test_server_security_findings.py
│ │ ├── test_server.py
│ │ ├── test_storage_security_additional.py
│ │ ├── test_storage_security_comprehensive.py
│ │ ├── test_storage_security_edge_cases.py
│ │ ├── test_storage_security_recommendations.py
│ │ ├── test_storage_security.py
│ │ └── test_user_agent_config.py
│ └── uv.lock
└── VIBE_CODING_TIPS_TRICKS.md
```
# Files
--------------------------------------------------------------------------------
/src/aws-dataprocessing-mcp-server/tests/handlers/glue/test_data_catalog_handler.py:
--------------------------------------------------------------------------------
```python
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the Glue Data Catalog Handler."""
import pytest
from awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler import (
GlueDataCatalogHandler,
)
from unittest.mock import ANY, AsyncMock, MagicMock, patch
class TestGlueDataCatalogHandler:
"""Tests for the GlueDataCatalogHandler class."""
@pytest.fixture
def mock_mcp(self):
"""Create a mock MCP server."""
mock = MagicMock()
return mock
@pytest.fixture
def mock_ctx(self):
"""Create a mock Context."""
mock = MagicMock()
return mock
@pytest.fixture
def mock_database_manager(self):
"""Create a mock DataCatalogDatabaseManager."""
mock = AsyncMock()
return mock
@pytest.fixture
def mock_table_manager(self):
"""Create a mock DataCatalogTableManager."""
mock = AsyncMock()
return mock
@pytest.fixture
def mock_catalog_manager(self):
"""Create a mock DataCatalogManager."""
mock = AsyncMock()
return mock
@pytest.fixture
def handler(self, mock_mcp, mock_database_manager, mock_table_manager, mock_catalog_manager):
"""Create a GlueDataCatalogHandler instance with mocked dependencies."""
with (
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogDatabaseManager',
return_value=mock_database_manager,
),
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogTableManager',
return_value=mock_table_manager,
),
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogManager',
return_value=mock_catalog_manager,
),
):
handler = GlueDataCatalogHandler(mock_mcp)
handler.data_catalog_database_manager = mock_database_manager
handler.data_catalog_table_manager = mock_table_manager
handler.data_catalog_manager = mock_catalog_manager
return handler
@pytest.fixture
def handler_with_write_access(
self, mock_mcp, mock_database_manager, mock_table_manager, mock_catalog_manager
):
"""Create a GlueDataCatalogHandler instance with write access enabled."""
with (
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogDatabaseManager',
return_value=mock_database_manager,
),
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogTableManager',
return_value=mock_table_manager,
),
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogManager',
return_value=mock_catalog_manager,
),
):
handler = GlueDataCatalogHandler(mock_mcp, allow_write=True)
handler.data_catalog_database_manager = mock_database_manager
handler.data_catalog_table_manager = mock_table_manager
handler.data_catalog_manager = mock_catalog_manager
return handler
def test_initialization(self, mock_mcp):
"""Test that the handler is initialized correctly."""
# Mock the AWS helper's create_boto3_client method to avoid boto3 client creation
with patch(
'awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client',
return_value=MagicMock(),
):
handler = GlueDataCatalogHandler(mock_mcp)
# Verify that the handler has the correct attributes
assert handler.mcp == mock_mcp
assert handler.allow_write is False
assert handler.allow_sensitive_data_access is False
# Verify that the tools were registered
assert mock_mcp.tool.call_count == 5
# Get all call args
call_args_list = mock_mcp.tool.call_args_list
# Get all tool names that were registered
tool_names = [call_args[1]['name'] for call_args in call_args_list]
# Verify that expected tools are registered
assert 'manage_aws_glue_databases' in tool_names
assert 'manage_aws_glue_tables' in tool_names
assert 'manage_aws_glue_connections' in tool_names
assert 'manage_aws_glue_partitions' in tool_names
assert 'manage_aws_glue_catalog' in tool_names
def test_initialization_with_write_access(self, mock_mcp):
"""Test that the handler is initialized correctly with write access."""
# Mock the AWS helper's create_boto3_client method to avoid boto3 client creation
with patch(
'awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client',
return_value=MagicMock(),
):
handler = GlueDataCatalogHandler(mock_mcp, allow_write=True)
# Verify that the handler has the correct attributes
assert handler.mcp == mock_mcp
assert handler.allow_write is True
assert handler.allow_sensitive_data_access is False
def test_initialization_with_sensitive_data_access(self, mock_mcp):
"""Test that the handler is initialized correctly with sensitive data access."""
# Mock the AWS helper's create_boto3_client method to avoid boto3 client creation
with patch(
'awslabs.aws_dataprocessing_mcp_server.utils.aws_helper.AwsHelper.create_boto3_client',
return_value=MagicMock(),
):
handler = GlueDataCatalogHandler(mock_mcp, allow_sensitive_data_access=True)
# Verify that the handler has the correct attributes
assert handler.mcp == mock_mcp
assert handler.allow_write is False
assert handler.allow_sensitive_data_access is True
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_create_no_write_access(
self, handler, mock_ctx
):
"""Test that create database operation is not allowed without write access."""
# Mock the response class
mock_response = MagicMock()
mock_response.isError = True
mock_response.content = [MagicMock()]
mock_response.content[
0
].text = 'Operation create-database is not allowed without write access'
mock_response.database_name = ''
mock_response.operation = 'create'
# Patch the CreateDatabaseResponse class
with patch(
'awslabs.aws_dataprocessing_mcp_server.models.data_catalog_models.CreateDatabaseResponse',
return_value=mock_response,
):
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='create-database', database_name='test-db'
)
# Verify the result
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.database_name == ''
assert result.operation == 'create-database'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_delete_no_write_access(
self, handler, mock_ctx
):
"""Test that delete database operation is not allowed without write access."""
# Mock the response class
mock_response = MagicMock()
mock_response.isError = True
mock_response.content = [MagicMock()]
mock_response.content[
0
].text = 'Operation delete-database is not allowed without write access'
mock_response.database_name = ''
mock_response.operation = 'delete'
# Patch the DeleteDatabaseResponse class
with patch(
'awslabs.aws_dataprocessing_mcp_server.models.data_catalog_models.DeleteDatabaseResponse',
return_value=mock_response,
):
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='delete-database', database_name='test-db'
)
# Verify the result
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.database_name == ''
assert result.operation == 'delete-database'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_update_no_write_access(
self, handler, mock_ctx
):
"""Test that update database operation is not allowed without write access."""
# Mock the response class
mock_response = MagicMock()
mock_response.isError = True
mock_response.content = [MagicMock()]
mock_response.content[
0
].text = 'Operation update-database is not allowed without write access'
mock_response.database_name = ''
mock_response.operation = 'update'
# Patch the UpdateDatabaseResponse class
with patch(
'awslabs.aws_dataprocessing_mcp_server.models.data_catalog_models.UpdateDatabaseResponse',
return_value=mock_response,
):
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='update-database', database_name='test-db'
)
# Verify the result
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.database_name == ''
assert result.operation == 'update-database'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_get_read_access(
self, handler, mock_ctx, mock_database_manager
):
"""Test that get database operation is allowed with read access."""
from unittest.mock import ANY
# Mock the response class
mock_response = MagicMock()
mock_response.isError = False
mock_response.content = []
mock_response.database_name = 'test-db'
mock_response.description = 'Test database'
mock_response.location_uri = 's3://test-bucket/'
mock_response.parameters = {}
mock_response.creation_time = '2023-01-01T00:00:00Z'
mock_response.operation = 'get'
mock_response.catalog_id = '123456789012'
# Setup the mock to return a response
mock_database_manager.get_database.return_value = mock_response
# Call the method with a read operation
result = await handler.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='get-database', database_name='test-db'
)
# Verify that the method was called with the correct parameters
# Use ANY for catalog_id to handle the FieldInfo object
mock_database_manager.get_database.assert_called_once_with(
ctx=mock_ctx, database_name='test-db', catalog_id=ANY
)
# Verify that the result is the expected response
assert result == mock_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_get_missing_database_name(
self, handler, mock_ctx, mock_database_manager
):
"""Test that get database operation is allowed with read access."""
with pytest.raises(ValueError) as e:
await handler.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='get-database', database_name=None
)
assert 'database_name is required' in str(e.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_list_read_access(
self, handler, mock_ctx, mock_database_manager
):
"""Test that list databases operation is allowed with read access."""
from unittest.mock import ANY
# Mock the response class
mock_response = MagicMock()
mock_response.isError = False
mock_response.content = []
mock_response.databases = []
mock_response.count = 0
mock_response.catalog_id = '123456789012'
mock_response.operation = 'list'
# Setup the mock to return a response
mock_database_manager.list_databases.return_value = mock_response
# Call the method with a read operation
result = await handler.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='list-databases'
)
# Verify that the method was called with the correct parameters
# Use ANY for catalog_id to handle the FieldInfo object
mock_database_manager.list_databases.assert_called_once_with(
ctx=mock_ctx, catalog_id=ANY, max_results=ANY, next_token=ANY
)
# Verify that the result is the expected response
assert result == mock_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_create_with_write_access(
self, handler_with_write_access, mock_ctx, mock_database_manager
):
"""Test that create database operation is allowed with write access."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.operation = 'create'
mock_database_manager.create_database.return_value = expected_response
# Call the method with a write operation
result = await handler_with_write_access.manage_aws_glue_data_catalog_databases(
mock_ctx,
operation='create-database',
database_name='test-db',
description='Test database',
location_uri='s3://test-bucket/',
parameters={'key': 'value'},
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_database_manager.create_database.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
description='Test database',
location_uri='s3://test-bucket/',
parameters={'key': 'value'},
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_delete_with_write_access(
self, handler_with_write_access, mock_ctx, mock_database_manager
):
"""Test that delete database operation is allowed with write access."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.operation = 'delete'
mock_database_manager.delete_database.return_value = expected_response
# Call the method with a write operation
result = await handler_with_write_access.manage_aws_glue_data_catalog_databases(
mock_ctx,
operation='delete-database',
database_name='test-db',
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_database_manager.delete_database.assert_called_once_with(
ctx=mock_ctx, database_name='test-db', catalog_id='123456789012'
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_delete_missing_database_name(
self, handler_with_write_access, mock_ctx
):
"""Test that delete database operation with missing database name."""
with pytest.raises(ValueError) as e:
await handler_with_write_access.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='delete-database', database_name=None
)
assert 'database_name is required' in str(e.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_update_missing_database_name(
self, handler_with_write_access, mock_ctx
):
"""Test that get database operation with write access."""
with pytest.raises(ValueError) as e:
await handler_with_write_access.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='update-database', database_name=None
)
assert 'database_name is required' in str(e.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_update_with_read_access(
self, handler, mock_ctx
):
"""Test that updadte database operation with read access."""
result = await handler.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='update-database', database_name=None
)
assert result.isError is True
assert len(result.content) == 1
assert 'is not allowed without write access' in result.content[0].text
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_update_with_write_access(
self, handler_with_write_access, mock_ctx, mock_database_manager
):
"""Test that update database operation is allowed with write access."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.operation = 'update'
mock_database_manager.update_database.return_value = expected_response
# Call the method with a write operation
result = await handler_with_write_access.manage_aws_glue_data_catalog_databases(
mock_ctx,
operation='update-database',
database_name='test-db',
description='Updated database',
location_uri='s3://updated-bucket/',
parameters={'key': 'updated-value'},
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_database_manager.update_database.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
description='Updated database',
location_uri='s3://updated-bucket/',
parameters={'key': 'updated-value'},
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_invalid_operation(
self, handler, mock_ctx
):
"""Test that an invalid operation returns an error response."""
# Set write access to true to bypass the "not allowed without write access" check
handler.allow_write = True
# Call the method with an invalid operation
result = await handler.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='invalid-operation', database_name='test-db'
)
# Verify that the result is an error response
assert result.isError is True
assert 'Invalid operation' in result.content[0].text
assert result.database_name == ''
assert result.operation == 'get-database'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_missing_database_name(
self, handler_with_write_access, mock_ctx
):
"""Test that missing database_name parameter raises a ValueError."""
# Call the method without database_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='create-database', database_name=None
)
# Verify that the correct error message is raised
assert 'database_name is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_exception_handling(
self, handler, mock_ctx, mock_database_manager
):
"""Test that exceptions are handled correctly."""
# Setup the mock to raise an exception
mock_database_manager.get_database.side_effect = Exception('Test exception')
# Patch the handler's method to handle the exception properly
with patch.object(
handler,
'manage_aws_glue_data_catalog_databases',
side_effect=handler.manage_aws_glue_data_catalog_databases,
):
# Create a mock response for the GetDatabaseResponse
mock_response = MagicMock()
mock_response.isError = True
mock_response.content = [MagicMock()]
mock_response.content[
0
].text = 'Error in manage_aws_glue_data_catalog_databases: Test exception'
mock_response.database_name = 'test-db'
mock_response.operation = 'get'
# Patch the GetDatabaseResponse class
with patch(
'awslabs.aws_dataprocessing_mcp_server.models.data_catalog_models.GetDatabaseResponse',
return_value=mock_response,
):
# Call the method
result = await handler.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='get-database', database_name='test-db'
)
# Verify that the result is an error response
assert result.isError is True
assert (
'Error in manage_aws_glue_data_catalog_databases: Test exception'
in result.content[0].text
)
assert result.database_name == 'test-db'
assert result.operation == 'get-database'
# Tests for manage_aws_glue_data_catalog_tables method
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_create_no_write_access(
self, handler, mock_ctx
):
"""Test that create table operation is not allowed without write access."""
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='create-table',
database_name='test-db',
table_name='test-table',
table_input={},
)
# Verify that the result is an error response
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.database_name == 'test-db'
assert result.table_name == ''
assert result.operation == 'create-table'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_get_read_access(
self, handler, mock_ctx, mock_table_manager
):
"""Test that get table operation is allowed with read access."""
from unittest.mock import ANY
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.table_definition = {}
expected_response.creation_time = '2023-01-01T00:00:00Z'
expected_response.last_access_time = '2023-01-01T00:00:00Z'
expected_response.operation = 'get'
mock_table_manager.get_table.return_value = expected_response
# Call the method with a read operation
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx, operation='get-table', database_name='test-db', table_name='test-table'
)
# Verify that the method was called with the correct parameters
# Use ANY for catalog_id to handle the FieldInfo object
mock_table_manager.get_table.assert_called_once_with(
ctx=mock_ctx, database_name='test-db', table_name='test-table', catalog_id=ANY
)
# Verify that the result is the expected response
assert result == expected_response
# Tests for manage_aws_glue_data_catalog_connections method
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_create_no_write_access(
self, handler, mock_ctx
):
"""Test that create connection operation is not allowed without write access."""
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='create-connection',
connection_name='test-connection',
connection_input={},
)
# Verify that the result is an error response
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.connection_name == ''
assert result.operation == 'create-connection'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_get_read_access(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test that get connection operation is allowed with read access."""
from unittest.mock import ANY
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connection_name = 'test-connection'
expected_response.connection_type = 'JDBC'
expected_response.connection_properties = {}
expected_response.physical_connection_requirements = None
expected_response.creation_time = '2023-01-01T00:00:00Z'
expected_response.last_updated_time = '2023-01-01T00:00:00Z'
expected_response.last_updated_by = ''
expected_response.status = ''
expected_response.status_reason = ''
expected_response.last_connection_validation_time = ''
expected_response.catalog_id = ''
expected_response.operation = 'get'
mock_catalog_manager.get_connection.return_value = expected_response
# Call the method with a read operation
result = await handler.manage_aws_glue_data_catalog_connections(
mock_ctx, operation='get-connection', connection_name='test-connection'
)
# Verify that the method was called with the correct parameters
# Use ANY for catalog_id to handle the FieldInfo object
mock_catalog_manager.get_connection.assert_called_once_with(
ctx=mock_ctx, connection_name='test-connection', catalog_id=ANY, hide_password=ANY
)
# Verify that the result is the expected response
assert result == expected_response
# Tests for manage_aws_glue_data_catalog_partitions method
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_create_no_write_access(
self, handler, mock_ctx
):
"""Test that create partition operation is not allowed without write access."""
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='create-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
partition_input={},
)
# Verify that the result is an error response
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.database_name == 'test-db'
assert result.table_name == 'test-table'
assert result.partition_values == []
assert result.operation == 'create-partition'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_get_read_access(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test that get partition operation is allowed with read access."""
from unittest.mock import ANY
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.partition_values = ['2023']
expected_response.partition_definition = {}
expected_response.creation_time = '2023-01-01T00:00:00Z'
expected_response.last_access_time = '2023-01-01T00:00:00Z'
expected_response.operation = 'get'
mock_catalog_manager.get_partition.return_value = expected_response
# Call the method with a read operation
result = await handler.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='get-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
)
# Verify that the method was called with the correct parameters
# Use ANY for catalog_id to handle the FieldInfo object
mock_catalog_manager.get_partition.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
catalog_id=ANY,
)
# Verify that the result is the expected response
assert result == expected_response
# Tests for manage_aws_glue_data_catalog method
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_create_no_write_access(self, handler, mock_ctx):
"""Test that create catalog operation is not allowed without write access."""
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog(
mock_ctx, operation='create-catalog', catalog_id='test-catalog', catalog_input={}
)
# Verify that the result is an error response
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.catalog_id == ''
assert result.operation == 'create-catalog'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_get_read_access(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test that get catalog operation is allowed with read access."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.catalog_id = 'test-catalog'
expected_response.catalog_definition = {}
expected_response.name = 'Test Catalog'
expected_response.description = 'Test catalog description'
expected_response.create_time = '2023-01-01T00:00:00Z'
expected_response.update_time = '2023-01-01T00:00:00Z'
expected_response.operation = 'get'
mock_catalog_manager.get_catalog.return_value = expected_response
# Call the method with a read operation
result = await handler.manage_aws_glue_data_catalog(
mock_ctx, operation='get-catalog', catalog_id='test-catalog'
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.get_catalog.assert_called_once_with(
ctx=mock_ctx, catalog_id='test-catalog'
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_create_with_write_access(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test that create catalog operation is allowed with write access."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.catalog_id = 'test-catalog'
expected_response.operation = 'create-catalog'
mock_catalog_manager.create_catalog.return_value = expected_response
# Call the method with a write operation
result = await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx,
operation='create-catalog',
catalog_id='test-catalog',
catalog_input={'Description': 'Test catalog', 'Type': 'GLUE'},
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.create_catalog.assert_called_once_with(
ctx=mock_ctx,
catalog_name='test-catalog',
catalog_input={'Description': 'Test catalog', 'Type': 'GLUE'},
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_delete_with_write_access(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test that delete catalog operation is allowed with write access."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.catalog_id = 'test-catalog'
expected_response.operation = 'delete-catalog'
mock_catalog_manager.delete_catalog.return_value = expected_response
# Call the method with a write operation
result = await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx, operation='delete-catalog', catalog_id='test-catalog'
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.delete_catalog.assert_called_once_with(
ctx=mock_ctx, catalog_id='test-catalog'
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_invalid_operation(self, handler, mock_ctx):
"""Test that an invalid operation returns an error response."""
# Set write access to true to bypass the "not allowed without write access" check
handler.allow_write = True
# Call the method with an invalid operation
result = await handler.manage_aws_glue_data_catalog(
mock_ctx, operation='invalid-operation', catalog_id='test-catalog'
)
# Verify that the result is an error response
assert result.isError is True
assert 'Invalid operation' in result.content[0].text
assert result.catalog_id == ''
assert result.operation == 'get-catalog'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_list_catalogs(self, handler, mock_ctx):
"""Test that list_catalogs operation returns a not implemented error."""
# Call the method with list-catalogs operation
mock_response = MagicMock()
mock_response.isError = False
mock_response.content = []
mock_response.catalogs = []
mock_response.count = 0
mock_response.catalog_id = '123456789012'
mock_response.operation = 'list-catalogs'
handler.data_catalog_manager.list_catalogs.return_value = mock_response
result = await handler.manage_aws_glue_data_catalog(mock_ctx, operation='list-catalogs')
assert result.isError is False
assert result.operation == 'list-catalogs'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_list_catalogs_error(self, handler, mock_ctx):
"""Test that list_catalogs operation returns a not implemented error."""
with patch.object(
handler.data_catalog_manager,
'list_catalogs',
side_effect=Exception('Invalid next_token provided'),
):
with pytest.raises(Exception) as e:
result = await handler.manage_aws_glue_data_catalog(
mock_ctx, operation='list-catalogs'
)
assert result.isError is False
assert result.operation == 'list-catalogs'
assert 'Invalid next_token provided' in str(e)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_import_catalog_with_read_only_access(
self, handler, mock_ctx
):
"""Test that import_catalog_to_glue operation returns a not implemented error."""
# Call the method with import-catalog-to-glue operation
result = await handler.manage_aws_glue_data_catalog(
mock_ctx,
operation='import-catalog-to-glue',
catalog_id='test-catalog',
)
assert result.isError is True
assert result.operation == 'import-catalog-to-glue'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_import_catalog(
self, handler_with_write_access, mock_ctx
):
"""Test that import_catalog_to_glue operation returns a not implemented error."""
# Call the method with import-catalog-to-glue operation
mock_response = MagicMock()
mock_response.isError = False
mock_response.content = []
mock_response.catalog_id = '123456789012'
mock_response.operation = 'import-catalog-to-glue'
handler_with_write_access.data_catalog_manager.import_catalog_to_glue.return_value = (
mock_response
)
result = await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx,
operation='import-catalog-to-glue',
catalog_id='test-catalog',
)
assert result.isError is False
assert result.operation == 'import-catalog-to-glue'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_missing_catalog_id(
self, handler_with_write_access, mock_ctx
):
"""Test that missing catalog_id parameter causes an error."""
# Mock the error response
error_response = MagicMock()
error_response.isError = True
error_response.catalog_id = ''
error_response.operation = 'create-catalog'
# Mock the create_catalog method to return the error response
handler_with_write_access.data_catalog_manager.create_catalog.return_value = error_response
# Call the method without catalog_id
result = await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx, operation='create-catalog', catalog_input={}, catalog_id='123456'
)
# Verify that the result is the expected error response
assert result == error_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_exception_handling(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test that exceptions are handled correctly in manage_aws_glue_data_catalog."""
# Setup the mock to raise an exception
mock_catalog_manager.get_catalog.side_effect = Exception('Test exception')
# Call the method
result = await handler.manage_aws_glue_data_catalog(
mock_ctx, operation='get-catalog', catalog_id='test-catalog'
)
# Verify that the result is an error response
assert result.isError is True
assert 'Error in manage_aws_glue_data_catalog' in result.content[0].text
assert 'Test exception' in result.content[0].text
assert result.catalog_id == 'test-catalog'
assert result.operation == 'get-catalog'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_list_tables_error(
self, handler_with_write_access, mock_ctx, mock_table_manager
):
"""Test that list_tables handles errors correctly."""
# Setup the mock to raise an exception
mock_table_manager.list_tables.side_effect = Exception('Test exception')
# Call the method
result = await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx, operation='list-tables', database_name='test-db'
)
# Verify that the result is an error response
assert result.isError is True
assert any(
'Error in manage_aws_glue_data_catalog_tables: Test exception' in content.text
for content in result.content
)
assert result.database_name == 'test-db'
assert result.table_name == '' # Empty string for table_name in error responses
assert result.operation == 'get-table'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_search_tables_error(
self, handler_with_write_access, mock_ctx, mock_table_manager
):
"""Test that search_tables handles errors correctly."""
# Setup the mock to raise an exception
mock_table_manager.search_tables.side_effect = Exception('Test exception')
# Call the method
result = await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx, operation='search-tables', database_name='test-db', search_text='test'
)
# Verify that the result is an error response
assert result.isError is True
assert any(
'Error in manage_aws_glue_data_catalog_tables: Test exception' in content.text
for content in result.content
)
assert result.database_name == 'test-db'
assert result.table_name == '' # Empty string for table_name in error responses
assert result.operation == 'get-table'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_missing_table_name(
self, handler_with_write_access, mock_ctx
):
"""Test that missing table_name parameter causes an error."""
# Call the method without table_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx, operation='get-table', database_name='test-db', table_name=None
)
# Verify that the correct error message is raised
assert 'table_name is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_list_connections_error(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test that list_connections handles errors correctly."""
# Setup the mock to raise an exception
mock_catalog_manager.list_connections.side_effect = Exception('Test exception')
# Call the method
result = await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx, operation='list-connections'
)
# Verify that the result is an error response
assert result.isError is True
assert any(
'Error in manage_aws_glue_data_catalog_connections: Test exception' in content.text
for content in result.content
)
assert result.connection_name == '' # Empty string for connection_name in error responses
assert result.catalog_id == '' # Empty string for catalog_id in error responses
assert result.operation == 'get-connection'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_missing_connection_name(
self, handler_with_write_access, mock_ctx
):
"""Test that missing connection_name parameter causes an error."""
# Mock the ValueError that should be raised
with patch.object(
handler_with_write_access.data_catalog_manager,
'get_connection',
side_effect=ValueError('connection_name is required for get operation'),
):
# Call the method without connection_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx, operation='get-connection'
)
# Verify that the correct error message is raised
assert 'connection_name is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_list_partitions_error(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test that list_partitions handles errors correctly."""
# Setup the mock to raise an exception
mock_catalog_manager.list_partitions.side_effect = Exception('Test exception')
# Call the method
result = await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx, operation='list-partitions', database_name='test-db', table_name='test-table'
)
# Verify that the result is an error response
assert result.isError is True
assert any(
'Error in manage_aws_glue_data_catalog_partitions: Test exception' in content.text
for content in result.content
)
assert result.database_name == 'test-db'
assert result.table_name == 'test-table'
assert result.partition_values == [] # Empty list for partition_values in error responses
assert result.operation == 'get-partition'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_missing_partition_values(
self, handler_with_write_access, mock_ctx
):
"""Test that missing partition_values parameter causes an error."""
# Mock the ValueError that should be raised
with patch.object(
handler_with_write_access.data_catalog_manager,
'get_partition',
side_effect=ValueError('partition_values is required for get-partition operation'),
):
# Call the method without partition_values
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='get-partition',
database_name='test-db',
table_name='test-table',
)
# Verify that the correct error message is raised
assert 'partition_values is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_delete_no_write_access(
self, handler, mock_ctx
):
"""Test that delete table operation is not allowed without write access."""
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='delete-table',
database_name='test-db',
table_name='test-table',
)
# Verify that the result is an error response
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.database_name == 'test-db'
assert result.table_name == ''
assert result.operation == 'delete-table'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_delete_no_write_access(
self, handler, mock_ctx
):
"""Test that delete connection operation is not allowed without write access."""
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_connections(
mock_ctx, operation='delete-connection', connection_name='test-connection'
)
# Verify that the result is an error response
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.connection_name == ''
assert result.operation == 'delete-connection'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_update_no_write_access(
self, handler, mock_ctx
):
"""Test that update connection operation is not allowed without write access."""
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='update-connection',
connection_name='test-connection',
connection_input={},
)
# Verify that the result is an error response
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.connection_name == ''
assert result.operation == 'update-connection'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_delete_no_write_access(
self, handler, mock_ctx
):
"""Test that delete partition operation is not allowed without write access."""
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='delete-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
)
# Verify that the result is an error response
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.database_name == 'test-db'
assert result.table_name == 'test-table'
assert result.partition_values == []
assert result.operation == 'delete-partition'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_update_no_write_access(
self, handler, mock_ctx
):
"""Test that update partition operation is not allowed without write access."""
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='update-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
partition_input={},
)
# Verify that the result is an error response
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.database_name == 'test-db'
assert result.table_name == 'test-table'
assert result.partition_values == []
assert result.operation == 'update-partition'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_delete_no_write_access(self, handler, mock_ctx):
"""Test that delete catalog operation is not allowed without write access."""
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog(
mock_ctx, operation='delete-catalog', catalog_id='test-catalog'
)
# Verify that the result is an error response
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.catalog_id == ''
assert result.operation == 'delete-catalog'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_with_all_parameters(
self, handler_with_write_access, mock_ctx, mock_database_manager
):
"""Test that all parameters are passed correctly to the database manager."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.operation = 'create'
mock_database_manager.create_database.return_value = expected_response
# Call the method with all parameters
result = await handler_with_write_access.manage_aws_glue_data_catalog_databases(
mock_ctx,
operation='create-database',
database_name='test-db',
description='Test database',
location_uri='s3://test-bucket/',
parameters={'key1': 'value1', 'key2': 'value2'},
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_database_manager.create_database.assert_called_once()
assert mock_database_manager.create_database.call_args[1]['database_name'] == 'test-db'
assert mock_database_manager.create_database.call_args[1]['description'] == 'Test database'
assert (
mock_database_manager.create_database.call_args[1]['location_uri']
== 's3://test-bucket/'
)
assert mock_database_manager.create_database.call_args[1]['parameters'] == {
'key1': 'value1',
'key2': 'value2',
}
assert mock_database_manager.create_database.call_args[1]['catalog_id'] == '123456789012'
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_with_short_operation_names(
self, handler_with_write_access, mock_ctx, mock_table_manager
):
"""Test that short operation names (create, delete, etc.) work correctly for tables."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.operation = 'create-table'
mock_table_manager.create_table.return_value = expected_response
# Call the method with a short operation name
result = await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='create-table', # Short form of 'create-table'
database_name='test-db',
table_name='test-table',
table_input={'Name': 'test-table'},
)
# Verify that the method was called with the correct parameters
mock_table_manager.create_table.assert_called_once()
assert mock_table_manager.create_table.call_args[1]['database_name'] == 'test-db'
assert mock_table_manager.create_table.call_args[1]['table_name'] == 'test-table'
assert mock_table_manager.create_table.call_args[1]['table_input'] == {
'Name': 'test-table'
}
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_search_with_short_operation_name(
self, handler, mock_ctx, mock_table_manager
):
"""Test that search operation with short name works correctly for tables."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.tables = []
expected_response.search_text = 'test'
expected_response.count = 0
expected_response.operation = 'search-tables'
mock_table_manager.search_tables.return_value = expected_response
# Call the method with a short operation name
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='search-tables', # Short form of 'search-tables'
database_name='test-db',
search_text='test',
)
# Verify that the method was called with the correct parameters
mock_table_manager.search_tables.assert_called_once()
assert mock_table_manager.search_tables.call_args[1]['search_text'] == 'test'
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_with_short_operation_names(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test that short operation names (create, delete, etc.) work correctly for connections."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connection_name = 'test-connection'
expected_response.operation = 'create-connection'
mock_catalog_manager.create_connection.return_value = expected_response
# Call the method with a short operation name
result = await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='create-connection', # Short form of 'create-connection'
connection_name='test-connection',
connection_input={'ConnectionType': 'JDBC'},
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.create_connection.assert_called_once()
assert (
mock_catalog_manager.create_connection.call_args[1]['connection_name']
== 'test-connection'
)
assert mock_catalog_manager.create_connection.call_args[1]['connection_input'] == {
'ConnectionType': 'JDBC'
}
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_with_short_operation_names(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test that short operation names (create, delete, etc.) work correctly for partitions."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.partition_values = ['2023']
expected_response.operation = 'create-partition'
mock_catalog_manager.create_partition.return_value = expected_response
# Call the method with a short operation name
result = await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='create-partition', # Short form of 'create-partition'
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
partition_input={'StorageDescriptor': {'Location': 's3://bucket/path/2023'}},
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.create_partition.assert_called_once()
assert mock_catalog_manager.create_partition.call_args[1]['database_name'] == 'test-db'
assert mock_catalog_manager.create_partition.call_args[1]['table_name'] == 'test-table'
assert mock_catalog_manager.create_partition.call_args[1]['partition_values'] == ['2023']
assert mock_catalog_manager.create_partition.call_args[1]['partition_input'] == {
'StorageDescriptor': {'Location': 's3://bucket/path/2023'}
}
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_with_short_operation_names(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test that short operation names (create, delete, etc.) work correctly for catalog."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.catalog_id = 'test-catalog'
expected_response.operation = 'create-catalog'
mock_catalog_manager.create_catalog.return_value = expected_response
# Call the method with a short operation name
result = await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx,
operation='create-catalog', # Short form of 'create-catalog'
catalog_id='test-catalog',
catalog_input={'Description': 'Test catalog'},
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.create_catalog.assert_called_once()
assert mock_catalog_manager.create_catalog.call_args[1]['catalog_name'] == 'test-catalog'
assert mock_catalog_manager.create_catalog.call_args[1]['catalog_input'] == {
'Description': 'Test catalog'
}
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_create_missing_table_input(
self, handler_with_write_access, mock_ctx
):
"""Test that missing table_input parameter for create-table operation raises a ValueError."""
# Mock the data_catalog_table_manager to raise the expected ValueError
handler_with_write_access.data_catalog_table_manager.create_table.side_effect = ValueError(
'table_name and table_input are required for create-table operation'
)
# Call the method without table_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='create-table',
database_name='test-db',
table_name='test-table',
)
# Verify that the correct error message is raised
assert 'database_name, table_input and table_name are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_update_missing_table_input(
self, handler_with_write_access, mock_ctx
):
"""Test that missing table_input parameter for update-table operation raises a ValueError."""
# Mock the data_catalog_table_manager to raise the expected ValueError
handler_with_write_access.data_catalog_table_manager.update_table.side_effect = ValueError(
'table_name and table_input are required for update-table operation'
)
# Call the method without table_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='update-table',
database_name='test-db',
table_name='test-table',
)
# Verify that the correct error message is raised
assert 'table_name and table_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_create_missing_connection_input(
self, handler_with_write_access, mock_ctx
):
"""Test that missing connection_input parameter for create operation raises a ValueError."""
# Mock the data_catalog_manager to raise the expected ValueError
handler_with_write_access.data_catalog_manager.create_connection.side_effect = ValueError(
'connection_name and connection_input are required for create operation'
)
# Call the method without connection_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='create-connection',
connection_name='test-connection',
)
# Verify that the correct error message is raised
assert 'connection_name and connection_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_update_missing_connection_input(
self, handler_with_write_access, mock_ctx
):
"""Test that missing connection_input parameter for update operation raises a ValueError."""
# Mock the data_catalog_manager to raise the expected ValueError
handler_with_write_access.data_catalog_manager.update_connection.side_effect = ValueError(
'connection_name and connection_input are required for update operation'
)
# Call the method without connection_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='update-connection',
connection_name='test-connection',
)
# Verify that the correct error message is raised
assert 'connection_name and connection_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_create_missing_partition_input(
self, handler_with_write_access, mock_ctx
):
"""Test that missing partition_input parameter for create-partition operation raises a ValueError."""
# Mock the data_catalog_manager to raise the expected ValueError
handler_with_write_access.data_catalog_manager.create_partition.side_effect = ValueError(
'partition_values and partition_input are required for create-partition operation'
)
# Call the method without partition_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='create-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
)
# Verify that the correct error message is raised
assert 'partition_values and partition_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_update_missing_partition_input(
self, handler_with_write_access, mock_ctx
):
"""Test that missing partition_input parameter for update-partition operation raises a ValueError."""
# Mock the data_catalog_manager to raise the expected ValueError
handler_with_write_access.data_catalog_manager.update_partition.side_effect = ValueError(
'partition_values and partition_input are required for update-partition operation'
)
# Call the method without partition_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='update-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
)
# Verify that the correct error message is raised
assert 'partition_values and partition_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_catalog_missing_catalog_input(
self, handler_with_write_access, mock_ctx
):
"""Test that missing catalog_input parameter for create-catalog operation raises a ValueError."""
# Mock the ValueError that should be raised
with patch.object(
handler_with_write_access.data_catalog_manager,
'create_catalog',
side_effect=ValueError('catalog_input is required for create-catalog operation'),
):
# Call the method without catalog_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx,
operation='create-catalog',
catalog_id='test-catalog',
)
# Verify that the correct error message is raised
assert 'catalog_id and catalog_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_create_with_table_input(
self, handler_with_write_access, mock_ctx, mock_table_manager
):
"""Test creating a table with a complete table input."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.operation = 'create-table'
mock_table_manager.create_table.return_value = expected_response
# Create a comprehensive table input
table_input = {
'Name': 'test-table',
'Description': 'Test table for unit testing',
'Owner': 'test-owner',
'TableType': 'EXTERNAL_TABLE',
'Parameters': {'classification': 'parquet', 'compressionType': 'snappy'},
'StorageDescriptor': {
'Columns': [
{'Name': 'id', 'Type': 'int'},
{'Name': 'name', 'Type': 'string'},
{'Name': 'timestamp', 'Type': 'timestamp'},
],
'Location': 's3://test-bucket/test-db/test-table/',
'InputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat',
'OutputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat',
'Compressed': True,
'SerdeInfo': {
'SerializationLibrary': 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe',
'Parameters': {'serialization.format': '1'},
},
},
'PartitionKeys': [
{'Name': 'year', 'Type': 'string'},
{'Name': 'month', 'Type': 'string'},
],
}
# Call the method with the table input
result = await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='create-table',
database_name='test-db',
table_name='test-table',
table_input=table_input,
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_table_manager.create_table.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
table_input=table_input,
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_update_with_table_input(
self, handler_with_write_access, mock_ctx, mock_table_manager
):
"""Test updating a table with a complete table input."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.operation = 'update-table'
mock_table_manager.update_table.return_value = expected_response
# Create a comprehensive table input for update
table_input = {
'Name': 'test-table',
'Description': 'Updated test table description',
'Owner': 'updated-owner',
'Parameters': {
'classification': 'parquet',
'compressionType': 'gzip', # Changed from snappy to gzip
'updatedAt': '2023-01-01',
},
'StorageDescriptor': {
'Columns': [
{'Name': 'id', 'Type': 'int'},
{'Name': 'name', 'Type': 'string'},
{'Name': 'timestamp', 'Type': 'timestamp'},
{'Name': 'new_column', 'Type': 'string'}, # Added a new column
],
'Location': 's3://test-bucket/test-db/test-table/',
'InputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat',
'OutputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat',
'Compressed': True,
'SerdeInfo': {
'SerializationLibrary': 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe',
'Parameters': {'serialization.format': '1'},
},
},
}
# Call the method with the table input
result = await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='update-table',
database_name='test-db',
table_name='test-table',
table_input=table_input,
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_table_manager.update_table.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
table_input=table_input,
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_create_with_connection_input(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test creating a connection with a complete connection input."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connection_name = 'test-jdbc-connection'
expected_response.operation = 'create-connection'
expected_response.catalog_id = '123456789012'
mock_catalog_manager.create_connection.return_value = expected_response
# Create a comprehensive connection input
connection_input = {
'ConnectionType': 'JDBC',
'ConnectionProperties': {
'JDBC_CONNECTION_URL': 'jdbc:mysql://test-host:3306/test-db',
'USERNAME': 'test-user',
'PASSWORD': 'test-password', # pragma: allowlist secret
'JDBC_ENFORCE_SSL': 'true',
},
'PhysicalConnectionRequirements': {
'AvailabilityZone': 'us-west-2a',
'SecurityGroupIdList': ['sg-12345678'],
'SubnetId': 'subnet-12345678',
},
'Description': 'Test JDBC connection for unit testing',
}
# Call the method with the connection input
result = await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='create-connection',
connection_name='test-jdbc-connection',
connection_input=connection_input,
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.create_connection.assert_called_once_with(
ctx=mock_ctx,
connection_name='test-jdbc-connection',
connection_input=connection_input,
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
assert result.connection_name == 'test-jdbc-connection'
assert result.catalog_id == '123456789012'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_update_with_connection_input(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test updating a connection with a complete connection input."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connection_name = 'test-jdbc-connection'
expected_response.operation = 'update-connection'
expected_response.catalog_id = '123456789012'
mock_catalog_manager.update_connection.return_value = expected_response
# Create a comprehensive connection input for update
connection_input = {
'ConnectionType': 'JDBC',
'ConnectionProperties': {
'JDBC_CONNECTION_URL': 'jdbc:mysql://updated-host:3306/updated-db',
'USERNAME': 'updated-user',
'PASSWORD': 'updated-password', # pragma: allowlist secret
'JDBC_ENFORCE_SSL': 'true',
},
'PhysicalConnectionRequirements': {
'AvailabilityZone': 'us-west-2b', # Changed from us-west-2a
'SecurityGroupIdList': ['sg-87654321'], # Changed security group
'SubnetId': 'subnet-87654321', # Changed subnet
},
'Description': 'Updated JDBC connection for unit testing',
}
# Call the method with the connection input
result = await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='update-connection',
connection_name='test-jdbc-connection',
connection_input=connection_input,
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.update_connection.assert_called_once_with(
ctx=mock_ctx,
connection_name='test-jdbc-connection',
connection_input=connection_input,
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
assert result.connection_name == 'test-jdbc-connection'
assert result.catalog_id == '123456789012'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_create_with_partition_input(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test creating a partition with a complete partition input."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.partition_values = ['2023', '01']
expected_response.operation = 'create-partition'
mock_catalog_manager.create_partition.return_value = expected_response
# Create a comprehensive partition input
partition_input = {
'StorageDescriptor': {
'Columns': [
{'Name': 'id', 'Type': 'int'},
{'Name': 'name', 'Type': 'string'},
{'Name': 'timestamp', 'Type': 'timestamp'},
],
'Location': 's3://test-bucket/test-db/test-table/year=2023/month=01/',
'InputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat',
'OutputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat',
'Compressed': True,
'SerdeInfo': {
'SerializationLibrary': 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe',
'Parameters': {'serialization.format': '1'},
},
},
'Parameters': {
'classification': 'parquet',
'compressionType': 'snappy',
'recordCount': '1000',
'averageRecordSize': '100',
},
'LastAccessTime': '2023-01-01T00:00:00Z',
}
# Call the method with the partition input
result = await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='create-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023', '01'],
partition_input=partition_input,
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.create_partition.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
partition_values=['2023', '01'],
partition_input=partition_input,
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
assert result.database_name == 'test-db'
assert result.table_name == 'test-table'
assert result.partition_values == ['2023', '01']
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_update_with_partition_input(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test updating a partition with a complete partition input."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.partition_values = ['2023', '01']
expected_response.operation = 'update-partition'
mock_catalog_manager.update_partition.return_value = expected_response
# Create a comprehensive partition input for update
partition_input = {
'StorageDescriptor': {
'Columns': [
{'Name': 'id', 'Type': 'int'},
{'Name': 'name', 'Type': 'string'},
{'Name': 'timestamp', 'Type': 'timestamp'},
{'Name': 'new_column', 'Type': 'string'}, # Added a new column
],
'Location': 's3://test-bucket/test-db/test-table/year=2023/month=01/',
'InputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat',
'OutputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat',
'Compressed': True,
'SerdeInfo': {
'SerializationLibrary': 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe',
'Parameters': {'serialization.format': '1'},
},
},
'Parameters': {
'classification': 'parquet',
'compressionType': 'gzip', # Changed from snappy to gzip
'recordCount': '2000', # Updated record count
'averageRecordSize': '120', # Updated average record size
'updatedAt': '2023-02-01T00:00:00Z', # Added update timestamp
},
'LastAccessTime': '2023-02-01T00:00:00Z', # Updated last access time
}
# Call the method with the partition input
result = await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='update-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023', '01'],
partition_input=partition_input,
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.update_partition.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
partition_values=['2023', '01'],
partition_input=partition_input,
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
assert result.database_name == 'test-db'
assert result.table_name == 'test-table'
assert result.partition_values == ['2023', '01']
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_search_tables_with_parameters(
self, handler, mock_ctx, mock_table_manager
):
"""Test that search tables operation works correctly with all parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.tables = [
{'DatabaseName': 'test-db', 'Name': 'test-table1', 'Description': 'First test table'},
{'DatabaseName': 'test-db', 'Name': 'test-table2', 'Description': 'Second test table'},
]
expected_response.search_text = 'test'
expected_response.count = 2
expected_response.operation = 'search-tables'
# expected_response.next_token = 'next-token-value'
mock_table_manager.search_tables.return_value = expected_response
# Call the method with search-tables operation and all parameters
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='search-tables',
database_name='test-db',
search_text='test',
max_results=10,
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_table_manager.search_tables.assert_called_once_with(
ctx=mock_ctx,
search_text='test',
max_results=10,
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
assert len(result.tables) == 2
assert result.tables[0]['Name'] == 'test-table1'
assert result.tables[1]['Name'] == 'test-table2'
assert result.search_text == 'test'
assert result.count == 2
# assert result.next_token == 'next-token-value'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_list_partitions_with_parameters(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test that list partitions operation works correctly with all parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.partitions = [
{
'Values': ['2023', '01'],
'StorageDescriptor': {'Location': 's3://bucket/path/2023/01'},
},
{
'Values': ['2023', '02'],
'StorageDescriptor': {'Location': 's3://bucket/path/2023/02'},
},
]
expected_response.count = 2
expected_response.operation = 'list-partitions'
# expected_response.next_token = 'next-token-value'
mock_catalog_manager.list_partitions.return_value = expected_response
# Call the method with list-partitions operation and all parameters
result = await handler.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='list-partitions',
database_name='test-db',
table_name='test-table',
max_results=10,
expression="year='2023'",
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.list_partitions.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
max_results=10,
expression="year='2023'",
catalog_id='123456789012',
next_token=ANY,
)
# Verify that the result is the expected response
assert result == expected_response
assert len(result.partitions) == 2
assert result.partitions[0]['Values'] == ['2023', '01']
assert result.partitions[1]['Values'] == ['2023', '02']
assert result.count == 2
# assert result.next_token == 'next-token-value'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_create_with_catalog_input(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test creating a catalog with a complete catalog input."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.catalog_id = 'test-catalog'
expected_response.operation = 'create-catalog'
mock_catalog_manager.create_catalog.return_value = expected_response
# Create a comprehensive catalog input
catalog_input = {
'Name': 'Test Catalog',
'Description': 'Test catalog for unit testing',
'Type': 'GLUE',
'Parameters': {'key1': 'value1', 'key2': 'value2'},
'Tags': {'Environment': 'Test', 'Project': 'UnitTest'},
}
# Call the method with the catalog input
result = await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx,
operation='create-catalog',
catalog_id='test-catalog',
catalog_input=catalog_input,
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.create_catalog.assert_called_once_with(
ctx=mock_ctx,
catalog_name='test-catalog',
catalog_input=catalog_input,
)
# Verify that the result is the expected response
assert result == expected_response
assert result.catalog_id == 'test-catalog'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_get_catalog_with_parameters(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test that get catalog operation works correctly with all parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.catalog_id = 'test-catalog'
expected_response.catalog_definition = {
'Name': 'Test Catalog',
'Description': 'Test catalog description',
'Type': 'GLUE',
'Parameters': {'key1': 'value1', 'key2': 'value2'},
}
expected_response.name = 'Test Catalog'
expected_response.description = 'Test catalog description'
expected_response.create_time = '2023-01-01T00:00:00Z'
expected_response.update_time = '2023-01-01T00:00:00Z'
expected_response.operation = 'get-catalog'
mock_catalog_manager.get_catalog.return_value = expected_response
# Call the method with get-catalog operation
result = await handler.manage_aws_glue_data_catalog(
mock_ctx,
operation='get-catalog',
catalog_id='test-catalog',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.get_catalog.assert_called_once_with(
ctx=mock_ctx,
catalog_id='test-catalog',
)
# Verify that the result is the expected response
assert result == expected_response
assert result.catalog_id == 'test-catalog'
assert result.name == 'Test Catalog'
assert result.description == 'Test catalog description'
assert result.create_time == '2023-01-01T00:00:00Z'
assert result.update_time == '2023-01-01T00:00:00Z'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_invalid_operation_with_write_access(
self, handler_with_write_access, mock_ctx
):
"""Test that an invalid operation returns an error response with write access."""
# Call the method with an invalid operation
result = await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx, operation='invalid-operation', database_name='test-db'
)
# Verify that the result is an error response
assert result.isError is True
assert 'Invalid operation' in result.content[0].text
assert result.database_name == 'test-db'
assert result.table_name == ''
assert result.operation == 'get-table'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_invalid_operation_with_write_access(
self, handler_with_write_access, mock_ctx
):
"""Test that an invalid operation returns an error response with write access."""
# Call the method with an invalid operation
result = await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx, operation='invalid-operation', connection_name='test-connection'
)
# Verify that the result is an error response
assert result.isError is True
assert 'Invalid operation' in result.content[0].text
assert result.connection_name == ''
assert result.operation == 'get-connection'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_invalid_operation_with_write_access(
self, handler_with_write_access, mock_ctx
):
"""Test that an invalid operation returns an error response with write access."""
# Call the method with an invalid operation
result = await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='invalid-operation',
database_name='test-db',
table_name='test-table',
)
# Verify that the result is an error response
assert result.isError is True
assert 'Invalid operation' in result.content[0].text
assert result.database_name == 'test-db'
assert result.table_name == 'test-table'
assert result.partition_values == []
assert result.operation == 'get-partition'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_search_tables_no_parameters(
self, handler, mock_ctx, mock_table_manager
):
"""Test that search tables operation works correctly with minimal parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.tables = []
expected_response.search_text = None
expected_response.count = 0
expected_response.operation = 'search-tables'
mock_table_manager.search_tables.return_value = expected_response
# Call the method with search-tables operation and minimal parameters
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='search-tables',
database_name='test-db',
)
# Verify that the method was called
assert mock_table_manager.search_tables.call_count == 1
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_list_partitions_no_parameters(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test that list partitions operation works correctly with minimal parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.partitions = []
expected_response.count = 0
expected_response.operation = 'list-partitions'
mock_catalog_manager.list_partitions.return_value = expected_response
# Call the method with list-partitions operation and minimal parameters
result = await handler.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='list-partitions',
database_name='test-db',
table_name='test-table',
)
# Verify that the method was called
assert mock_catalog_manager.list_partitions.call_count == 1
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_missing_catalog_id_for_get(
self, handler, mock_ctx
):
"""Test that missing catalog_id parameter for get-catalog operation returns an error response."""
# Call the method without catalog_id
with pytest.raises(ValueError) as e:
await handler.manage_aws_glue_data_catalog(
mock_ctx,
operation='get-catalog',
)
assert 'catalog_id is required' in str(e.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_missing_catalog_id_for_delete(
self, handler_with_write_access, mock_ctx
):
"""Test that missing catalog_id parameter for delete-catalog operation returns an error response."""
# Call the method without catalog_id
with pytest.raises(ValueError) as e:
await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx,
operation='delete-catalog',
)
assert 'catalog_id is required' in str(e.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_other_write_access_error(
self, handler, mock_ctx
):
"""Test that other write operations are not allowed without write access."""
# Call the method with a non-standard write operation
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='other-write-operation',
database_name='test-db',
table_name='test-table',
)
# Verify that the result is an error response
assert result.isError is True
assert 'Invalid operation' in result.content[0].text
assert result.database_name == 'test-db'
assert result.table_name == ''
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_other_write_access_error(
self, handler, mock_ctx
):
"""Test that other write operations are not allowed without write access."""
# Call the method with a non-standard write operation
result = await handler.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='other-write-operation',
connection_name='test-connection',
)
# Verify that the result is an error response
assert result.isError is True
assert 'Invalid operation' in result.content[0].text
assert result.connection_name == ''
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_other_write_access_error(
self, handler, mock_ctx
):
"""Test that other write operations are not allowed without write access."""
# Call the method with a non-standard write operation
result = await handler.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='other-write-operation',
database_name='test-db',
table_name='test-table',
)
# Verify that the result is an error response
assert result.isError is True
assert 'Invalid operation: other-write-operation' in result.content[0].text
assert result.database_name == 'test-db'
assert result.table_name == 'test-table'
assert result.partition_values == []
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_other_write_access_error(self, handler, mock_ctx):
"""Test that other write operations are not allowed without write access."""
# Call the method with a non-standard write operation
result = await handler.manage_aws_glue_data_catalog(
mock_ctx,
operation='other-write-operation',
catalog_id='test-catalog',
)
# Verify that the result is an error response
assert result.isError is True
assert 'Invalid operation: other-write-operation' in result.content[0].text
assert result.catalog_id == ''
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_create_with_catalog_id(
self, handler_with_write_access, mock_ctx, mock_table_manager
):
"""Test creating a table with a catalog ID."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.operation = 'create-table'
mock_table_manager.create_table.return_value = expected_response
# Call the method with a catalog ID
result = await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='create-table',
database_name='test-db',
table_name='test-table',
table_input={'Name': 'test-table'},
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_table_manager.create_table.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
table_input={'Name': 'test-table'},
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_list_tables_with_max_results(
self, handler, mock_ctx, mock_table_manager
):
"""Test listing tables with max_results parameter."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.tables = [{'Name': 'test-table1'}, {'Name': 'test-table2'}]
expected_response.count = 2
expected_response.operation = 'list-tables'
mock_table_manager.list_tables.return_value = expected_response
# Call the method with max_results
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='list-tables',
database_name='test-db',
max_results=10,
)
# Verify that the method was called with the correct parameters
assert mock_table_manager.list_tables.call_count == 1
assert mock_table_manager.list_tables.call_args[1]['max_results'] == 10
# Verify that the result is the expected response
assert result == expected_response
assert len(result.tables) == 2
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_get_with_catalog_id(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test getting a connection with a catalog ID."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connection_name = 'test-connection'
expected_response.operation = 'get-connection'
expected_response.catalog_id = '123456789012'
mock_catalog_manager.get_connection.return_value = expected_response
# Call the method with a catalog ID
result = await handler.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='get-connection',
connection_name='test-connection',
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
assert mock_catalog_manager.get_connection.call_count == 1
assert mock_catalog_manager.get_connection.call_args[1]['catalog_id'] == '123456789012'
# Verify that the result is the expected response
assert result == expected_response
assert result.catalog_id == '123456789012'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_get_with_catalog_id(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test getting a partition with a catalog ID."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.partition_values = ['2023', '01']
expected_response.operation = 'get-partition'
mock_catalog_manager.get_partition.return_value = expected_response
# Call the method with a catalog ID
result = await handler.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='get-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023', '01'],
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
assert mock_catalog_manager.get_partition.call_count == 1
assert mock_catalog_manager.get_partition.call_args[1]['catalog_id'] == '123456789012'
# Verify that the result is the expected response
assert result == expected_response
assert result.partition_values == ['2023', '01']
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_exception_handling_specific(
self, handler_with_write_access, mock_ctx, mock_table_manager
):
"""Test specific exception handling in manage_aws_glue_data_catalog_tables."""
# Setup the mock to raise a specific exception
mock_table_manager.create_table.side_effect = ValueError('Specific test exception')
# Call the method
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='create-table',
database_name='test-db',
table_name='test-table',
table_input={'Name': 'test-table'},
)
# Verify that the correct error message is raised
assert 'Specific test exception' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_exception_handling_specific(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test specific exception handling in manage_aws_glue_data_catalog_connections."""
# Setup the mock to raise a specific exception
mock_catalog_manager.create_connection.side_effect = ValueError('Specific test exception')
# Call the method
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='create-connection',
connection_name='test-connection',
connection_input={'ConnectionType': 'JDBC'},
)
# Verify that the correct error message is raised
assert 'Specific test exception' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_exception_handling_specific(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test specific exception handling in manage_aws_glue_data_catalog_partitions."""
# Setup the mock to raise a specific exception
mock_catalog_manager.create_partition.side_effect = ValueError('Specific test exception')
# Call the method
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='create-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023', '01'],
partition_input={'StorageDescriptor': {'Location': 's3://bucket/path/2023/01'}},
)
# Verify that the correct error message is raised
assert 'Specific test exception' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_exception_handling_specific(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test specific exception handling in manage_aws_glue_data_catalog."""
# Setup the mock to raise a specific exception
mock_catalog_manager.create_catalog.side_effect = ValueError('Specific test exception')
# Call the method
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx,
operation='create-catalog',
catalog_id='test-catalog',
catalog_input={'Description': 'Test catalog'},
)
# Verify that the correct error message is raised
assert 'Specific test exception' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_with_sensitive_data_access(
self, mock_mcp, mock_ctx, mock_database_manager
):
"""Test that the handler works correctly with sensitive data access."""
# Create a handler with sensitive data access
with (
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogDatabaseManager',
return_value=mock_database_manager,
),
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogTableManager',
return_value=MagicMock(),
),
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogManager',
return_value=MagicMock(),
),
):
handler = GlueDataCatalogHandler(mock_mcp, allow_sensitive_data_access=True)
handler.data_catalog_database_manager = mock_database_manager
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.operation = 'get'
mock_database_manager.get_database.return_value = expected_response
# Call the method
result = await handler.manage_aws_glue_data_catalog_databases(
mock_ctx,
operation='get-database',
database_name='test-db',
)
# Verify that the result is the expected response
assert result == expected_response
assert handler.allow_sensitive_data_access is True
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_with_both_access_flags(
self, mock_mcp, mock_ctx, mock_database_manager
):
"""Test that the handler works correctly with both write and sensitive data access."""
# Create a handler with both write and sensitive data access
with (
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogDatabaseManager',
return_value=mock_database_manager,
),
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogTableManager',
return_value=MagicMock(),
),
patch(
'awslabs.aws_dataprocessing_mcp_server.handlers.glue.data_catalog_handler.DataCatalogManager',
return_value=MagicMock(),
),
):
handler = GlueDataCatalogHandler(
mock_mcp, allow_write=True, allow_sensitive_data_access=True
)
handler.data_catalog_database_manager = mock_database_manager
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.operation = 'create'
mock_database_manager.create_database.return_value = expected_response
# Call the method
result = await handler.manage_aws_glue_data_catalog_databases(
mock_ctx,
operation='create-database',
database_name='test-db',
)
# Verify that the result is the expected response
assert result == expected_response
assert handler.allow_write is True
assert handler.allow_sensitive_data_access is True
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_update_no_write_access(
self, handler, mock_ctx
):
"""Test that update table operation is not allowed without write access."""
# Call the method with a write operation
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='update-table',
database_name='test-db',
table_name='test-table',
table_input={'Name': 'test-table'},
)
# Verify that the result is an error response
assert result.isError is True
assert 'not allowed without write access' in result.content[0].text
assert result.database_name == 'test-db'
assert result.table_name == ''
assert result.operation == 'update-table'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_search_tables_no_write_access(
self, handler, mock_ctx
):
"""Test that search tables operation is allowed without write access."""
# Mock the search_tables method to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.tables = []
expected_response.search_text = 'test'
expected_response.count = 0
expected_response.operation = 'search-tables'
handler.data_catalog_table_manager.search_tables.return_value = expected_response
# Call the method with a read operation
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='search-tables',
database_name='test-db',
search_text='test',
)
# Verify that the result is the expected response
assert result == expected_response
assert result.isError is False
assert handler.data_catalog_table_manager.search_tables.call_count == 1
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_list_tables_no_write_access(
self, handler, mock_ctx
):
"""Test that list tables operation is allowed without write access."""
# Mock the list_tables method to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.tables = []
expected_response.count = 0
expected_response.operation = 'list-tables'
handler.data_catalog_table_manager.list_tables.return_value = expected_response
# Call the method with a read operation
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='list-tables',
database_name='test-db',
)
# Verify that the result is the expected response
assert result == expected_response
assert result.isError is False
assert handler.data_catalog_table_manager.list_tables.call_count == 1
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_list_connections_no_write_access(
self, handler, mock_ctx
):
"""Test that list connections operation is allowed without write access."""
# Mock the list_connections method to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connections = []
expected_response.count = 0
expected_response.operation = 'list-connections'
handler.data_catalog_manager.list_connections.return_value = expected_response
# Call the method with a read operation
result = await handler.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='list-connections',
)
# Verify that the result is the expected response
assert result == expected_response
assert result.isError is False
assert handler.data_catalog_manager.list_connections.call_count == 1
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_get_partition_no_write_access(
self, handler, mock_ctx
):
"""Test that get partition operation is allowed without write access."""
# Mock the get_partition method to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.partition_values = ['2023']
expected_response.operation = 'get-partition'
handler.data_catalog_manager.get_partition.return_value = expected_response
# Call the method with a read operation
result = await handler.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='get-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
)
# Verify that the result is the expected response
assert result == expected_response
assert result.isError is False
assert handler.data_catalog_manager.get_partition.call_count == 1
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_get_catalog_no_write_access(
self, handler, mock_ctx
):
"""Test that get catalog operation is allowed without write access."""
# Mock the get_catalog method to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.catalog_id = 'test-catalog'
expected_response.operation = 'get-catalog'
handler.data_catalog_manager.get_catalog.return_value = expected_response
# Call the method with a read operation
result = await handler.manage_aws_glue_data_catalog(
mock_ctx,
operation='get-catalog',
catalog_id='test-catalog',
)
# Verify that the result is the expected response
assert result == expected_response
assert result.isError is False
assert handler.data_catalog_manager.get_catalog.call_count == 1
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_exception_handling_general(
self, handler, mock_ctx
):
"""Test general exception handling in manage_aws_glue_data_catalog_tables."""
# Mock the get_table method to raise a general exception
handler.data_catalog_table_manager.get_table.side_effect = Exception(
'General test exception'
)
# Call the method
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='get-table',
database_name='test-db',
table_name='test-table',
)
# Verify that the result is an error response
assert result.isError is True
assert (
'Error in manage_aws_glue_data_catalog_tables: General test exception'
in result.content[0].text
)
assert result.database_name == 'test-db'
assert result.table_name == ''
assert result.operation == 'get-table'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_exception_handling_general(
self, handler, mock_ctx
):
"""Test general exception handling in manage_aws_glue_data_catalog_connections."""
# Mock the get_connection method to raise a general exception
handler.data_catalog_manager.get_connection.side_effect = Exception(
'General test exception'
)
# Call the method
result = await handler.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='get-connection',
connection_name='test-connection',
)
# Verify that the result is an error response
assert result.isError is True
assert (
'Error in manage_aws_glue_data_catalog_connections: General test exception'
in result.content[0].text
)
assert result.connection_name == ''
assert result.operation == 'get-connection'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_exception_handling_general(
self, handler, mock_ctx
):
"""Test general exception handling in manage_aws_glue_data_catalog_partitions."""
# Mock the get_partition method to raise a general exception
handler.data_catalog_manager.get_partition.side_effect = Exception(
'General test exception'
)
# Call the method
result = await handler.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='get-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
)
# Verify that the result is an error response
assert result.isError is True
assert (
'Error in manage_aws_glue_data_catalog_partitions: General test exception'
in result.content[0].text
)
assert result.database_name == 'test-db'
assert result.table_name == 'test-table'
assert result.partition_values == []
assert result.operation == 'get-partition'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_exception_handling_general(
self, handler, mock_ctx
):
"""Test general exception handling in manage_aws_glue_data_catalog."""
# Mock the get_catalog method to raise a general exception
handler.data_catalog_manager.get_catalog.side_effect = Exception('General test exception')
# Call the method
result = await handler.manage_aws_glue_data_catalog(
mock_ctx,
operation='get-catalog',
catalog_id='test-catalog',
)
# Verify that the result is an error response
assert result.isError is True
assert (
'Error in manage_aws_glue_data_catalog: General test exception'
in result.content[0].text
)
assert result.catalog_id == 'test-catalog'
assert result.operation == 'get-catalog'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_error_response_for_other_operations(
self, handler, mock_ctx
):
"""Test that an error response is returned for operations not explicitly handled."""
# Set write access to true to bypass the "not allowed without write access" check
handler.allow_write = True
# Call the method with an operation that doesn't match any of the explicit cases
result = await handler.manage_aws_glue_data_catalog_databases(
mock_ctx,
operation='unknown-operation',
database_name='test-db',
)
# Verify that the result is an error response
assert result.isError is True
assert 'Invalid operation' in result.content[0].text
assert result.database_name == ''
assert result.description == ''
assert result.location_uri == ''
assert result.parameters == {}
assert result.creation_time == ''
assert result.operation == 'get-database'
assert result.catalog_id == ''
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_with_none_parameters(
self, handler_with_write_access, mock_ctx, mock_database_manager
):
"""Test that the handler works correctly with None parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.operation = 'create'
mock_database_manager.create_database.return_value = expected_response
# Call the method with None parameters
result = await handler_with_write_access.manage_aws_glue_data_catalog_databases(
mock_ctx,
operation='create-database',
database_name='test-db',
description=None,
location_uri=None,
parameters=None,
catalog_id=None,
)
# Verify that the method was called with the correct parameters
mock_database_manager.create_database.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
description=None,
location_uri=None,
parameters=None,
catalog_id=None,
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_with_none_parameters(
self, handler_with_write_access, mock_ctx, mock_table_manager
):
"""Test that the handler works correctly with None parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.operation = 'create-table'
mock_table_manager.create_table.return_value = expected_response
# Call the method with None parameters
result = await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='create-table',
database_name='test-db',
table_name='test-table',
table_input={'Name': 'test-table'},
catalog_id=None,
)
# Verify that the method was called with the correct parameters
mock_table_manager.create_table.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
table_input={'Name': 'test-table'},
catalog_id=None,
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_with_none_parameters(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test that the handler works correctly with None parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connection_name = 'test-connection'
expected_response.operation = 'create-connection'
mock_catalog_manager.create_connection.return_value = expected_response
# Call the method with None parameters
result = await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='create-connection',
connection_name='test-connection',
connection_input={'ConnectionType': 'JDBC'},
catalog_id=None,
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.create_connection.assert_called_once_with(
ctx=mock_ctx,
connection_name='test-connection',
connection_input={'ConnectionType': 'JDBC'},
catalog_id=None,
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_with_none_parameters(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test that the handler works correctly with None parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.partition_values = ['2023']
expected_response.operation = 'create-partition'
mock_catalog_manager.create_partition.return_value = expected_response
# Call the method with None parameters
result = await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='create-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
partition_input={'StorageDescriptor': {'Location': 's3://bucket/path/2023'}},
catalog_id=None,
max_results=None,
expression=None,
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.create_partition.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
partition_input={'StorageDescriptor': {'Location': 's3://bucket/path/2023'}},
catalog_id=None,
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_with_none_parameters(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test that the handler works correctly with None parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.catalog_id = 'test-catalog'
expected_response.operation = 'create-catalog'
mock_catalog_manager.create_catalog.return_value = expected_response
# Call the method with None parameters
result = await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx,
operation='create-catalog',
catalog_id='test-catalog',
catalog_input={'Description': 'Test catalog'},
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.create_catalog.assert_called_once_with(
ctx=mock_ctx,
catalog_name='test-catalog',
catalog_input={'Description': 'Test catalog'},
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_update_with_catalog_id(
self, handler_with_write_access, mock_ctx, mock_table_manager
):
"""Test updating a table with a catalog ID."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.operation = 'update-table'
mock_table_manager.update_table.return_value = expected_response
# Call the method with a catalog ID
result = await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='update-table',
database_name='test-db',
table_name='test-table',
table_input={'Name': 'test-table'},
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_table_manager.update_table.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
table_input={'Name': 'test-table'},
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_update_with_catalog_id(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test updating a connection with a catalog ID."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connection_name = 'test-connection'
expected_response.operation = 'update-connection'
expected_response.catalog_id = '123456789012'
mock_catalog_manager.update_connection.return_value = expected_response
# Call the method with a catalog ID
result = await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='update-connection',
connection_name='test-connection',
connection_input={'ConnectionType': 'JDBC'},
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.update_connection.assert_called_once_with(
ctx=mock_ctx,
connection_name='test-connection',
connection_input={'ConnectionType': 'JDBC'},
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
assert result.catalog_id == '123456789012'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_update_with_catalog_id(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test updating a partition with a catalog ID."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.partition_values = ['2023']
expected_response.operation = 'update-partition'
mock_catalog_manager.update_partition.return_value = expected_response
# Call the method with a catalog ID
result = await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='update-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
partition_input={'StorageDescriptor': {'Location': 's3://bucket/path/2023'}},
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.update_partition.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
partition_input={'StorageDescriptor': {'Location': 's3://bucket/path/2023'}},
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_delete_with_catalog_id(
self, handler_with_write_access, mock_ctx, mock_table_manager
):
"""Test deleting a table with a catalog ID."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.operation = 'delete-table'
mock_table_manager.delete_table.return_value = expected_response
# Call the method with a catalog ID
result = await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='delete-table',
database_name='test-db',
table_name='test-table',
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_table_manager.delete_table.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_delete_with_catalog_id(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test deleting a connection with a catalog ID."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connection_name = 'test-connection'
expected_response.operation = 'delete-connection'
expected_response.catalog_id = '123456789012'
mock_catalog_manager.delete_connection.return_value = expected_response
# Call the method with a catalog ID
result = await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='delete-connection',
connection_name='test-connection',
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.delete_connection.assert_called_once_with(
ctx=mock_ctx,
connection_name='test-connection',
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
assert result.catalog_id == '123456789012'
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_delete_with_catalog_id(
self, handler_with_write_access, mock_ctx, mock_catalog_manager
):
"""Test deleting a partition with a catalog ID."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.database_name = 'test-db'
expected_response.table_name = 'test-table'
expected_response.partition_values = ['2023']
expected_response.operation = 'delete-partition'
mock_catalog_manager.delete_partition.return_value = expected_response
# Call the method with a catalog ID
result = await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='delete-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.delete_partition.assert_called_once_with(
ctx=mock_ctx,
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
catalog_id='123456789012',
)
# Verify that the result is the expected response
assert result == expected_response
# Additional tests to increase coverage for specific lines
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_with_max_results(
self, handler, mock_ctx, mock_table_manager
):
"""Test listing tables with max_results parameter."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.tables = [{'Name': 'test-table1'}, {'Name': 'test-table2'}]
expected_response.count = 2
expected_response.operation = 'list-tables'
mock_table_manager.list_tables.return_value = expected_response
# Call the method with max_results
result = await handler.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='list-tables',
database_name='test-db',
max_results=10,
)
# Verify that the method was called with the correct parameters
assert mock_table_manager.list_tables.call_count == 1
assert mock_table_manager.list_tables.call_args[1]['max_results'] == 10
# Verify that the result is the expected response
assert result == expected_response
assert len(result.tables) == 2
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_databases_create_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that create database operation with missing required parameters raises a ValueError."""
# Mock the ValueError that should be raised
with patch.object(
handler_with_write_access.data_catalog_database_manager,
'create_database',
side_effect=ValueError('database_name is required for create-database operation'),
):
# Call the method without database_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_databases(
mock_ctx, operation='create-database'
)
# Verify that the correct error message is raised
assert 'database_name is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_create_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that create table operation with missing required parameters raises a ValueError."""
# Call the method without table_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx, operation='create-table', database_name='test-db', table_name=None
)
# Verify that the correct error message is raised
assert 'database_name, table_input and table_name are required' in str(excinfo.value)
# Call the method without table_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='create-table',
database_name='test-db',
table_name='test-table',
table_input=None,
)
# Verify that the correct error message is raised
assert 'database_name, table_input and table_name are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_delete_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that delete table operation with missing required parameters raises a ValueError."""
# Call the method without table_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx, operation='delete-table', database_name='test-db', table_name=None
)
# Verify that the correct error message is raised
assert 'table_name and database_name required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_get_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that get table operation with missing required parameters raises a ValueError."""
# Call the method without table_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx, operation='get-table', database_name='test-db', table_name=None
)
# Verify that the correct error message is raised
assert 'table_name is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_tables_update_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that update table operation with missing required parameters raises a ValueError."""
# Call the method without table_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx, operation='update-table', database_name='test-db', table_name=None
)
# Verify that the correct error message is raised
assert 'table_name and table_input are required' in str(excinfo.value)
# Call the method without table_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_tables(
mock_ctx,
operation='update-table',
database_name='test-db',
table_name='test-table',
table_input=None,
)
# Verify that the correct error message is raised
assert 'table_name and table_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_create_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that create connection operation with missing required parameters raises a ValueError."""
# Call the method without connection_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx, operation='create-connection', connection_name=None
)
# Verify that the correct error message is raised
assert 'connection_name and connection_input are required' in str(excinfo.value)
# Call the method without connection_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='create-connection',
connection_name='test-connection',
connection_input=None,
)
# Verify that the correct error message is raised
assert 'connection_name and connection_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_delete_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that delete connection operation with missing required parameters raises a ValueError."""
# Call the method without connection_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx, operation='delete-connection', connection_name=None
)
# Verify that the correct error message is raised
assert 'connection_name is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_get_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that get connection operation with missing required parameters raises a ValueError."""
# Call the method without connection_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx, operation='get-connection', connection_name=None
)
# Verify that the correct error message is raised
assert 'connection_name is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_update_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that update connection operation with missing required parameters raises a ValueError."""
# Call the method without connection_name
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx, operation='update-connection', connection_name=None
)
# Verify that the correct error message is raised
assert 'connection_name and connection_input are required' in str(excinfo.value)
# Call the method without connection_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='update-connection',
connection_name='test-connection',
connection_input=None,
)
# Verify that the correct error message is raised
assert 'connection_name and connection_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_create_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that create partition operation with missing required parameters raises a ValueError."""
# Call the method without partition_values
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='create-partition',
database_name='test-db',
table_name='test-table',
partition_values=None,
)
# Verify that the correct error message is raised
assert 'partition_values and partition_input are required' in str(excinfo.value)
# Call the method without partition_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='create-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
partition_input=None,
)
# Verify that the correct error message is raised
assert 'partition_values and partition_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_delete_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that delete partition operation with missing required parameters raises a ValueError."""
# Call the method without partition_values
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='delete-partition',
database_name='test-db',
table_name='test-table',
partition_values=None,
)
# Verify that the correct error message is raised
assert 'partition_values is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_get_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that get partition operation with missing required parameters raises a ValueError."""
# Call the method without partition_values
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='get-partition',
database_name='test-db',
table_name='test-table',
partition_values=None,
)
# Verify that the correct error message is raised
assert 'partition_values is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_update_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that update partition operation with missing required parameters raises a ValueError."""
# Call the method without partition_values
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='update-partition',
database_name='test-db',
table_name='test-table',
partition_values=None,
)
# Verify that the correct error message is raised
assert 'partition_values and partition_input are required' in str(excinfo.value)
# Call the method without partition_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='update-partition',
database_name='test-db',
table_name='test-table',
partition_values=['2023'],
partition_input=None,
)
# Verify that the correct error message is raised
assert 'partition_values and partition_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_create_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that create catalog operation with missing required parameters raises a ValueError."""
# Call the method without catalog_id
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx, operation='create-catalog', catalog_id=None
)
# Verify that the correct error message is raised
assert 'catalog_id and catalog_input are required' in str(excinfo.value)
# Call the method without catalog_input
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx, operation='create-catalog', catalog_id='test-catalog', catalog_input=None
)
# Verify that the correct error message is raised
assert 'catalog_id and catalog_input are required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_delete_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that delete catalog operation with missing required parameters raises a ValueError."""
# Call the method without catalog_id
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx, operation='delete-catalog', catalog_id=None
)
# Verify that the correct error message is raised
assert 'catalog_id is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_get_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that get catalog operation with missing required parameters raises a ValueError."""
# Call the method without catalog_id
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx, operation='get-catalog', catalog_id=None
)
# Verify that the correct error message is raised
assert 'catalog_id is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_import_missing_required_params(
self, handler_with_write_access, mock_ctx
):
"""Test that import catalog operation with missing required parameters raises a ValueError."""
# Call the method without catalog_id
with pytest.raises(ValueError) as excinfo:
await handler_with_write_access.manage_aws_glue_data_catalog(
mock_ctx, operation='import-catalog-to-glue', catalog_id=None
)
# Verify that the correct error message is raised
assert 'catalog_id is required' in str(excinfo.value)
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_partitions_list_with_all_parameters(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test listing partitions with all parameters including next_token."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.partitions = [{'Values': ['2023', '01']}, {'Values': ['2023', '02']}]
expected_response.count = 2
expected_response.next_token = 'next-token-value'
expected_response.operation = 'list-partitions'
mock_catalog_manager.list_partitions.return_value = expected_response
# Call the method with all parameters
result = await handler.manage_aws_glue_data_catalog_partitions(
mock_ctx,
operation='list-partitions',
database_name='test-db',
table_name='test-table',
max_results=10,
expression="year='2023'",
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.list_partitions.assert_called_once()
assert mock_catalog_manager.list_partitions.call_args[1]['database_name'] == 'test-db'
assert mock_catalog_manager.list_partitions.call_args[1]['table_name'] == 'test-table'
assert mock_catalog_manager.list_partitions.call_args[1]['max_results'] == 10
assert mock_catalog_manager.list_partitions.call_args[1]['expression'] == "year='2023'"
assert mock_catalog_manager.list_partitions.call_args[1]['catalog_id'] == '123456789012'
# Verify that the result is the expected response
assert result == expected_response
assert len(result.partitions) == 2
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_list_with_max_results(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test listing connections with max_results parameter."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connections = [
{'Name': 'connection1', 'ConnectionType': 'JDBC'},
{'Name': 'connection2', 'ConnectionType': 'KAFKA'},
]
expected_response.count = 2
expected_response.operation = 'list-connections'
mock_catalog_manager.list_connections.return_value = expected_response
# Call the method with max_results
result = await handler.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='list-connections',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.list_connections.assert_called_once()
# Verify that the result is the expected response
assert result == expected_response
assert len(result.connections) == 2
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_list_with_all_parameters(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test listing connections with all parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connections = [
{'Name': 'connection1', 'ConnectionType': 'JDBC'},
{'Name': 'connection2', 'ConnectionType': 'KAFKA'},
]
expected_response.count = 2
expected_response.next_token = 'next-token-value'
expected_response.operation = 'list-connections'
mock_catalog_manager.list_connections.return_value = expected_response
# Call the method with all parameters
result = await handler.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='list-connections',
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.list_connections.assert_called_once()
assert mock_catalog_manager.list_connections.call_args[1]['catalog_id'] == '123456789012'
# Verify that the result is the expected response
assert result == expected_response
assert len(result.connections) == 2
@pytest.mark.asyncio
async def test_manage_aws_glue_data_catalog_connections_get_with_all_parameters(
self, handler, mock_ctx, mock_catalog_manager
):
"""Test getting a connection with all parameters."""
# Setup the mock to return a response
expected_response = MagicMock()
expected_response.isError = False
expected_response.content = []
expected_response.connection_name = 'test-connection'
expected_response.connection_type = 'JDBC'
expected_response.connection_properties = {
'JDBC_CONNECTION_URL': 'jdbc:mysql://test-host:3306/test-db'
}
expected_response.operation = 'get'
mock_catalog_manager.get_connection.return_value = expected_response
# Call the method with all parameters
result = await handler.manage_aws_glue_data_catalog_connections(
mock_ctx,
operation='get-connection',
connection_name='test-connection',
catalog_id='123456789012',
)
# Verify that the method was called with the correct parameters
mock_catalog_manager.get_connection.assert_called_once()
assert (
mock_catalog_manager.get_connection.call_args[1]['connection_name']
== 'test-connection'
)
assert mock_catalog_manager.get_connection.call_args[1]['catalog_id'] == '123456789012'
# Verify that the result is the expected response
assert result == expected_response
```