awslabs.openapi-mcp-server 0.2.10__tar.gz → 0.2.12__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/Dockerfile +19 -22
  2. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/PKG-INFO +1 -1
  3. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/__init__.py +2 -2
  4. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/server.py +43 -23
  5. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/docker-healthcheck.sh +1 -1
  6. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/pyproject.toml +1 -1
  7. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_server_exception_handling.py +5 -45
  8. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_server_extended.py +0 -5
  9. awslabs_openapi_mcp_server-0.2.12/uv-requirements.txt +23 -0
  10. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/uv.lock +14 -13
  11. awslabs_openapi_mcp_server-0.2.10/uv-requirements.txt +0 -27
  12. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/.coveragerc +0 -0
  13. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/.dockerignore +0 -0
  14. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/.gitignore +0 -0
  15. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/.python-version +0 -0
  16. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/AUTHENTICATION.md +0 -0
  17. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/AWS_BEST_PRACTICES.md +0 -0
  18. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/CHANGELOG.md +0 -0
  19. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/DEPLOYMENT.md +0 -0
  20. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/LICENSE +0 -0
  21. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/NOTICE +0 -0
  22. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/OBSERVABILITY.md +0 -0
  23. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/README.md +0 -0
  24. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/__init__.py +0 -0
  25. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/api/__init__.py +0 -0
  26. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/api/config.py +0 -0
  27. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/__init__.py +0 -0
  28. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/api_key_auth.py +0 -0
  29. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/auth_cache.py +0 -0
  30. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/auth_errors.py +0 -0
  31. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/auth_factory.py +0 -0
  32. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/auth_protocol.py +0 -0
  33. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/auth_provider.py +0 -0
  34. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/base_auth.py +0 -0
  35. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/basic_auth.py +0 -0
  36. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/bearer_auth.py +0 -0
  37. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/cognito_auth.py +0 -0
  38. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/auth/register.py +0 -0
  39. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/patch/__init__.py +0 -0
  40. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/prompts/__init__.py +0 -0
  41. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/prompts/generators/__init__.py +0 -0
  42. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/prompts/generators/operation_prompts.py +0 -0
  43. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/prompts/generators/workflow_prompts.py +0 -0
  44. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/prompts/models.py +0 -0
  45. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/prompts/prompt_manager.py +0 -0
  46. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/utils/__init__.py +0 -0
  47. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/utils/cache_provider.py +0 -0
  48. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/utils/config.py +0 -0
  49. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/utils/error_handler.py +0 -0
  50. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/utils/http_client.py +0 -0
  51. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/utils/metrics_provider.py +0 -0
  52. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/utils/openapi.py +0 -0
  53. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/awslabs/openapi_mcp_server/utils/openapi_validator.py +0 -0
  54. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/pyrightconfig.json +0 -0
  55. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/README.md +0 -0
  56. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/api/test_config.py +0 -0
  57. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_api_key_auth.py +0 -0
  58. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_cache.py +0 -0
  59. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_errors.py +0 -0
  60. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_factory.py +0 -0
  61. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_factory_caching.py +0 -0
  62. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_factory_coverage.py +0 -0
  63. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_protocol.py +0 -0
  64. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_protocol_additional.py +0 -0
  65. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_protocol_boost.py +0 -0
  66. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_protocol_coverage.py +0 -0
  67. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_protocol_extended.py +0 -0
  68. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_protocol_improved.py +0 -0
  69. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_auth_provider_additional.py +0 -0
  70. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_base_auth.py +0 -0
  71. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_base_auth_coverage.py +0 -0
  72. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_basic_auth.py +0 -0
  73. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_bearer_auth.py +0 -0
  74. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_cognito_auth.py +0 -0
  75. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_cognito_auth_additional_coverage.py +0 -0
  76. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_cognito_auth_boost_coverage.py +0 -0
  77. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_cognito_auth_client_credentials.py +0 -0
  78. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_cognito_auth_coverage_boost.py +0 -0
  79. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_cognito_auth_exceptions.py +0 -0
  80. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_register.py +0 -0
  81. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/auth/test_register_coverage.py +0 -0
  82. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/prompts/standalone/test_operation_prompt.py +0 -0
  83. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/prompts/standalone/test_prompt_arguments.py +0 -0
  84. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/prompts/standalone/test_secure_operation_prompt.py +0 -0
  85. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/prompts/test_mcp_prompt_manager.py +0 -0
  86. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/prompts/test_mcp_prompt_manager_integration.py +0 -0
  87. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/prompts/test_models_dict_method.py +0 -0
  88. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/prompts/test_operation_prompts_extended.py +0 -0
  89. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/prompts/test_prompt_manager_additional.py +0 -0
  90. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/prompts/test_prompt_manager_comprehensive.py +0 -0
  91. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/prompts/test_prompt_manager_coverage.py +0 -0
  92. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/prompts/test_prompt_registration.py +0 -0
  93. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_api_name.py +0 -0
  94. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_cache_coverage_89.py +0 -0
  95. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_client.py +0 -0
  96. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_coverage_boost.py +0 -0
  97. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_init.py +0 -0
  98. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_main.py +0 -0
  99. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_main_extended.py +0 -0
  100. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_openapi_coverage_89.py +0 -0
  101. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_server.py +0 -0
  102. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_server_auth_errors.py +0 -0
  103. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_server_coverage_boost.py +0 -0
  104. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_server_coverage_boost_2.py +0 -0
  105. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_server_httpx_version.py +0 -0
  106. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_server_part1.py +0 -0
  107. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_server_route_logging.py +0 -0
  108. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/test_server_signal_handlers.py +0 -0
  109. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_cache_provider.py +0 -0
  110. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_error_handler.py +0 -0
  111. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_error_handler_boost.py +0 -0
  112. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_error_handler_extended.py +0 -0
  113. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_error_handler_fix.py +0 -0
  114. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_http_client.py +0 -0
  115. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_http_client_comprehensive.py +0 -0
  116. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_http_client_extended.py +0 -0
  117. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_http_client_extended2.py +0 -0
  118. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_http_client_import_error.py +0 -0
  119. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_metrics_provider.py +0 -0
  120. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_metrics_provider_decorators.py +0 -0
  121. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_metrics_provider_extended2.py +0 -0
  122. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_metrics_provider_prometheus.py +0 -0
  123. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_openapi.py +0 -0
  124. {awslabs_openapi_mcp_server-0.2.10 → awslabs_openapi_mcp_server-0.2.12}/tests/utils/test_openapi_validator.py +0 -0
@@ -13,7 +13,11 @@
13
13
  # limitations under the License.
14
14
 
15
15
  # dependabot should continue to update this to the latest hash.
16
- FROM public.ecr.aws/docker/library/python:3.13-alpine@sha256:e7e041128ffc3e3600509f508e44d34ab08ff432bdb62ec508d01dfc5ca459f7 AS uv
16
+ FROM public.ecr.aws/amazonlinux/amazonlinux@sha256:e27a70c006c68f0d194cc9b9624714d6ed8d979a94f60f7d31392f4c8294155b AS uv
17
+
18
+ # Install build dependencies needed for compiling packages
19
+ RUN dnf install -y shadow-utils python3 python3-devel gcc && \
20
+ dnf clean all
17
21
 
18
22
  # Install the project into `/app`
19
23
  WORKDIR /app
@@ -25,7 +29,7 @@ ENV UV_COMPILE_BYTECODE=1
25
29
  ENV UV_LINK_MODE=copy
26
30
 
27
31
  # Prefer the system python
28
- ENV UV_PYTHON_PREFERENCE=only-system
32
+ ENV UV_PYTHON_PREFERENCE=only-managed
29
33
 
30
34
  # Run without updating the uv.lock file like running with `--frozen`
31
35
  ENV UV_FROZEN=true
@@ -37,19 +41,10 @@ COPY pyproject.toml uv.lock uv-requirements.txt ./
37
41
  ENV PIP_NO_CACHE_DIR=1 \
38
42
  PIP_DISABLE_PIP_VERSION_CHECK=1
39
43
 
40
- # Install system dependencies and Python package manager
41
- RUN apk update && \
42
- apk add --no-cache --virtual .build-deps \
43
- build-base \
44
- gcc \
45
- musl-dev \
46
- libffi-dev \
47
- openssl-dev \
48
- cargo
49
-
50
44
  # Install the project's dependencies using the lockfile and settings
51
45
  RUN --mount=type=cache,target=/root/.cache/uv \
52
- pip install --require-hashes --requirement uv-requirements.txt --no-cache-dir && \
46
+ python3 -m ensurepip && \
47
+ python3 -m pip install --require-hashes --requirement uv-requirements.txt --no-cache-dir && \
53
48
  uv sync --python 3.13 --frozen --no-install-project --no-dev --no-editable
54
49
 
55
50
  # Then, add the rest of the project source code and install it
@@ -61,20 +56,22 @@ RUN --mount=type=cache,target=/root/.cache/uv \
61
56
  # Make the directory just in case it doesn't exist
62
57
  RUN mkdir -p /root/.local
63
58
 
64
- FROM public.ecr.aws/docker/library/python:3.13-alpine@sha256:e7e041128ffc3e3600509f508e44d34ab08ff432bdb62ec508d01dfc5ca459f7
59
+ FROM public.ecr.aws/amazonlinux/amazonlinux@sha256:e27a70c006c68f0d194cc9b9624714d6ed8d979a94f60f7d31392f4c8294155b
65
60
 
66
61
  # Place executables in the environment at the front of the path and include other binaries
67
- ENV PATH="/app/.venv/bin:$PATH" \
62
+ ENV PATH="/app/.venv/bin:$PATH:/usr/sbin" \
68
63
  PYTHONUNBUFFERED=1
69
64
 
70
- # Install runtime dependencies and create application user
71
- RUN apk update && \
72
- apk add --no-cache ca-certificates && \
73
- update-ca-certificates && \
74
- addgroup -S app && \
75
- adduser -S app -G app -h /app
65
+ # Install other tools as needed for the MCP server
66
+ # Add non-root user and ability to change directory into /root
67
+ RUN dnf install -y shadow-utils procps && \
68
+ dnf clean all && \
69
+ groupadd --force --system app && \
70
+ useradd app -g app -d /app && \
71
+ chmod o+x /root
76
72
 
77
- # Copy application artifacts from build stage
73
+ # Get the project from the uv layer
74
+ COPY --from=uv --chown=app:app /root/.local /root/.local
78
75
  COPY --from=uv --chown=app:app /app/.venv /app/.venv
79
76
 
80
77
  # Get healthcheck script
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: awslabs.openapi-mcp-server
3
- Version: 0.2.10
3
+ Version: 0.2.12
4
4
  Summary: An AWS Labs Model Context Protocol (MCP) server for OpenAPI
5
5
  Project-URL: Homepage, https://awslabs.github.io/mcp/
6
6
  Project-URL: Documentation, https://awslabs.github.io/mcp/servers/openapi-mcp-server/
@@ -15,7 +15,7 @@
15
15
  OpenAPI MCP Server - A server that dynamically creates MCP tools and resources from OpenAPI specifications.
16
16
  """
17
17
 
18
- __version__ = '0.2.10'
18
+ __version__ = '0.2.12'
19
19
 
20
20
 
21
21
  import inspect
@@ -34,7 +34,7 @@ def get_format():
34
34
  # Set up enhanced logging format to include function name, line number, and logger name
35
35
  # Fixed the whitespace issue after log level by removing padding
36
36
  logger.add(
37
- sys.stdout,
37
+ sys.stderr,
38
38
  format=get_format(),
39
39
  level='INFO',
40
40
  )
@@ -33,7 +33,7 @@ from fastmcp.server.openapi import FastMCPOpenAPI, MCPType, RouteMap
33
33
  from typing import Any, Dict
34
34
 
35
35
 
36
- def create_mcp_server(config: Config) -> FastMCP:
36
+ async def create_mcp_server_async(config: Config) -> FastMCP:
37
37
  """Create and configure the FastMCP server.
38
38
 
39
39
  Args:
@@ -221,7 +221,7 @@ def create_mcp_server(config: Config) -> FastMCP:
221
221
  prompt_manager = MCPPromptManager()
222
222
 
223
223
  # Generate prompts
224
- asyncio.run(prompt_manager.generate_prompts(server, config.api_name, openapi_spec))
224
+ await prompt_manager.generate_prompts(server, config.api_name, openapi_spec)
225
225
 
226
226
  # Register resource handler
227
227
  prompt_manager.register_api_resource_handler(server, config.api_name, client)
@@ -292,7 +292,7 @@ def create_mcp_server(config: Config) -> FastMCP:
292
292
  if hasattr(server, 'list_tools'):
293
293
  try:
294
294
  # Use asyncio to run the async method in a synchronous context
295
- tools = asyncio.run(server.list_tools()) # type: ignore
295
+ tools = await server.list_tools() # type: ignore
296
296
  tool_count = len(tools)
297
297
  tool_names = [tool.get('name') for tool in tools]
298
298
 
@@ -344,6 +344,45 @@ def create_mcp_server(config: Config) -> FastMCP:
344
344
  return server
345
345
 
346
346
 
347
+ def create_mcp_server(config: Config) -> FastMCP:
348
+ """Create and configure the FastMCP server (synchronous wrapper).
349
+
350
+ This is a synchronous convenience wrapper that calls
351
+ :func:`create_mcp_server_async` using ``asyncio.run``.
352
+ For asynchronous contexts, use :func:`create_mcp_server_async`
353
+ directly instead of this function.
354
+
355
+ Args:
356
+ config: Server configuration.
357
+
358
+ Returns:
359
+ FastMCP: The configured FastMCP server.
360
+
361
+ """
362
+ return asyncio.run(create_mcp_server_async(config))
363
+
364
+
365
+ async def get_all_counts(server: FastMCP) -> tuple[int, int, int, int]:
366
+ """Get counts of prompts, tools, resources, and resource templates."""
367
+ prompts = await server.get_prompts()
368
+ tools = await server.get_tools()
369
+ resources = await server.get_resources()
370
+
371
+ # Get resource templates if available
372
+ resource_templates = []
373
+ if hasattr(server, 'get_resource_templates'):
374
+ try:
375
+ resource_templates = await server.get_resource_templates()
376
+ except AttributeError as e:
377
+ # This is expected if the method exists but is not implemented
378
+ logger.debug(f'get_resource_templates exists but not implemented: {e}')
379
+ except Exception as e:
380
+ # Log other unexpected errors
381
+ logger.warning(f'Error retrieving resource templates: {e}')
382
+
383
+ return len(prompts), len(tools), len(resources), len(resource_templates)
384
+
385
+
347
386
  def setup_signal_handlers():
348
387
  """Set up signal handlers for graceful shutdown."""
349
388
  # Store original SIGINT handler
@@ -449,7 +488,7 @@ def main():
449
488
 
450
489
  # Set up logging with loguru at specified level
451
490
  logger.remove()
452
- logger.add(lambda msg: print(msg, end=''), level=args.log_level)
491
+ logger.add(lambda msg: print(msg, end='', file=sys.stderr), level=args.log_level)
453
492
  logger.info(f'Starting server with logging level: {args.log_level}')
454
493
 
455
494
  # Load configuration
@@ -466,25 +505,6 @@ def main():
466
505
 
467
506
  try:
468
507
  # Get counts of prompts, tools, resources, and resource templates
469
- async def get_all_counts(server):
470
- prompts = await server.get_prompts()
471
- tools = await server.get_tools()
472
- resources = await server.get_resources()
473
-
474
- # Get resource templates if available
475
- resource_templates = []
476
- if hasattr(server, 'get_resource_templates'):
477
- try:
478
- resource_templates = await server.get_resource_templates()
479
- except AttributeError as e:
480
- # This is expected if the method exists but is not implemented
481
- logger.debug(f'get_resource_templates exists but not implemented: {e}')
482
- except Exception as e:
483
- # Log other unexpected errors
484
- logger.warning(f'Error retrieving resource templates: {e}')
485
-
486
- return len(prompts), len(tools), len(resources), len(resource_templates)
487
-
488
508
  prompt_count, tool_count, resource_count, resource_template_count = asyncio.run(
489
509
  get_all_counts(mcp_server)
490
510
  )
@@ -16,7 +16,7 @@
16
16
  SERVER="openapi-mcp-server"
17
17
 
18
18
  # Check if the server process is running
19
- if pgrep -P 0 -a -l -x -f "/app/.venv/bin/python3 /app/.venv/bin/awslabs.$SERVER" > /dev/null; then
19
+ if pgrep -P 0 -a -l -x -f "/app/.venv/bin/python3? /app/.venv/bin/awslabs.$SERVER" > /dev/null; then
20
20
  echo -n "$SERVER is running";
21
21
  exit 0;
22
22
  fi;
@@ -7,7 +7,7 @@ allow-direct-references = true
7
7
 
8
8
  [project]
9
9
  name = "awslabs.openapi-mcp-server"
10
- version = "0.2.10"
10
+ version = "0.2.12"
11
11
  description = "An AWS Labs Model Context Protocol (MCP) server for OpenAPI"
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.10"
@@ -14,6 +14,7 @@
14
14
  """Test exception handling in server.py get_all_counts function."""
15
15
 
16
16
  import pytest
17
+ from awslabs.openapi_mcp_server.server import get_all_counts
17
18
  from unittest.mock import AsyncMock, MagicMock, patch
18
19
 
19
20
 
@@ -31,32 +32,10 @@ async def test_get_all_counts_attribute_error_handling():
31
32
  side_effect=AttributeError('Method not implemented')
32
33
  )
33
34
 
34
- # Mock the main function's get_all_counts inner function
35
+ # Mock the main function's get_all_counts function
35
36
  with patch('awslabs.openapi_mcp_server.server.logger') as mock_logger:
36
- # We need to access the inner function, so let's create a minimal test
37
- # that exercises the exception handling path
38
-
39
- # Create the get_all_counts function similar to what's in main()
40
- async def get_all_counts():
41
- prompts = await mock_server.get_prompts()
42
- tools = await mock_server.get_tools()
43
- resources = await mock_server.get_resources()
44
- resource_templates = []
45
-
46
- if hasattr(mock_server, 'get_resource_templates'):
47
- try:
48
- resource_templates = await mock_server.get_resource_templates()
49
- except AttributeError as e:
50
- # This is expected if the method exists but is not implemented
51
- mock_logger.debug(f'get_resource_templates exists but not implemented: {e}')
52
- except Exception as e:
53
- # Log other unexpected errors
54
- mock_logger.warning(f'Error retrieving resource templates: {e}')
55
-
56
- return len(prompts), len(tools), len(resources), len(resource_templates)
57
-
58
37
  # Execute the function
59
- result = await get_all_counts()
38
+ result = await get_all_counts(mock_server)
60
39
 
61
40
  # Verify the result
62
41
  assert result == (0, 0, 0, 0)
@@ -80,29 +59,10 @@ async def test_get_all_counts_general_exception_handling():
80
59
  # Mock hasattr to return True, but get_resource_templates raises a general Exception
81
60
  mock_server.get_resource_templates = AsyncMock(side_effect=RuntimeError('Unexpected error'))
82
61
 
83
- # Mock the main function's get_all_counts inner function
62
+ # Mock the main function's get_all_counts function
84
63
  with patch('awslabs.openapi_mcp_server.server.logger') as mock_logger:
85
- # Create the get_all_counts function similar to what's in main()
86
- async def get_all_counts():
87
- prompts = await mock_server.get_prompts()
88
- tools = await mock_server.get_tools()
89
- resources = await mock_server.get_resources()
90
- resource_templates = []
91
-
92
- if hasattr(mock_server, 'get_resource_templates'):
93
- try:
94
- resource_templates = await mock_server.get_resource_templates()
95
- except AttributeError as e:
96
- # This is expected if the method exists but is not implemented
97
- mock_logger.debug(f'get_resource_templates exists but not implemented: {e}')
98
- except Exception as e:
99
- # Log other unexpected errors
100
- mock_logger.warning(f'Error retrieving resource templates: {e}')
101
-
102
- return len(prompts), len(tools), len(resources), len(resource_templates)
103
-
104
64
  # Execute the function
105
- result = await get_all_counts()
65
+ result = await get_all_counts(mock_server)
106
66
 
107
67
  # Verify the result
108
68
  assert result == (0, 0, 0, 0)
@@ -110,9 +110,7 @@ def test_create_mcp_server_with_query_params_routes(
110
110
  @patch('awslabs.openapi_mcp_server.server.load_openapi_spec')
111
111
  @patch('awslabs.openapi_mcp_server.server.validate_openapi_spec', return_value=True)
112
112
  @patch('awslabs.openapi_mcp_server.server.HttpClientFactory.create_client')
113
- @patch('awslabs.openapi_mcp_server.server.asyncio.run')
114
113
  def test_create_mcp_server_with_prompt_generation(
115
- mock_asyncio_run,
116
114
  mock_create_client,
117
115
  mock_validate,
118
116
  mock_load_spec,
@@ -145,9 +143,6 @@ def test_create_mcp_server_with_prompt_generation(
145
143
  # Verify the result
146
144
  assert result == mock_server
147
145
 
148
- # Verify that asyncio.run was called
149
- mock_asyncio_run.assert_called()
150
-
151
146
 
152
147
  @patch('awslabs.openapi_mcp_server.server.signal')
153
148
  @patch('awslabs.openapi_mcp_server.server.logger')
@@ -0,0 +1,23 @@
1
+ # This file was autogenerated by uv via the following command:
2
+ # uv pip compile --generate-hashes --output-file=uv-requirements.txt --strip-extras uv-requirements.in
3
+ uv==0.9.24 \
4
+ --hash=sha256:009cc82cdfc48add6ec13a0c4ffbb788ae2cab53573b4218069ca626721a404b \
5
+ --hash=sha256:15d3955bfb03a7b78aaf5afb639cedefdf0fc35ff844c92e3fe6e8700b94b84f \
6
+ --hash=sha256:1914d33e526167dc202ec4a59119c68467b31f7c71dcf8b1077571d091ca3e7c \
7
+ --hash=sha256:207c8a2d4c4d55589feb63b4be74f6ff6ab92fa81b14a6515007ccec5a868ae0 \
8
+ --hash=sha256:38c59e18fe5fa42f7baeb4f08c94914cee6d87ff8faa6fc95c994dbc0de26c90 \
9
+ --hash=sha256:3b610d89d6025000d08cd9bd458c6e264003a0ecfdaa8e4eba28938130cd1837 \
10
+ --hash=sha256:44c0b8a78724e4cfa8e9c0266023c70fc792d0b39a5da17f5f847af2b530796b \
11
+ --hash=sha256:488a07e59fb417bf86de5630197223b7a0223229e626afc124c26827db78cff8 \
12
+ --hash=sha256:63a0a46693098cf8446e41bd5d9ce7d3bc9b775a63fe0c8405ab6ee328424d46 \
13
+ --hash=sha256:6720c9939cca7daff3cccc35dd896bbe139d7d463c62cba8dbbc474ff8eb93d1 \
14
+ --hash=sha256:68a3186074c03876ee06b68730d5ff69a430296760d917ebbbb8e3fb54fb4091 \
15
+ --hash=sha256:69531d9a8772afb2dff68fef2469f666e4f8a0132b2109e36541c423415835da \
16
+ --hash=sha256:75a000f529ec92235b10fb5e16ca41f23f46c643308fd6c5b0d7b73ca056c5b9 \
17
+ --hash=sha256:841ede01d6dcf1676a21dce05f3647ba171c1d92768a03e8b8b6b7354b34a6d2 \
18
+ --hash=sha256:8cd626306b415491f839b1a9100da6795c82c44d4cf278dd7ace7a774af89df4 \
19
+ --hash=sha256:8d3c0fec7aa17f936a5b258816e856647b21f978a81bcfb2dc8caf2892a4965e \
20
+ --hash=sha256:aafe7dd9b633672054cf27f1a8e4127506324631f1af5edd051728f4f8085351 \
21
+ --hash=sha256:d59d31c25fc530c68db9164174efac511a25fc882cec49cd48f75a18e7ebd6d5 \
22
+ --hash=sha256:d7d1333d9c21088c89cb284ef29fdf48dc2015fe993174a823a3e7c991db90f9
23
+ # via -r uv-requirements.in (contents of `uv==0.9.24`)
@@ -55,19 +55,19 @@ wheels = [
55
55
 
56
56
  [[package]]
57
57
  name = "authlib"
58
- version = "1.6.5"
58
+ version = "1.6.6"
59
59
  source = { registry = "https://pypi.org/simple" }
60
60
  dependencies = [
61
61
  { name = "cryptography" },
62
62
  ]
63
- sdist = { url = "https://files.pythonhosted.org/packages/cd/3f/1d3bbd0bf23bdd99276d4def22f29c27a914067b4cf66f753ff9b8bbd0f3/authlib-1.6.5.tar.gz", hash = "sha256:6aaf9c79b7cc96c900f0b284061691c5d4e61221640a948fe690b556a6d6d10b", size = 164553, upload-time = "2025-10-02T13:36:09.489Z" }
63
+ sdist = { url = "https://files.pythonhosted.org/packages/bb/9b/b1661026ff24bc641b76b78c5222d614776b0c085bcfdac9bd15a1cb4b35/authlib-1.6.6.tar.gz", hash = "sha256:45770e8e056d0f283451d9996fbb59b70d45722b45d854d58f32878d0a40c38e", size = 164894, upload-time = "2025-12-12T08:01:41.464Z" }
64
64
  wheels = [
65
- { url = "https://files.pythonhosted.org/packages/f8/aa/5082412d1ee302e9e7d80b6949bc4d2a8fa1149aaab610c5fc24709605d6/authlib-1.6.5-py2.py3-none-any.whl", hash = "sha256:3e0e0507807f842b02175507bdee8957a1d5707fd4afb17c32fb43fee90b6e3a", size = 243608, upload-time = "2025-10-02T13:36:07.637Z" },
65
+ { url = "https://files.pythonhosted.org/packages/54/51/321e821856452f7386c4e9df866f196720b1ad0c5ea1623ea7399969ae3b/authlib-1.6.6-py2.py3-none-any.whl", hash = "sha256:7d9e9bc535c13974313a87f53e8430eb6ea3d1cf6ae4f6efcd793f2e949143fd", size = 244005, upload-time = "2025-12-12T08:01:40.209Z" },
66
66
  ]
67
67
 
68
68
  [[package]]
69
69
  name = "awslabs-openapi-mcp-server"
70
- version = "0.2.10"
70
+ version = "0.2.12"
71
71
  source = { editable = "." }
72
72
  dependencies = [
73
73
  { name = "bcrypt" },
@@ -815,11 +815,11 @@ wheels = [
815
815
 
816
816
  [[package]]
817
817
  name = "filelock"
818
- version = "3.20.1"
818
+ version = "3.20.3"
819
819
  source = { registry = "https://pypi.org/simple" }
820
- sdist = { url = "https://files.pythonhosted.org/packages/a7/23/ce7a1126827cedeb958fc043d61745754464eb56c5937c35bbf2b8e26f34/filelock-3.20.1.tar.gz", hash = "sha256:b8360948b351b80f420878d8516519a2204b07aefcdcfd24912a5d33127f188c", size = 19476, upload-time = "2025-12-15T23:54:28.027Z" }
820
+ sdist = { url = "https://files.pythonhosted.org/packages/1d/65/ce7f1b70157833bf3cb851b556a37d4547ceafc158aa9b34b36782f23696/filelock-3.20.3.tar.gz", hash = "sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1", size = 19485, upload-time = "2026-01-09T17:55:05.421Z" }
821
821
  wheels = [
822
- { url = "https://files.pythonhosted.org/packages/e3/7f/a1a97644e39e7316d850784c642093c99df1290a460df4ede27659056834/filelock-3.20.1-py3-none-any.whl", hash = "sha256:15d9e9a67306188a44baa72f569d2bfd803076269365fdea0934385da4dc361a", size = 16666, upload-time = "2025-12-15T23:54:26.874Z" },
822
+ { url = "https://files.pythonhosted.org/packages/b5/36/7fb70f04bf00bc646cd5bb45aa9eddb15e19437a28b8fb2b4a5249fac770/filelock-3.20.3-py3-none-any.whl", hash = "sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1", size = 16701, upload-time = "2026-01-09T17:55:04.334Z" },
823
823
  ]
824
824
 
825
825
  [[package]]
@@ -921,14 +921,14 @@ wheels = [
921
921
 
922
922
  [[package]]
923
923
  name = "jaraco-context"
924
- version = "6.0.1"
924
+ version = "6.1.0"
925
925
  source = { registry = "https://pypi.org/simple" }
926
926
  dependencies = [
927
927
  { name = "backports-tarfile", marker = "python_full_version < '3.12'" },
928
928
  ]
929
- sdist = { url = "https://files.pythonhosted.org/packages/df/ad/f3777b81bf0b6e7bc7514a1656d3e637b2e8e15fab2ce3235730b3e7a4e6/jaraco_context-6.0.1.tar.gz", hash = "sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3", size = 13912, upload-time = "2024-08-20T03:39:27.358Z" }
929
+ sdist = { url = "https://files.pythonhosted.org/packages/cb/9c/a788f5bb29c61e456b8ee52ce76dbdd32fd72cd73dd67bc95f42c7a8d13c/jaraco_context-6.1.0.tar.gz", hash = "sha256:129a341b0a85a7db7879e22acd66902fda67882db771754574338898b2d5d86f", size = 15850, upload-time = "2026-01-13T02:53:53.847Z" }
930
930
  wheels = [
931
- { url = "https://files.pythonhosted.org/packages/ff/db/0c52c4cf5e4bd9f5d7135ec7669a3a767af21b3a308e1ed3674881e52b62/jaraco.context-6.0.1-py3-none-any.whl", hash = "sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4", size = 6825, upload-time = "2024-08-20T03:39:25.966Z" },
931
+ { url = "https://files.pythonhosted.org/packages/8d/48/aa685dbf1024c7bd82bede569e3a85f82c32fd3d79ba5fea578f0159571a/jaraco_context-6.1.0-py3-none-any.whl", hash = "sha256:a43b5ed85815223d0d3cfdb6d7ca0d2bc8946f28f30b6f3216bda070f68badda", size = 7065, upload-time = "2026-01-13T02:53:53.031Z" },
932
932
  ]
933
933
 
934
934
  [[package]]
@@ -2514,16 +2514,17 @@ wheels = [
2514
2514
 
2515
2515
  [[package]]
2516
2516
  name = "virtualenv"
2517
- version = "20.31.2"
2517
+ version = "20.36.1"
2518
2518
  source = { registry = "https://pypi.org/simple" }
2519
2519
  dependencies = [
2520
2520
  { name = "distlib" },
2521
2521
  { name = "filelock" },
2522
2522
  { name = "platformdirs" },
2523
+ { name = "typing-extensions", marker = "python_full_version < '3.11'" },
2523
2524
  ]
2524
- sdist = { url = "https://files.pythonhosted.org/packages/56/2c/444f465fb2c65f40c3a104fd0c495184c4f2336d65baf398e3c75d72ea94/virtualenv-20.31.2.tar.gz", hash = "sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af", size = 6076316, upload-time = "2025-05-08T17:58:23.811Z" }
2525
+ sdist = { url = "https://files.pythonhosted.org/packages/aa/a3/4d310fa5f00863544e1d0f4de93bddec248499ccf97d4791bc3122c9d4f3/virtualenv-20.36.1.tar.gz", hash = "sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba", size = 6032239, upload-time = "2026-01-09T18:21:01.296Z" }
2525
2526
  wheels = [
2526
- { url = "https://files.pythonhosted.org/packages/f3/40/b1c265d4b2b62b58576588510fc4d1fe60a86319c8de99fd8e9fec617d2c/virtualenv-20.31.2-py3-none-any.whl", hash = "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11", size = 6057982, upload-time = "2025-05-08T17:58:21.15Z" },
2527
+ { url = "https://files.pythonhosted.org/packages/6a/2a/dc2228b2888f51192c7dc766106cd475f1b768c10caaf9727659726f7391/virtualenv-20.36.1-py3-none-any.whl", hash = "sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f", size = 6008258, upload-time = "2026-01-09T18:20:59.425Z" },
2527
2528
  ]
2528
2529
 
2529
2530
  [[package]]
@@ -1,27 +0,0 @@
1
- #
2
- # This file is autogenerated by pip-compile with Python 3.12
3
- # by the following command:
4
- #
5
- # pip-compile --generate-hashes --output-file=uv-requirements.txt --strip-extras uv-requirements.in
6
- #
7
- uv==0.9.6 \
8
- --hash=sha256:0169a85d3ba5ef1c37089d64ff26de573439ca84ecf549276a2eee42d7f833f2 \
9
- --hash=sha256:0fde18c22376c8b02954c7db3847bc75ac42619932c44b43f49d056e5cfb05f9 \
10
- --hash=sha256:166175ba952d2ad727e1dbd57d7cfc1782dfe7b8d79972174a46a7aa33ddceec \
11
- --hash=sha256:3c2c2b2b093330e603d838fec26941ab6f62e8d62a012f9fa0d5ed88da39d907 \
12
- --hash=sha256:538716ec97f8d899baa7e1c427f4411525459c0ef72ea9b3625ce9610c9976e6 \
13
- --hash=sha256:547fd27ab5da7cd1a833288a36858852451d416a056825f162ecf2af5be6f8b8 \
14
- --hash=sha256:62e3f057a9ae5e5003a7cd56b617e940f519f6dabcbb22d36cdd0149df25d409 \
15
- --hash=sha256:6403176b55388cf94fb8737e73b26ee2a7b1805a9139da5afa951210986d4fcd \
16
- --hash=sha256:7e89c964f614fa3f0481060cac709d6da50feac553e1e11227d6c4c81c87af7c \
17
- --hash=sha256:86e05782f9b75d39ab1c0af98bf11e87e646a36a61d425021d5b284073e56315 \
18
- --hash=sha256:90122a76e6441b8c580fc9faf06bd8c4dbe276cb1c185ad91eceb2afa78e492a \
19
- --hash=sha256:95a62c1f668272555ad0c446bf44a9924dee06054b831d04c162e0bad736dc28 \
20
- --hash=sha256:a7c6067919d87208c4a6092033c3bc9799cb8be1c8bc6ef419a1f6d42a755329 \
21
- --hash=sha256:b2f934737c93f88c906b6a47bcc083170210fe5d66565e80a7c139599e5cbf2f \
22
- --hash=sha256:b31377ebf2d0499afc5abe3fe1abded5ca843f3a1161b432fe26eb0ce15bab8e \
23
- --hash=sha256:d1072db92cc9525febdf9d113c23916dfc20ca03e21218cc7beefe7185a90631 \
24
- --hash=sha256:e700b2098f9d365061c572d0729b4e8bc71c6468d83dfaae2537cd66e3cb1b98 \
25
- --hash=sha256:ea67369918af24ea7e01991dfc8b8988d1b0b7c49cb39d9e5bc0c409930a0a3f \
26
- --hash=sha256:f0ba311b3ca49d246f36d444d3ee81571619ef95e5f509eb694a81defcbed262
27
- # via -r uv-requirements.in (contents of `uv==0.9.6`)