Fix usage of a single object instances for multiple concurrent requests (#6746)

This commit is contained in:
Daniel Fangl 2023-08-31 18:32:02 +02:00 committed by GitHub
parent 2ddcb8e705
commit de44a85ed2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 738 additions and 314 deletions

View File

@ -6,17 +6,18 @@ url_bases = [
] ]
response = PrometheusServiceResponse()
url_paths = { url_paths = {
"{0}/workspaces$": response.dispatch, "{0}/workspaces$": PrometheusServiceResponse.dispatch,
"{0}/workspaces/(?P<workspace_id>[^/]+)$": response.dispatch, "{0}/workspaces/(?P<workspace_id>[^/]+)$": PrometheusServiceResponse.dispatch,
"{0}/workspaces/(?P<workspace_id>[^/]+)/alias$": response.dispatch, "{0}/workspaces/(?P<workspace_id>[^/]+)/alias$": PrometheusServiceResponse.dispatch,
"{0}/workspaces/(?P<workspace_id>[^/]+)/logging$": response.dispatch, "{0}/workspaces/(?P<workspace_id>[^/]+)/logging$": PrometheusServiceResponse.dispatch,
"{0}/workspaces/(?P<workspace_id>[^/]+)/rulegroupsnamespaces$": response.dispatch, "{0}/workspaces/(?P<workspace_id>[^/]+)/rulegroupsnamespaces$": PrometheusServiceResponse.dispatch,
"{0}/workspaces/(?P<workspace_id>[^/]+)/rulegroupsnamespaces/(?P<name>[^/]+)$": response.dispatch, "{0}/workspaces/(?P<workspace_id>[^/]+)/rulegroupsnamespaces/(?P<name>[^/]+)$": PrometheusServiceResponse.dispatch,
"{0}/tags/(?P<resource_arn>[^/]+)$": response.dispatch, "{0}/tags/(?P<resource_arn>[^/]+)$": PrometheusServiceResponse.dispatch,
"{0}/tags/(?P<arn_prefix>[^/]+)/(?P<workspace_id>[^/]+)$": response.tags, "{0}/tags/(?P<arn_prefix>[^/]+)/(?P<workspace_id>[^/]+)$": PrometheusServiceResponse.method_dispatch(
"{0}/tags/(?P<arn_prefix>[^/]+)/(?P<workspace_id>[^/]+)/(?P<ns_name>[^/]+)$": response.tags, PrometheusServiceResponse.tags # type: ignore
),
"{0}/tags/(?P<arn_prefix>[^/]+)/(?P<workspace_id>[^/]+)/(?P<ns_name>[^/]+)$": PrometheusServiceResponse.method_dispatch(
PrometheusServiceResponse.tags # type: ignore
),
} }

View File

@ -1,46 +1,108 @@
from .responses import APIGatewayResponse from .responses import APIGatewayResponse
from ..apigatewayv2.urls import url_paths as url_paths_v2 from ..apigatewayv2.urls import url_paths as url_paths_v2
response = APIGatewayResponse()
url_bases = [r"https?://apigateway\.(.+)\.amazonaws.com"] url_bases = [r"https?://apigateway\.(.+)\.amazonaws.com"]
url_paths = { url_paths = {
"{0}/restapis$": response.restapis, "{0}/restapis$": APIGatewayResponse.method_dispatch(APIGatewayResponse.restapis),
"{0}/restapis/(?P<function_id>[^/]+)/?$": response.restapis_individual, "{0}/restapis/(?P<function_id>[^/]+)/?$": APIGatewayResponse.method_dispatch(
"{0}/restapis/(?P<function_id>[^/]+)/resources$": response.resources, APIGatewayResponse.restapis_individual
"{0}/restapis/(?P<function_id>[^/]+)/authorizers$": response.restapis_authorizers, ),
"{0}/restapis/(?P<function_id>[^/]+)/authorizers/(?P<authorizer_id>[^/]+)/?$": response.authorizers, "{0}/restapis/(?P<function_id>[^/]+)/resources$": APIGatewayResponse.method_dispatch(
"{0}/restapis/(?P<function_id>[^/]+)/stages$": response.restapis_stages, APIGatewayResponse.resources
"{0}/tags/arn:aws:apigateway:(?P<region_name>[^/]+)::/restapis/(?P<function_id>[^/]+)/stages/(?P<stage_name>[^/]+)/?$": response.restapis_stages_tags, ),
"{0}/restapis/(?P<function_id>[^/]+)/stages/(?P<stage_name>[^/]+)/?$": response.stages, "{0}/restapis/(?P<function_id>[^/]+)/authorizers$": APIGatewayResponse.method_dispatch(
"{0}/restapis/(?P<function_id>[^/]+)/stages/(?P<stage_name>[^/]+)/exports/(?P<export_type>[^/]+)/?$": response.export, APIGatewayResponse.restapis_authorizers
"{0}/restapis/(?P<function_id>[^/]+)/deployments$": response.deployments, ),
"{0}/restapis/(?P<function_id>[^/]+)/deployments/(?P<deployment_id>[^/]+)/?$": response.individual_deployment, "{0}/restapis/(?P<function_id>[^/]+)/authorizers/(?P<authorizer_id>[^/]+)/?$": APIGatewayResponse.method_dispatch(
"{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/?$": response.resource_individual, APIGatewayResponse.authorizers
"{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/methods/(?P<method_name>[^/]+)/?$": response.resource_methods, ),
r"{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/methods/(?P<method_name>[^/]+)/responses/(?P<status_code>\d+)$": response.resource_method_responses, "{0}/restapis/(?P<function_id>[^/]+)/stages$": APIGatewayResponse.method_dispatch(
r"{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/methods/(?P<method_name>[^/]+)/integration$": response.integrations, APIGatewayResponse.restapis_stages
r"{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/methods/(?P<method_name>[^/]+)/integration/responses/(?P<status_code>\d+)$": response.integration_responses, ),
r"{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/methods/(?P<method_name>[^/]+)/integration/responses/(?P<status_code>\d+)/$": response.integration_responses, "{0}/tags/arn:aws:apigateway:(?P<region_name>[^/]+)::/restapis/(?P<function_id>[^/]+)/stages/(?P<stage_name>[^/]+)/?$": APIGatewayResponse.method_dispatch(
"{0}/apikeys$": response.apikeys, APIGatewayResponse.restapis_stages_tags
"{0}/apikeys/(?P<apikey>[^/]+)": response.apikey_individual, ),
"{0}/usageplans$": response.usage_plans, "{0}/restapis/(?P<function_id>[^/]+)/stages/(?P<stage_name>[^/]+)/?$": APIGatewayResponse.method_dispatch(
"{0}/domainnames$": response.domain_names, APIGatewayResponse.stages
"{0}/restapis/(?P<function_id>[^/]+)/models$": response.models, ),
"{0}/restapis/(?P<function_id>[^/]+)/models/(?P<model_name>[^/]+)/?$": response.model_induvidual, "{0}/restapis/(?P<function_id>[^/]+)/stages/(?P<stage_name>[^/]+)/exports/(?P<export_type>[^/]+)/?$": APIGatewayResponse.method_dispatch(
"{0}/domainnames/(?P<domain_name>[^/]+)/?$": response.domain_name_induvidual, APIGatewayResponse.export
"{0}/domainnames/(?P<domain_name>[^/]+)/basepathmappings$": response.base_path_mappings, ),
"{0}/domainnames/(?P<domain_name>[^/]+)/basepathmappings/(?P<base_path_mapping>[^/]+)$": response.base_path_mapping_individual, "{0}/restapis/(?P<function_id>[^/]+)/deployments$": APIGatewayResponse.method_dispatch(
"{0}/usageplans/(?P<usage_plan_id>[^/]+)/?$": response.usage_plan_individual, APIGatewayResponse.deployments
"{0}/usageplans/(?P<usage_plan_id>[^/]+)/keys$": response.usage_plan_keys, ),
"{0}/usageplans/(?P<usage_plan_id>[^/]+)/keys/(?P<api_key_id>[^/]+)/?$": response.usage_plan_key_individual, "{0}/restapis/(?P<function_id>[^/]+)/deployments/(?P<deployment_id>[^/]+)/?$": APIGatewayResponse.method_dispatch(
"{0}/restapis/(?P<function_id>[^/]+)/requestvalidators$": response.request_validators, APIGatewayResponse.individual_deployment
"{0}/restapis/(?P<api_id>[^/]+)/requestvalidators/(?P<validator_id>[^/]+)/?$": response.request_validator_individual, ),
"{0}/restapis/(?P<api_id>[^/]+)/gatewayresponses/?$": response.gateway_responses, "{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/?$": APIGatewayResponse.method_dispatch(
"{0}/restapis/(?P<api_id>[^/]+)/gatewayresponses/(?P<response_type>[^/]+)/?$": response.gateway_response, APIGatewayResponse.resource_individual
"{0}/vpclinks$": response.vpc_links, ),
"{0}/vpclinks/(?P<vpclink_id>[^/]+)": response.vpc_link, "{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/methods/(?P<method_name>[^/]+)/?$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.resource_methods
),
r"{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/methods/(?P<method_name>[^/]+)/responses/(?P<status_code>\d+)$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.resource_method_responses
),
r"{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/methods/(?P<method_name>[^/]+)/integration$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.integrations
),
r"{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/methods/(?P<method_name>[^/]+)/integration/responses/(?P<status_code>\d+)$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.integration_responses
),
r"{0}/restapis/(?P<function_id>[^/]+)/resources/(?P<resource_id>[^/]+)/methods/(?P<method_name>[^/]+)/integration/responses/(?P<status_code>\d+)/$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.integration_responses
),
"{0}/apikeys$": APIGatewayResponse.method_dispatch(APIGatewayResponse.apikeys),
"{0}/apikeys/(?P<apikey>[^/]+)": APIGatewayResponse.method_dispatch(
APIGatewayResponse.apikey_individual
),
"{0}/usageplans$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.usage_plans
),
"{0}/domainnames$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.domain_names
),
"{0}/restapis/(?P<function_id>[^/]+)/models$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.models
),
"{0}/restapis/(?P<function_id>[^/]+)/models/(?P<model_name>[^/]+)/?$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.model_induvidual
),
"{0}/domainnames/(?P<domain_name>[^/]+)/?$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.domain_name_induvidual
),
"{0}/domainnames/(?P<domain_name>[^/]+)/basepathmappings$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.base_path_mappings
),
"{0}/domainnames/(?P<domain_name>[^/]+)/basepathmappings/(?P<base_path_mapping>[^/]+)$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.base_path_mapping_individual
),
"{0}/usageplans/(?P<usage_plan_id>[^/]+)/?$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.usage_plan_individual
),
"{0}/usageplans/(?P<usage_plan_id>[^/]+)/keys$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.usage_plan_keys
),
"{0}/usageplans/(?P<usage_plan_id>[^/]+)/keys/(?P<api_key_id>[^/]+)/?$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.usage_plan_key_individual
),
"{0}/restapis/(?P<function_id>[^/]+)/requestvalidators$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.request_validators
),
"{0}/restapis/(?P<api_id>[^/]+)/requestvalidators/(?P<validator_id>[^/]+)/?$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.request_validator_individual
),
"{0}/restapis/(?P<api_id>[^/]+)/gatewayresponses/?$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.gateway_responses
),
"{0}/restapis/(?P<api_id>[^/]+)/gatewayresponses/(?P<response_type>[^/]+)/?$": APIGatewayResponse.method_dispatch(
APIGatewayResponse.gateway_response
),
"{0}/vpclinks$": APIGatewayResponse.method_dispatch(APIGatewayResponse.vpc_links),
"{0}/vpclinks/(?P<vpclink_id>[^/]+)": APIGatewayResponse.method_dispatch(
APIGatewayResponse.vpc_link
),
} }
# Also manages the APIGatewayV2 # Also manages the APIGatewayV2

View File

@ -6,35 +6,84 @@ url_bases = [
] ]
response_v2 = ApiGatewayV2Response()
url_paths = { url_paths = {
"{0}/v2/apis$": response_v2.apis, "{0}/v2/apis$": ApiGatewayV2Response.method_dispatch(ApiGatewayV2Response.apis),
"{0}/v2/apis/(?P<api_id>[^/]+)$": response_v2.api, "{0}/v2/apis/(?P<api_id>[^/]+)$": ApiGatewayV2Response.method_dispatch(
"{0}/v2/apis/(?P<api_id>[^/]+)/authorizers$": response_v2.authorizers, ApiGatewayV2Response.api
"{0}/v2/apis/(?P<api_id>[^/]+)/authorizers/(?P<authorizer_id>[^/]+)$": response_v2.authorizer, ),
"{0}/v2/apis/(?P<api_id>[^/]+)/cors$": response_v2.cors, "{0}/v2/apis/(?P<api_id>[^/]+)/authorizers$": ApiGatewayV2Response.method_dispatch(
"{0}/v2/apis/(?P<api_id>[^/]+)/integrations$": response_v2.integrations, ApiGatewayV2Response.authorizers
"{0}/v2/apis/(?P<api_id>[^/]+)/integrations/(?P<integration_id>[^/]+)$": response_v2.integration, ),
"{0}/v2/apis/(?P<api_id>[^/]+)/integrations/(?P<integration_id>[^/]+)/integrationresponses$": response_v2.integration_responses, "{0}/v2/apis/(?P<api_id>[^/]+)/authorizers/(?P<authorizer_id>[^/]+)$": ApiGatewayV2Response.method_dispatch(
"{0}/v2/apis/(?P<api_id>[^/]+)/integrations/(?P<integration_id>[^/]+)/integrationresponses/(?P<integration_response_id>[^/]+)$": response_v2.integration_response, ApiGatewayV2Response.authorizer
"{0}/v2/apis/(?P<api_id>[^/]+)/models$": response_v2.models, ),
"{0}/v2/apis/(?P<api_id>[^/]+)/models/(?P<model_id>[^/]+)$": response_v2.model, "{0}/v2/apis/(?P<api_id>[^/]+)/cors$": ApiGatewayV2Response.method_dispatch(
"{0}/v2/apis/(?P<api_id>[^/]+)/routes$": response_v2.routes, ApiGatewayV2Response.cors
"{0}/v2/apis/(?P<api_id>[^/]+)/routes/(?P<route_id>[^/]+)$": response_v2.route, ),
"{0}/v2/apis/(?P<api_id>[^/]+)/routes/(?P<route_id>[^/]+)/routeresponses$": response_v2.route_responses, "{0}/v2/apis/(?P<api_id>[^/]+)/integrations$": ApiGatewayV2Response.method_dispatch(
"{0}/v2/apis/(?P<api_id>[^/]+)/routes/(?P<route_id>[^/]+)/routeresponses/(?P<route_response_id>[^/]+)$": response_v2.route_response, ApiGatewayV2Response.integrations
"{0}/v2/apis/(?P<api_id>[^/]+)/routes/(?P<route_id>[^/]+)/requestparameters/(?P<request_parameter>[^/]+)$": response_v2.route_request_parameter, ),
"{0}/v2/apis/(?P<api_id>[^/]+)/stages$": response_v2.stages, "{0}/v2/apis/(?P<api_id>[^/]+)/integrations/(?P<integration_id>[^/]+)$": ApiGatewayV2Response.method_dispatch(
"{0}/v2/apis/(?P<api_id>[^/]+)/stages/(?P<stage_name>[^/]+)$": response_v2.stage, ApiGatewayV2Response.integration
"{0}/v2/tags/(?P<resource_arn>[^/]+)$": response_v2.tags, ),
"{0}/v2/tags/(?P<resource_arn_pt1>[^/]+)/apis/(?P<resource_arn_pt2>[^/]+)$": response_v2.tags, "{0}/v2/apis/(?P<api_id>[^/]+)/integrations/(?P<integration_id>[^/]+)/integrationresponses$": ApiGatewayV2Response.method_dispatch(
"{0}/v2/tags/(?P<resource_arn_pt1>[^/]+)/vpclinks/(?P<resource_arn_pt2>[^/]+)$": response_v2.tags, ApiGatewayV2Response.integration_responses
"{0}/v2/vpclinks$": response_v2.vpc_links, ),
"{0}/v2/vpclinks/(?P<vpc_link_id>[^/]+)$": response_v2.vpc_link, "{0}/v2/apis/(?P<api_id>[^/]+)/integrations/(?P<integration_id>[^/]+)/integrationresponses/(?P<integration_response_id>[^/]+)$": ApiGatewayV2Response.method_dispatch(
"{0}/v2/domainnames$": response_v2.domain_names, ApiGatewayV2Response.integration_response
"{0}/v2/domainnames/(?P<domain_name>[^/]+)$": response_v2.domain_name, ),
"{0}/v2/domainnames/(?P<domain_name>[^/]+)/apimappings$": response_v2.api_mappings, "{0}/v2/apis/(?P<api_id>[^/]+)/models$": ApiGatewayV2Response.method_dispatch(
"{0}/v2/domainnames/(?P<domain_name>[^/]+)/apimappings/(?P<api_mapping_id>[^/]+)$": response_v2.api_mapping, ApiGatewayV2Response.models
),
"{0}/v2/apis/(?P<api_id>[^/]+)/models/(?P<model_id>[^/]+)$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.model
),
"{0}/v2/apis/(?P<api_id>[^/]+)/routes$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.routes
),
"{0}/v2/apis/(?P<api_id>[^/]+)/routes/(?P<route_id>[^/]+)$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.route
),
"{0}/v2/apis/(?P<api_id>[^/]+)/routes/(?P<route_id>[^/]+)/routeresponses$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.route_responses
),
"{0}/v2/apis/(?P<api_id>[^/]+)/routes/(?P<route_id>[^/]+)/routeresponses/(?P<route_response_id>[^/]+)$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.route_response
),
"{0}/v2/apis/(?P<api_id>[^/]+)/routes/(?P<route_id>[^/]+)/requestparameters/(?P<request_parameter>[^/]+)$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.route_request_parameter
),
"{0}/v2/apis/(?P<api_id>[^/]+)/stages$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.stages
),
"{0}/v2/apis/(?P<api_id>[^/]+)/stages/(?P<stage_name>[^/]+)$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.stage
),
"{0}/v2/tags/(?P<resource_arn>[^/]+)$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.tags
),
"{0}/v2/tags/(?P<resource_arn_pt1>[^/]+)/apis/(?P<resource_arn_pt2>[^/]+)$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.tags
),
"{0}/v2/tags/(?P<resource_arn_pt1>[^/]+)/vpclinks/(?P<resource_arn_pt2>[^/]+)$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.tags
),
"{0}/v2/vpclinks$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.vpc_links
),
"{0}/v2/vpclinks/(?P<vpc_link_id>[^/]+)$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.vpc_link
),
"{0}/v2/domainnames$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.domain_names
),
"{0}/v2/domainnames/(?P<domain_name>[^/]+)$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.domain_name
),
"{0}/v2/domainnames/(?P<domain_name>[^/]+)/apimappings$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.api_mappings
),
"{0}/v2/domainnames/(?P<domain_name>[^/]+)/apimappings/(?P<api_mapping_id>[^/]+)$": ApiGatewayV2Response.method_dispatch(
ApiGatewayV2Response.api_mapping
),
} }

View File

@ -6,17 +6,18 @@ url_bases = [
] ]
response = AppConfigResponse()
url_paths = { url_paths = {
"{0}/applications$": response.dispatch, "{0}/applications$": AppConfigResponse.dispatch,
"{0}/applications/(?P<app_id>[^/]+)$": response.dispatch, "{0}/applications/(?P<app_id>[^/]+)$": AppConfigResponse.dispatch,
"{0}/applications/(?P<app_id>[^/]+)/configurationprofiles$": response.dispatch, "{0}/applications/(?P<app_id>[^/]+)/configurationprofiles$": AppConfigResponse.dispatch,
"{0}/applications/(?P<app_id>[^/]+)/configurationprofiles/(?P<config_profile_id>[^/]+)$": response.dispatch, "{0}/applications/(?P<app_id>[^/]+)/configurationprofiles/(?P<config_profile_id>[^/]+)$": AppConfigResponse.dispatch,
"{0}/applications/(?P<app_id>[^/]+)/configurationprofiles/(?P<config_profile_id>[^/]+)/hostedconfigurationversions$": response.dispatch, "{0}/applications/(?P<app_id>[^/]+)/configurationprofiles/(?P<config_profile_id>[^/]+)/hostedconfigurationversions$": AppConfigResponse.dispatch,
"{0}/applications/(?P<app_id>[^/]+)/configurationprofiles/(?P<config_profile_id>[^/]+)/hostedconfigurationversions/(?P<version>[^/]+)$": response.dispatch, "{0}/applications/(?P<app_id>[^/]+)/configurationprofiles/(?P<config_profile_id>[^/]+)/hostedconfigurationversions/(?P<version>[^/]+)$": AppConfigResponse.dispatch,
"{0}/tags/(?P<app_id>.+)$": response.dispatch, "{0}/tags/(?P<app_id>.+)$": AppConfigResponse.dispatch,
"{0}/tags/(?P<arn_part_1>[^/]+)/(?P<app_id>[^/]+)$": response.tags, "{0}/tags/(?P<arn_part_1>[^/]+)/(?P<app_id>[^/]+)$": AppConfigResponse.method_dispatch(
"{0}/tags/(?P<arn_part_1>[^/]+)/(?P<app_id>[^/]+)/configurationprofile/(?P<cp_id>[^/]+)$": response.tags, AppConfigResponse.tags # type: ignore
),
"{0}/tags/(?P<arn_part_1>[^/]+)/(?P<app_id>[^/]+)/configurationprofile/(?P<cp_id>[^/]+)$": AppConfigResponse.method_dispatch(
AppConfigResponse.tags # type: ignore
),
} }

View File

@ -6,17 +6,30 @@ url_bases = [
] ]
response = AppSyncResponse()
url_paths = { url_paths = {
"{0}/v1/apis$": response.graph_ql, "{0}/v1/apis$": AppSyncResponse.method_dispatch(AppSyncResponse.graph_ql),
"{0}/v1/apis/(?P<api_id>[^/]+)$": response.graph_ql_individual, "{0}/v1/apis/(?P<api_id>[^/]+)$": AppSyncResponse.method_dispatch(
"{0}/v1/apis/(?P<api_id>[^/]+)/apikeys$": response.api_key, AppSyncResponse.graph_ql_individual
"{0}/v1/apis/(?P<api_id>[^/]+)/apikeys/(?P<api_key_id>[^/]+)$": response.api_key_individual, ),
"{0}/v1/apis/(?P<api_id>[^/]+)/schemacreation$": response.schemacreation, "{0}/v1/apis/(?P<api_id>[^/]+)/apikeys$": AppSyncResponse.method_dispatch(
"{0}/v1/apis/(?P<api_id>[^/]+)/schema$": response.schema, AppSyncResponse.api_key
"{0}/v1/tags/(?P<resource_arn>.+)$": response.tags, ),
"{0}/v1/tags/(?P<resource_arn_pt1>.+)/(?P<resource_arn_pt2>.+)$": response.tags, "{0}/v1/apis/(?P<api_id>[^/]+)/apikeys/(?P<api_key_id>[^/]+)$": AppSyncResponse.method_dispatch(
"{0}/v1/apis/(?P<api_id>[^/]+)/types/(?P<type_name>.+)$": response.types, AppSyncResponse.api_key_individual
),
"{0}/v1/apis/(?P<api_id>[^/]+)/schemacreation$": AppSyncResponse.method_dispatch(
AppSyncResponse.schemacreation
),
"{0}/v1/apis/(?P<api_id>[^/]+)/schema$": AppSyncResponse.method_dispatch(
AppSyncResponse.schema
),
"{0}/v1/tags/(?P<resource_arn>.+)$": AppSyncResponse.method_dispatch(
AppSyncResponse.tags
),
"{0}/v1/tags/(?P<resource_arn_pt1>.+)/(?P<resource_arn_pt2>.+)$": AppSyncResponse.method_dispatch(
AppSyncResponse.tags
),
"{0}/v1/apis/(?P<api_id>[^/]+)/types/(?P<type_name>.+)$": AppSyncResponse.method_dispatch(
AppSyncResponse.types
),
} }

View File

@ -2,32 +2,81 @@ from .responses import LambdaResponse
url_bases = [r"https?://lambda\.(.+)\.amazonaws\.com"] url_bases = [r"https?://lambda\.(.+)\.amazonaws\.com"]
response = LambdaResponse()
url_paths = { url_paths = {
r"{0}/(?P<api_version>[^/]+)/functions$": response.root, r"{0}/(?P<api_version>[^/]+)/functions$": LambdaResponse.method_dispatch(
r"{0}/(?P<api_version>[^/]+)/functions/$": response.root, LambdaResponse.root
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/?$": response.function, ),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/aliases$": response.aliases, r"{0}/(?P<api_version>[^/]+)/functions/$": LambdaResponse.method_dispatch(
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/aliases/(?P<alias_name>[\w_-]+)$": response.alias, LambdaResponse.root
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/versions/?$": response.versions, ),
r"{0}/(?P<api_version>[^/]+)/event-source-mappings/$": response.event_source_mappings, r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/?$": LambdaResponse.method_dispatch(
r"{0}/(?P<api_version>[^/]+)/event-source-mappings/(?P<UUID>[\w_-]+)/?$": response.event_source_mapping, LambdaResponse.function
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_-]+)/invocations/?$": response.invoke, ),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<resource_arn>.+)/invocations/?$": response.invoke, r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/aliases$": LambdaResponse.method_dispatch(
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/invoke-async$": response.invoke_async, LambdaResponse.aliases
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/invoke-async/$": response.invoke_async, ),
r"{0}/(?P<api_version>[^/]+)/tags/(?P<resource_arn>.+)": response.tag, r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/aliases/(?P<alias_name>[\w_-]+)$": LambdaResponse.method_dispatch(
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/policy/(?P<statement_id>[\w_-]+)$": response.policy, LambdaResponse.alias
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/policy/?$": response.policy, ),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/configuration/?$": response.configuration, r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/versions/?$": LambdaResponse.method_dispatch(
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/code/?$": response.code, LambdaResponse.versions
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/code-signing-config$": response.code_signing_config, ),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/concurrency/?$": response.function_concurrency, r"{0}/(?P<api_version>[^/]+)/event-source-mappings/$": LambdaResponse.method_dispatch(
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/url/?$": response.function_url_config, LambdaResponse.event_source_mappings
r"{0}/(?P<api_version>[^/]+)/layers$": response.list_layers, ),
r"{0}/(?P<api_version>[^/]+)/layers/$": response.list_layers, r"{0}/(?P<api_version>[^/]+)/event-source-mappings/(?P<UUID>[\w_-]+)/?$": LambdaResponse.method_dispatch(
r"{0}/(?P<api_version>[^/]+)/layers/(?P<layer_name>.+)/versions$": response.layers_versions, LambdaResponse.event_source_mapping
r"{0}/(?P<api_version>[^/]+)/layers/(?P<layer_name>.+)/versions/$": response.layers_versions, ),
r"{0}/(?P<api_version>[^/]+)/layers/(?P<layer_name>.+)/versions/(?P<layer_version>[\w_-]+)$": response.layers_version, r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_-]+)/invocations/?$": LambdaResponse.method_dispatch(
LambdaResponse.invoke
),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<resource_arn>.+)/invocations/?$": LambdaResponse.method_dispatch(
LambdaResponse.invoke
),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/invoke-async$": LambdaResponse.method_dispatch(
LambdaResponse.invoke_async
),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/invoke-async/$": LambdaResponse.method_dispatch(
LambdaResponse.invoke_async
),
r"{0}/(?P<api_version>[^/]+)/tags/(?P<resource_arn>.+)": LambdaResponse.method_dispatch(
LambdaResponse.tag
),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/policy/(?P<statement_id>[\w_-]+)$": LambdaResponse.method_dispatch(
LambdaResponse.policy
),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/policy/?$": LambdaResponse.method_dispatch(
LambdaResponse.policy
),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/configuration/?$": LambdaResponse.method_dispatch(
LambdaResponse.configuration
),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/code/?$": LambdaResponse.method_dispatch(
LambdaResponse.code
),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/code-signing-config$": LambdaResponse.method_dispatch(
LambdaResponse.code_signing_config
),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/concurrency/?$": LambdaResponse.method_dispatch(
LambdaResponse.function_concurrency
),
r"{0}/(?P<api_version>[^/]+)/functions/(?P<function_name>[\w_:%-]+)/url/?$": LambdaResponse.method_dispatch(
LambdaResponse.function_url_config
),
r"{0}/(?P<api_version>[^/]+)/layers$": LambdaResponse.method_dispatch(
LambdaResponse.list_layers
),
r"{0}/(?P<api_version>[^/]+)/layers/$": LambdaResponse.method_dispatch(
LambdaResponse.list_layers
),
r"{0}/(?P<api_version>[^/]+)/layers/(?P<layer_name>.+)/versions$": LambdaResponse.method_dispatch(
LambdaResponse.layers_versions
),
r"{0}/(?P<api_version>[^/]+)/layers/(?P<layer_name>.+)/versions/$": LambdaResponse.method_dispatch(
LambdaResponse.layers_versions
),
r"{0}/(?P<api_version>[^/]+)/layers/(?P<layer_name>.+)/versions/(?P<layer_version>[\w_-]+)$": LambdaResponse.method_dispatch(
LambdaResponse.layers_version
),
} }

View File

@ -2,18 +2,32 @@
from .responses import CloudFrontResponse from .responses import CloudFrontResponse
response = CloudFrontResponse()
url_bases = [ url_bases = [
r"https?://cloudfront\.amazonaws\.com", r"https?://cloudfront\.amazonaws\.com",
] ]
url_paths = { url_paths = {
"{0}/2020-05-31/distribution$": response.distributions, "{0}/2020-05-31/distribution$": CloudFrontResponse.method_dispatch(
"{0}/2020-05-31/distribution/(?P<distribution_id>[^/]+)$": response.individual_distribution, CloudFrontResponse.distributions
"{0}/2020-05-31/distribution/(?P<distribution_id>[^/]+)/config$": response.update_distribution, ),
"{0}/2020-05-31/distribution/(?P<distribution_id>[^/]+)/invalidation": response.invalidation, "{0}/2020-05-31/distribution/(?P<distribution_id>[^/]+)$": CloudFrontResponse.method_dispatch(
"{0}/2020-05-31/tagging$": response.tags, CloudFrontResponse.individual_distribution
"{0}/2020-05-31/origin-access-control$": response.origin_access_controls, ),
"{0}/2020-05-31/origin-access-control/(?P<oac_id>[^/]+)$": response.origin_access_control, "{0}/2020-05-31/distribution/(?P<distribution_id>[^/]+)/config$": CloudFrontResponse.method_dispatch(
"{0}/2020-05-31/origin-access-control/(?P<oac_id>[^/]+)/config$": response.origin_access_control, CloudFrontResponse.update_distribution
),
"{0}/2020-05-31/distribution/(?P<distribution_id>[^/]+)/invalidation": CloudFrontResponse.method_dispatch(
CloudFrontResponse.invalidation
),
"{0}/2020-05-31/tagging$": CloudFrontResponse.method_dispatch(
CloudFrontResponse.tags
),
"{0}/2020-05-31/origin-access-control$": CloudFrontResponse.method_dispatch(
CloudFrontResponse.origin_access_controls
),
"{0}/2020-05-31/origin-access-control/(?P<oac_id>[^/]+)$": CloudFrontResponse.method_dispatch(
CloudFrontResponse.origin_access_control
),
"{0}/2020-05-31/origin-access-control/(?P<oac_id>[^/]+)/config$": CloudFrontResponse.method_dispatch(
CloudFrontResponse.origin_access_control
),
} }

View File

@ -4,5 +4,7 @@ url_bases = [r"https?://cognito-idp\.(.+)\.amazonaws.com"]
url_paths = { url_paths = {
"{0}/$": CognitoIdpResponse.dispatch, "{0}/$": CognitoIdpResponse.dispatch,
"{0}/(?P<user_pool_id>[^/]+)/.well-known/jwks.json$": CognitoIdpJsonWebKeyResponse().serve_json_web_key, "{0}/(?P<user_pool_id>[^/]+)/.well-known/jwks.json$": CognitoIdpJsonWebKeyResponse.method_dispatch(
CognitoIdpJsonWebKeyResponse.serve_json_web_key
),
} }

View File

@ -30,6 +30,7 @@ from typing import (
Set, Set,
ClassVar, ClassVar,
Callable, Callable,
TypeVar,
) )
from urllib.parse import parse_qs, parse_qsl, urlparse from urllib.parse import parse_qs, parse_qsl, urlparse
from werkzeug.exceptions import HTTPException from werkzeug.exceptions import HTTPException
@ -41,6 +42,9 @@ log = logging.getLogger(__name__)
JINJA_ENVS: Dict[type, Environment] = {} JINJA_ENVS: Dict[type, Environment] = {}
ResponseShape = TypeVar("ResponseShape", bound="BaseResponse")
def _decode_dict(d: Dict[Any, Any]) -> Dict[str, Any]: def _decode_dict(d: Dict[Any, Any]) -> Dict[str, Any]:
decoded: Dict[str, Any] = OrderedDict() decoded: Dict[str, Any] = OrderedDict()
for key, value in d.items(): for key, value in d.items():
@ -239,6 +243,24 @@ class BaseResponse(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
def dispatch(cls, *args: Any, **kwargs: Any) -> Any: # type: ignore[misc] def dispatch(cls, *args: Any, **kwargs: Any) -> Any: # type: ignore[misc]
return cls()._dispatch(*args, **kwargs) return cls()._dispatch(*args, **kwargs)
@classmethod
def method_dispatch( # type: ignore[misc]
cls, to_call: Callable[[ResponseShape, Any, str, Any], TYPE_RESPONSE]
) -> Callable[[Any, str, Any], TYPE_RESPONSE]:
"""
Takes a given unbound function (part of a Response class) and executes it for a new instance of this
response class.
Can be used wherever we want to specify different methods for dispatching in urls.py
:param to_call: Unbound method residing in this Response class
:return: A wrapper executing the given method on a new instance of this class
"""
@functools.wraps(to_call) # type: ignore
def _inner(request: Any, full_url: str, headers: Any) -> TYPE_RESPONSE:
return getattr(cls(), to_call.__name__)(request, full_url, headers)
return _inner
def setup_class( def setup_class(
self, request: Any, full_url: str, headers: Any, use_raw_body: bool = False self, request: Any, full_url: str, headers: Any, use_raw_body: bool = False
) -> None: ) -> None:

View File

@ -3,19 +3,37 @@ from .responses import DataBrewResponse
url_bases = [r"https?://databrew\.(.+)\.amazonaws.com"] url_bases = [r"https?://databrew\.(.+)\.amazonaws.com"]
url_paths = { url_paths = {
"{0}/recipeVersions$": DataBrewResponse().list_recipe_versions, "{0}/recipeVersions$": DataBrewResponse.method_dispatch(
DataBrewResponse.list_recipe_versions
),
"{0}/recipes$": DataBrewResponse.dispatch, "{0}/recipes$": DataBrewResponse.dispatch,
"{0}/recipes/(?P<recipe_name>[^/]+)$": DataBrewResponse().recipe_response, "{0}/recipes/(?P<recipe_name>[^/]+)$": DataBrewResponse.method_dispatch(
"{0}/recipes/(?P<recipe_name>[^/]+)/recipeVersion/(?P<recipe_version>[^/]+)": DataBrewResponse().delete_recipe_version, DataBrewResponse.recipe_response
"{0}/recipes/(?P<recipe_name>[^/]+)/publishRecipe$": DataBrewResponse().publish_recipe, ),
"{0}/recipes/(?P<recipe_name>[^/]+)/recipeVersion/(?P<recipe_version>[^/]+)": DataBrewResponse.method_dispatch(
DataBrewResponse.delete_recipe_version
),
"{0}/recipes/(?P<recipe_name>[^/]+)/publishRecipe$": DataBrewResponse.method_dispatch(
DataBrewResponse.publish_recipe
),
"{0}/rulesets$": DataBrewResponse.dispatch, "{0}/rulesets$": DataBrewResponse.dispatch,
"{0}/rulesets/(?P<ruleset_name>[^/]+)$": DataBrewResponse().ruleset_response, "{0}/rulesets/(?P<ruleset_name>[^/]+)$": DataBrewResponse.method_dispatch(
DataBrewResponse.ruleset_response
),
"{0}/datasets$": DataBrewResponse.dispatch, "{0}/datasets$": DataBrewResponse.dispatch,
"{0}/datasets/(?P<dataset_name>[^/]+)$": DataBrewResponse().dataset_response, "{0}/datasets/(?P<dataset_name>[^/]+)$": DataBrewResponse.method_dispatch(
"{0}/jobs$": DataBrewResponse().list_jobs, DataBrewResponse.dataset_response
"{0}/jobs/(?P<job_name>[^/]+)$": DataBrewResponse().job_response, ),
"{0}/jobs$": DataBrewResponse.method_dispatch(DataBrewResponse.list_jobs),
"{0}/jobs/(?P<job_name>[^/]+)$": DataBrewResponse.method_dispatch(
DataBrewResponse.job_response
),
"{0}/profileJobs$": DataBrewResponse.dispatch, "{0}/profileJobs$": DataBrewResponse.dispatch,
"{0}/recipeJobs$": DataBrewResponse.dispatch, "{0}/recipeJobs$": DataBrewResponse.dispatch,
"{0}/profileJobs/(?P<job_name>[^/]+)$": DataBrewResponse().profile_job_response, "{0}/profileJobs/(?P<job_name>[^/]+)$": DataBrewResponse.method_dispatch(
"{0}/recipeJobs/(?P<job_name>[^/]+)$": DataBrewResponse().recipe_job_response, DataBrewResponse.profile_job_response
),
"{0}/recipeJobs/(?P<job_name>[^/]+)$": DataBrewResponse.method_dispatch(
DataBrewResponse.recipe_job_response
),
} }

View File

@ -4,13 +4,18 @@ from .responses import EBSResponse
url_bases = [r"https?://ebs\.(.+)\.amazonaws\.com"] url_bases = [r"https?://ebs\.(.+)\.amazonaws\.com"]
response = EBSResponse()
url_paths = { url_paths = {
"{0}/snapshots$": response.snapshots, "{0}/snapshots$": EBSResponse.method_dispatch(EBSResponse.snapshots),
"{0}/snapshots/completion/(?P<snapshot_id>[^/]+)$": response.complete_snapshot, "{0}/snapshots/completion/(?P<snapshot_id>[^/]+)$": EBSResponse.method_dispatch(
"{0}/snapshots/(?P<snapshot_id>[^/]+)/changedblocks$": response.snapshot_changed_blocks, EBSResponse.complete_snapshot
"{0}/snapshots/(?P<snapshot_id>[^/]+)/blocks$": response.snapshot_blocks, ),
"{0}/snapshots/(?P<snapshot_id>[^/]+)/blocks/(?P<block_idx>[^/]+)$": response.snapshot_block, "{0}/snapshots/(?P<snapshot_id>[^/]+)/changedblocks$": EBSResponse.method_dispatch(
EBSResponse.snapshot_changed_blocks
),
"{0}/snapshots/(?P<snapshot_id>[^/]+)/blocks$": EBSResponse.method_dispatch(
EBSResponse.snapshot_blocks
),
"{0}/snapshots/(?P<snapshot_id>[^/]+)/blocks/(?P<block_idx>[^/]+)$": EBSResponse.method_dispatch(
EBSResponse.snapshot_block
),
} }

View File

@ -5,10 +5,11 @@ url_bases = [
] ]
response = ElasticTranscoderResponse()
url_paths = { url_paths = {
r"{0}/(?P<api_version>[^/]+)/pipelines/?$": response.pipelines, r"{0}/(?P<api_version>[^/]+)/pipelines/?$": ElasticTranscoderResponse.method_dispatch(
r"{0}/(?P<api_version>[^/]+)/pipelines/(?P<pipeline_id>[^/]+)/?$": response.individual_pipeline, ElasticTranscoderResponse.pipelines
),
r"{0}/(?P<api_version>[^/]+)/pipelines/(?P<pipeline_id>[^/]+)/?$": ElasticTranscoderResponse.method_dispatch(
ElasticTranscoderResponse.individual_pipeline
),
} }

View File

@ -62,6 +62,7 @@ class GlacierResponse(BaseResponse):
def vault_archive_response( def vault_archive_response(
self, request: Any, full_url: str, headers: Any self, request: Any, full_url: str, headers: Any
) -> TYPE_RESPONSE: ) -> TYPE_RESPONSE:
self.setup_class(request, full_url, headers, use_raw_body=True)
return self._vault_archive_response(request, full_url, headers) return self._vault_archive_response(request, full_url, headers)
def _vault_archive_response( def _vault_archive_response(

View File

@ -2,14 +2,26 @@ from .responses import GlacierResponse
url_bases = [r"https?://glacier\.(.+)\.amazonaws.com"] url_bases = [r"https?://glacier\.(.+)\.amazonaws.com"]
response = GlacierResponse()
url_paths = { url_paths = {
"{0}/(?P<account_number>.+)/vaults$": response.all_vault_response, "{0}/(?P<account_number>.+)/vaults$": GlacierResponse.method_dispatch(
"{0}/(?P<account_number>.+)/vaults/(?P<vault_name>[^/]+)$": response.vault_response, GlacierResponse.all_vault_response
"{0}/(?P<account_number>.+)/vaults/(?P<vault_name>.+)/archives$": response.vault_archive_response, ),
"{0}/(?P<account_number>.+)/vaults/(?P<vault_name>.+)/archives/(?P<archive_id>.+)$": response.vault_archive_individual_response, "{0}/(?P<account_number>.+)/vaults/(?P<vault_name>[^/]+)$": GlacierResponse.method_dispatch(
"{0}/(?P<account_number>.+)/vaults/(?P<vault_name>.+)/jobs$": response.vault_jobs_response, GlacierResponse.vault_response
"{0}/(?P<account_number>.+)/vaults/(?P<vault_name>.+)/jobs/(?P<job_id>[^/.]+)$": response.vault_jobs_individual_response, ),
"{0}/(?P<account_number>.+)/vaults/(?P<vault_name>.+)/jobs/(?P<job_id>.+)/output$": response.vault_jobs_output_response, "{0}/(?P<account_number>.+)/vaults/(?P<vault_name>.+)/archives$": GlacierResponse.method_dispatch(
GlacierResponse.vault_archive_response
),
"{0}/(?P<account_number>.+)/vaults/(?P<vault_name>.+)/archives/(?P<archive_id>.+)$": GlacierResponse.method_dispatch(
GlacierResponse.vault_archive_individual_response
),
"{0}/(?P<account_number>.+)/vaults/(?P<vault_name>.+)/jobs$": GlacierResponse.method_dispatch(
GlacierResponse.vault_jobs_response
),
"{0}/(?P<account_number>.+)/vaults/(?P<vault_name>.+)/jobs/(?P<job_id>[^/.]+)$": GlacierResponse.method_dispatch(
GlacierResponse.vault_jobs_individual_response
),
"{0}/(?P<account_number>.+)/vaults/(?P<vault_name>.+)/jobs/(?P<job_id>.+)/output$": GlacierResponse.method_dispatch(
GlacierResponse.vault_jobs_output_response
),
} }

View File

@ -4,35 +4,89 @@ url_bases = [
r"https?://greengrass\.(.+)\.amazonaws.com", r"https?://greengrass\.(.+)\.amazonaws.com",
] ]
response = GreengrassResponse()
url_paths = { url_paths = {
"{0}/greengrass/definition/cores$": response.core_definitions, "{0}/greengrass/definition/cores$": GreengrassResponse.method_dispatch(
"{0}/greengrass/definition/cores/(?P<definition_id>[^/]+)/?$": response.core_definition, GreengrassResponse.core_definitions
"{0}/greengrass/definition/cores/(?P<definition_id>[^/]+)/versions$": response.core_definition_versions, ),
"{0}/greengrass/definition/cores/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": response.core_definition_version, "{0}/greengrass/definition/cores/(?P<definition_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
"{0}/greengrass/definition/devices$": response.device_definitions, GreengrassResponse.core_definition
"{0}/greengrass/definition/devices/(?P<definition_id>[^/]+)/?$": response.device_definition, ),
"{0}/greengrass/definition/devices/(?P<definition_id>[^/]+)/versions$": response.device_definition_versions, "{0}/greengrass/definition/cores/(?P<definition_id>[^/]+)/versions$": GreengrassResponse.method_dispatch(
"{0}/greengrass/definition/devices/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": response.device_definition_version, GreengrassResponse.core_definition_versions
"{0}/greengrass/definition/functions$": response.function_definitions, ),
"{0}/greengrass/definition/functions/(?P<definition_id>[^/]+)/?$": response.function_definition, "{0}/greengrass/definition/cores/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
"{0}/greengrass/definition/functions/(?P<definition_id>[^/]+)/versions$": response.function_definition_versions, GreengrassResponse.core_definition_version
"{0}/greengrass/definition/functions/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": response.function_definition_version, ),
"{0}/greengrass/definition/resources$": response.resource_definitions, "{0}/greengrass/definition/devices$": GreengrassResponse.method_dispatch(
"{0}/greengrass/definition/resources/(?P<definition_id>[^/]+)/?$": response.resource_definition, GreengrassResponse.device_definitions
"{0}/greengrass/definition/resources/(?P<definition_id>[^/]+)/versions$": response.resource_definition_versions, ),
"{0}/greengrass/definition/subscriptions$": response.subscription_definitions, "{0}/greengrass/definition/devices/(?P<definition_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
"{0}/greengrass/definition/subscriptions/(?P<definition_id>[^/]+)/?$": response.subscription_definition, GreengrassResponse.device_definition
"{0}/greengrass/definition/subscriptions/(?P<definition_id>[^/]+)/versions$": response.subscription_definition_versions, ),
"{0}/greengrass/definition/subscriptions/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": response.subscription_definition_version, "{0}/greengrass/definition/devices/(?P<definition_id>[^/]+)/versions$": GreengrassResponse.method_dispatch(
"{0}/greengrass/definition/resources/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": response.resource_definition_version, GreengrassResponse.device_definition_versions
"{0}/greengrass/groups$": response.groups, ),
"{0}/greengrass/groups/(?P<group_id>[^/]+)/?$": response.group, "{0}/greengrass/definition/devices/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
"{0}/greengrass/groups/(?P<group_id>[^/]+)/role$": response.role, GreengrassResponse.device_definition_version
"{0}/greengrass/groups/(?P<group_id>[^/]+)/versions$": response.group_versions, ),
"{0}/greengrass/groups/(?P<group_id>[^/]+)/deployments$": response.deployments, "{0}/greengrass/definition/functions$": GreengrassResponse.method_dispatch(
"{0}/greengrass/groups/(?P<group_id>[^/]+)/deployments/\\$reset$": response.deployments_reset, GreengrassResponse.function_definitions
"{0}/greengrass/groups/(?P<group_id>[^/]+)/deployments/(?P<group_version_id>[^/]+)/status$": response.deployment_satus, ),
"{0}/greengrass/groups/(?P<group_id>[^/]+)/versions/(?P<group_version_id>[^/]+)/?$": response.group_version, "{0}/greengrass/definition/functions/(?P<definition_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
GreengrassResponse.function_definition
),
"{0}/greengrass/definition/functions/(?P<definition_id>[^/]+)/versions$": GreengrassResponse.method_dispatch(
GreengrassResponse.function_definition_versions
),
"{0}/greengrass/definition/functions/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
GreengrassResponse.function_definition_version
),
"{0}/greengrass/definition/resources$": GreengrassResponse.method_dispatch(
GreengrassResponse.resource_definitions
),
"{0}/greengrass/definition/resources/(?P<definition_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
GreengrassResponse.resource_definition
),
"{0}/greengrass/definition/resources/(?P<definition_id>[^/]+)/versions$": GreengrassResponse.method_dispatch(
GreengrassResponse.resource_definition_versions
),
"{0}/greengrass/definition/subscriptions$": GreengrassResponse.method_dispatch(
GreengrassResponse.subscription_definitions
),
"{0}/greengrass/definition/subscriptions/(?P<definition_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
GreengrassResponse.subscription_definition
),
"{0}/greengrass/definition/subscriptions/(?P<definition_id>[^/]+)/versions$": GreengrassResponse.method_dispatch(
GreengrassResponse.subscription_definition_versions
),
"{0}/greengrass/definition/subscriptions/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
GreengrassResponse.subscription_definition_version
),
"{0}/greengrass/definition/resources/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
GreengrassResponse.resource_definition_version
),
"{0}/greengrass/groups$": GreengrassResponse.method_dispatch(
GreengrassResponse.groups
),
"{0}/greengrass/groups/(?P<group_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
GreengrassResponse.group
),
"{0}/greengrass/groups/(?P<group_id>[^/]+)/role$": GreengrassResponse.method_dispatch(
GreengrassResponse.role
),
"{0}/greengrass/groups/(?P<group_id>[^/]+)/versions$": GreengrassResponse.method_dispatch(
GreengrassResponse.group_versions
),
"{0}/greengrass/groups/(?P<group_id>[^/]+)/deployments$": GreengrassResponse.method_dispatch(
GreengrassResponse.deployments
),
"{0}/greengrass/groups/(?P<group_id>[^/]+)/deployments/\\$reset$": GreengrassResponse.method_dispatch(
GreengrassResponse.deployments_reset
),
"{0}/greengrass/groups/(?P<group_id>[^/]+)/deployments/(?P<group_version_id>[^/]+)/status$": GreengrassResponse.method_dispatch(
GreengrassResponse.deployment_satus
),
"{0}/greengrass/groups/(?P<group_id>[^/]+)/versions/(?P<group_version_id>[^/]+)/?$": GreengrassResponse.method_dispatch(
GreengrassResponse.group_version
),
} }

View File

@ -1,17 +1,25 @@
from .responses import GuardDutyResponse from .responses import GuardDutyResponse
response = GuardDutyResponse()
url_bases = [ url_bases = [
"https?://guardduty\\.(.+)\\.amazonaws\\.com", "https?://guardduty\\.(.+)\\.amazonaws\\.com",
] ]
url_paths = { url_paths = {
"{0}/detector$": response.detectors, "{0}/detector$": GuardDutyResponse.method_dispatch(GuardDutyResponse.detectors),
"{0}/detector/(?P<detector_id>[^/]+)$": response.detector, "{0}/detector/(?P<detector_id>[^/]+)$": GuardDutyResponse.method_dispatch(
"{0}/detector/(?P<detector_id>[^/]+)/filter$": response.filters, GuardDutyResponse.detector
"{0}/detector/(?P<detector_id>[^/]+)/filter/(?P<filter_name>[^/]+)$": response.filter, ),
"{0}/admin/enable$": response.enable_organization_admin_account, "{0}/detector/(?P<detector_id>[^/]+)/filter$": GuardDutyResponse.method_dispatch(
"{0}/admin$": response.list_organization_admin_accounts, GuardDutyResponse.filters
),
"{0}/detector/(?P<detector_id>[^/]+)/filter/(?P<filter_name>[^/]+)$": GuardDutyResponse.method_dispatch(
GuardDutyResponse.filter
),
"{0}/admin/enable$": GuardDutyResponse.method_dispatch(
GuardDutyResponse.enable_organization_admin_account
),
"{0}/admin$": GuardDutyResponse.method_dispatch(
GuardDutyResponse.list_organization_admin_accounts
),
} }

View File

@ -2,6 +2,8 @@ from .responses import InstanceMetadataResponse
url_bases = ["http://169.254.169.254"] url_bases = ["http://169.254.169.254"]
instance_metadata = InstanceMetadataResponse() url_paths = {
"{0}/(?P<path>.+)": InstanceMetadataResponse.method_dispatch(
url_paths = {"{0}/(?P<path>.+)": instance_metadata.metadata_response} InstanceMetadataResponse.metadata_response
)
}

View File

@ -3,22 +3,23 @@ from .responses import IoTResponse
url_bases = [r"https?://iot\.(.+)\.amazonaws\.com"] url_bases = [r"https?://iot\.(.+)\.amazonaws\.com"]
response = IoTResponse()
url_paths = { url_paths = {
# #
# Paths for :class:`moto.core.models.MockAWS` # Paths for :class:`moto.core.models.MockAWS`
# #
# This route requires special handling. # This route requires special handling.
"{0}/attached-policies/(?P<target>.*)$": response.dispatch_attached_policies, "{0}/attached-policies/(?P<target>.*)$": IoTResponse.method_dispatch(
IoTResponse.dispatch_attached_policies
),
# The remaining routes can be handled by the default dispatcher. # The remaining routes can be handled by the default dispatcher.
"{0}/.*$": response.dispatch, "{0}/.*$": IoTResponse.dispatch,
# #
# (Flask) Paths for :class:`moto.core.models.ServerModeMockAWS` # (Flask) Paths for :class:`moto.core.models.ServerModeMockAWS`
# #
# This route requires special handling. # This route requires special handling.
"{0}/attached-policies/<path:target>$": response.dispatch_attached_policies, "{0}/attached-policies/<path:target>$": IoTResponse.method_dispatch(
IoTResponse.dispatch_attached_policies
),
# The remaining routes can be handled by the default dispatcher. # The remaining routes can be handled by the default dispatcher.
"{0}/<path:route>$": response.dispatch, "{0}/<path:route>$": IoTResponse.dispatch,
} }

View File

@ -6,8 +6,8 @@ from typing import Any, Callable, List, Tuple
def exception_handler( def exception_handler(
f: Callable[[Any, Any, Any, Any], TYPE_RESPONSE] f: Callable[[Any, Any, str, Any], TYPE_RESPONSE]
) -> Callable[[Any], TYPE_RESPONSE]: ) -> Callable[[Any, Any, str, Any], TYPE_RESPONSE]:
@wraps(f) @wraps(f)
def _wrapper(*args: Any, **kwargs: Any) -> TYPE_RESPONSE: # type: ignore[misc] def _wrapper(*args: Any, **kwargs: Any) -> TYPE_RESPONSE: # type: ignore[misc]
try: try:

View File

@ -3,19 +3,47 @@ from .responses import ManagedBlockchainResponse
url_bases = [r"https?://managedblockchain\.(.+)\.amazonaws.com"] url_bases = [r"https?://managedblockchain\.(.+)\.amazonaws.com"]
url_paths = { url_paths = {
"{0}/networks$": ManagedBlockchainResponse().network_response, "{0}/networks$": ManagedBlockchainResponse.method_dispatch(
"{0}/networks/(?P<networkid>[^/.]+)$": ManagedBlockchainResponse().networkid_response, ManagedBlockchainResponse.network_response
"{0}/networks/(?P<networkid>[^/.]+)/proposals$": ManagedBlockchainResponse().proposal_response, ),
"{0}/networks/(?P<networkid>[^/.]+)/proposals/(?P<proposalid>[^/.]+)$": ManagedBlockchainResponse().proposalid_response, "{0}/networks/(?P<networkid>[^/.]+)$": ManagedBlockchainResponse.method_dispatch(
"{0}/networks/(?P<networkid>[^/.]+)/proposals/(?P<proposalid>[^/.]+)/votes$": ManagedBlockchainResponse().proposal_votes_response, ManagedBlockchainResponse.networkid_response
"{0}/invitations$": ManagedBlockchainResponse().invitation_response, ),
"{0}/invitations/(?P<invitationid>[^/.]+)$": ManagedBlockchainResponse().invitationid_response, "{0}/networks/(?P<networkid>[^/.]+)/proposals$": ManagedBlockchainResponse.method_dispatch(
"{0}/networks/(?P<networkid>[^/.]+)/members$": ManagedBlockchainResponse().member_response, ManagedBlockchainResponse.proposal_response
"{0}/networks/(?P<networkid>[^/.]+)/members/(?P<memberid>[^/.]+)$": ManagedBlockchainResponse().memberid_response, ),
"{0}/networks/(?P<networkid>[^/.]+)/members/(?P<memberid>[^/.]+)/nodes$": ManagedBlockchainResponse().node_response, "{0}/networks/(?P<networkid>[^/.]+)/proposals/(?P<proposalid>[^/.]+)$": ManagedBlockchainResponse.method_dispatch(
"{0}/networks/(?P<networkid>[^/.]+)/members/(?P<memberid>[^/.]+)/nodes?(?P<querys>[^/.]+)$": ManagedBlockchainResponse().node_response, ManagedBlockchainResponse.proposalid_response
"{0}/networks/(?P<networkid>[^/.]+)/members/(?P<memberid>[^/.]+)/nodes/(?P<nodeid>[^/.]+)$": ManagedBlockchainResponse().nodeid_response, ),
"{0}/networks/(?P<networkid>[^/.]+)/proposals/(?P<proposalid>[^/.]+)/votes$": ManagedBlockchainResponse.method_dispatch(
ManagedBlockchainResponse.proposal_votes_response
),
"{0}/invitations$": ManagedBlockchainResponse.method_dispatch(
ManagedBlockchainResponse.invitation_response
),
"{0}/invitations/(?P<invitationid>[^/.]+)$": ManagedBlockchainResponse.method_dispatch(
ManagedBlockchainResponse.invitationid_response
),
"{0}/networks/(?P<networkid>[^/.]+)/members$": ManagedBlockchainResponse.method_dispatch(
ManagedBlockchainResponse.member_response
),
"{0}/networks/(?P<networkid>[^/.]+)/members/(?P<memberid>[^/.]+)$": ManagedBlockchainResponse.method_dispatch(
ManagedBlockchainResponse.memberid_response
),
"{0}/networks/(?P<networkid>[^/.]+)/members/(?P<memberid>[^/.]+)/nodes$": ManagedBlockchainResponse.method_dispatch(
ManagedBlockchainResponse.node_response
),
"{0}/networks/(?P<networkid>[^/.]+)/members/(?P<memberid>[^/.]+)/nodes?(?P<querys>[^/.]+)$": ManagedBlockchainResponse.method_dispatch(
ManagedBlockchainResponse.node_response
),
"{0}/networks/(?P<networkid>[^/.]+)/members/(?P<memberid>[^/.]+)/nodes/(?P<nodeid>[^/.]+)$": ManagedBlockchainResponse.method_dispatch(
ManagedBlockchainResponse.nodeid_response
),
# >= botocore 1.19.41 (API change - memberId is now part of query-string or body) # >= botocore 1.19.41 (API change - memberId is now part of query-string or body)
"{0}/networks/(?P<networkid>[^/.]+)/nodes$": ManagedBlockchainResponse().node_response, "{0}/networks/(?P<networkid>[^/.]+)/nodes$": ManagedBlockchainResponse.method_dispatch(
"{0}/networks/(?P<networkid>[^/.]+)/nodes/(?P<nodeid>[^/.]+)$": ManagedBlockchainResponse().nodeid_response, ManagedBlockchainResponse.node_response
),
"{0}/networks/(?P<networkid>[^/.]+)/nodes/(?P<nodeid>[^/.]+)$": ManagedBlockchainResponse.method_dispatch(
ManagedBlockchainResponse.nodeid_response
),
} }

View File

@ -6,17 +6,26 @@ url_bases = [
] ]
response = MQResponse()
url_paths = { url_paths = {
"{0}/v1/brokers/(?P<broker_id>[^/]+)$": response.broker, "{0}/v1/brokers/(?P<broker_id>[^/]+)$": MQResponse.method_dispatch(
"{0}/v1/brokers/(?P<broker_id>[^/]+)/reboot$": response.reboot, MQResponse.broker
"{0}/v1/brokers/(?P<broker_id>[^/]+)/users$": response.users, ),
"{0}/v1/brokers/(?P<broker_id>[^/]+)/users/(?P<user_name>[^/]+)$": response.user, "{0}/v1/brokers/(?P<broker_id>[^/]+)/reboot$": MQResponse.method_dispatch(
"{0}/v1/brokers$": response.brokers, MQResponse.reboot
"{0}/v1/configurations$": response.configurations, ),
"{0}/v1/configurations/(?P<config_id>[^/]+)$": response.configuration, "{0}/v1/brokers/(?P<broker_id>[^/]+)/users$": MQResponse.method_dispatch(
"{0}/v1/configurations/(?P<config_id>[^/]+)/revisions/(?P<revision_id>[^/]+)$": response.configuration_revision, MQResponse.users
"{0}/v1/tags/(?P<resource_arn>[^/]+)$": response.tags, ),
"{0}/v1/brokers/(?P<broker_id>[^/]+)/users/(?P<user_name>[^/]+)$": MQResponse.method_dispatch(
MQResponse.user
),
"{0}/v1/brokers$": MQResponse.method_dispatch(MQResponse.brokers),
"{0}/v1/configurations$": MQResponse.method_dispatch(MQResponse.configurations),
"{0}/v1/configurations/(?P<config_id>[^/]+)$": MQResponse.method_dispatch(
MQResponse.configuration
),
"{0}/v1/configurations/(?P<config_id>[^/]+)/revisions/(?P<revision_id>[^/]+)$": MQResponse.method_dispatch(
MQResponse.configuration_revision
),
"{0}/v1/tags/(?P<resource_arn>[^/]+)$": MQResponse.method_dispatch(MQResponse.tags),
} }

View File

@ -6,14 +6,21 @@ url_bases = [
] ]
response = PinpointResponse()
url_paths = { url_paths = {
"{0}/v1/apps$": response.apps, "{0}/v1/apps$": PinpointResponse.method_dispatch(PinpointResponse.apps),
"{0}/v1/apps/(?P<app_id>[^/]+)$": response.app, "{0}/v1/apps/(?P<app_id>[^/]+)$": PinpointResponse.method_dispatch(
"{0}/v1/apps/(?P<app_id>[^/]+)/eventstream": response.eventstream, PinpointResponse.app
"{0}/v1/apps/(?P<app_id>[^/]+)/settings$": response.app_settings, ),
"{0}/v1/tags/(?P<app_arn>[^/]+)$": response.tags, "{0}/v1/apps/(?P<app_id>[^/]+)/eventstream": PinpointResponse.method_dispatch(
"{0}/v1/tags/(?P<app_arn_pt_1>[^/]+)/(?P<app_arn_pt_2>[^/]+)$": response.tags, PinpointResponse.eventstream
),
"{0}/v1/apps/(?P<app_id>[^/]+)/settings$": PinpointResponse.method_dispatch(
PinpointResponse.app_settings
),
"{0}/v1/tags/(?P<app_arn>[^/]+)$": PinpointResponse.method_dispatch(
PinpointResponse.tags
),
"{0}/v1/tags/(?P<app_arn_pt_1>[^/]+)/(?P<app_arn_pt_2>[^/]+)$": PinpointResponse.method_dispatch(
PinpointResponse.tags
),
} }

View File

@ -6,16 +6,29 @@ url_bases = [
] ]
response = QuickSightResponse()
url_paths = { url_paths = {
r"{0}/accounts/(?P<account_id>[\d]+)/data-sets$": response.dataset, r"{0}/accounts/(?P<account_id>[\d]+)/data-sets$": QuickSightResponse.method_dispatch(
r"{0}/accounts/(?P<account_id>[\d]+)/data-sets/(?P<datasetid>[^/.]+)/ingestions/(?P<ingestionid>[^/.]+)$": response.ingestion, QuickSightResponse.dataset
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/groups$": response.groups, ),
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/groups/(?P<groupname>[^/]+)$": response.group, r"{0}/accounts/(?P<account_id>[\d]+)/data-sets/(?P<datasetid>[^/.]+)/ingestions/(?P<ingestionid>[^/.]+)$": QuickSightResponse.method_dispatch(
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/groups/(?P<groupname>[^/]+)/members$": response.group_members, QuickSightResponse.ingestion
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/groups/(?P<groupname>[^/]+)/members/(?P<username>[^/]+)$": response.group_member, ),
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/users$": response.users, r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/groups$": QuickSightResponse.method_dispatch(
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/users/(?P<username>[^/]+)$": response.user, QuickSightResponse.groups
),
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/groups/(?P<groupname>[^/]+)$": QuickSightResponse.method_dispatch(
QuickSightResponse.group
),
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/groups/(?P<groupname>[^/]+)/members$": QuickSightResponse.method_dispatch(
QuickSightResponse.group_members
),
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/groups/(?P<groupname>[^/]+)/members/(?P<username>[^/]+)$": QuickSightResponse.method_dispatch(
QuickSightResponse.group_member
),
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/users$": QuickSightResponse.method_dispatch(
QuickSightResponse.users
),
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[a-zA-Z0-9._-]+)/users/(?P<username>[^/]+)$": QuickSightResponse.method_dispatch(
QuickSightResponse.user
),
} }

View File

@ -19,26 +19,66 @@ def tag_response2(request: Any, full_url: str, headers: Any) -> TYPE_RESPONSE:
url_paths = { url_paths = {
r"{0}/(?P<api_version>[\d_-]+)/hostedzone$": Route53().list_or_create_hostzone_response, r"{0}/(?P<api_version>[\d_-]+)/hostedzone$": Route53.method_dispatch(
r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)$": Route53().get_or_delete_hostzone_response, Route53.list_or_create_hostzone_response
r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/rrset$": Route53().rrset_response, ),
r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/rrset/$": Route53().rrset_response, r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)$": Route53.method_dispatch(
r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/dnssec$": Route53().get_dnssec_response, Route53.get_or_delete_hostzone_response
r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/dnssec/$": Route53().get_dnssec_response, ),
r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/associatevpc/?$": Route53().associate_vpc_response, r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/rrset$": Route53.method_dispatch(
r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/disassociatevpc/?$": Route53().disassociate_vpc_response, Route53.rrset_response
r"{0}/(?P<api_version>[\d_-]+)/hostedzonesbyname": Route53().list_hosted_zones_by_name_response, ),
r"{0}/(?P<api_version>[\d_-]+)/hostedzonesbyvpc": Route53().list_hosted_zones_by_vpc_response, r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/rrset/$": Route53.method_dispatch(
r"{0}/(?P<api_version>[\d_-]+)/hostedzonecount": Route53().get_hosted_zone_count_response, Route53.rrset_response
r"{0}/(?P<api_version>[\d_-]+)/healthcheck$": Route53().health_check_response1, ),
r"{0}/(?P<api_version>[\d_-]+)/healthcheck/(?P<health_check_id>[^/]+)$": Route53().health_check_response2, r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/dnssec$": Route53.method_dispatch(
r"{0}/(?P<api_version>[\d_-]+)/healthcheck/(?P<health_check_id>[^/]+)/status$": Route53().health_check_status_response, Route53.get_dnssec_response
),
r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/dnssec/$": Route53.method_dispatch(
Route53.get_dnssec_response
),
r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/associatevpc/?$": Route53.method_dispatch(
Route53.associate_vpc_response
),
r"{0}/(?P<api_version>[\d_-]+)/hostedzone/(?P<zone_id>[^/]+)/disassociatevpc/?$": Route53.method_dispatch(
Route53.disassociate_vpc_response
),
r"{0}/(?P<api_version>[\d_-]+)/hostedzonesbyname": Route53.method_dispatch(
Route53.list_hosted_zones_by_name_response
),
r"{0}/(?P<api_version>[\d_-]+)/hostedzonesbyvpc": Route53.method_dispatch(
Route53.list_hosted_zones_by_vpc_response
),
r"{0}/(?P<api_version>[\d_-]+)/hostedzonecount": Route53.method_dispatch(
Route53.get_hosted_zone_count_response
),
r"{0}/(?P<api_version>[\d_-]+)/healthcheck$": Route53.method_dispatch(
Route53.health_check_response1
),
r"{0}/(?P<api_version>[\d_-]+)/healthcheck/(?P<health_check_id>[^/]+)$": Route53.method_dispatch(
Route53.health_check_response2
),
r"{0}/(?P<api_version>[\d_-]+)/healthcheck/(?P<health_check_id>[^/]+)/status$": Route53.method_dispatch(
Route53.health_check_status_response
),
r"{0}/(?P<api_version>[\d_-]+)/tags/healthcheck/(?P<zone_id>[^/]+)$": tag_response1, r"{0}/(?P<api_version>[\d_-]+)/tags/healthcheck/(?P<zone_id>[^/]+)$": tag_response1,
r"{0}/(?P<api_version>[\d_-]+)/tags/hostedzone/(?P<zone_id>[^/]+)$": tag_response2, r"{0}/(?P<api_version>[\d_-]+)/tags/hostedzone/(?P<zone_id>[^/]+)$": tag_response2,
r"{0}/(?P<api_version>[\d_-]+)/trafficpolicyinstances/*": Route53().not_implemented_response, r"{0}/(?P<api_version>[\d_-]+)/trafficpolicyinstances/*": Route53.method_dispatch(
r"{0}/(?P<api_version>[\d_-]+)/change/(?P<change_id>[^/]+)$": Route53().get_change, Route53.not_implemented_response
r"{0}/(?P<api_version>[\d_-]+)/queryloggingconfig$": Route53().list_or_create_query_logging_config_response, ),
r"{0}/(?P<api_version>[\d_-]+)/queryloggingconfig/(?P<query_id>[^/]+)$": Route53().get_or_delete_query_logging_config_response, r"{0}/(?P<api_version>[\d_-]+)/change/(?P<change_id>[^/]+)$": Route53.method_dispatch(
r"{0}/(?P<api_version>[\d_-]+)/delegationset$": Route53().reusable_delegation_sets, Route53.get_change
r"{0}/(?P<api_version>[\d_-]+)/delegationset/(?P<delegation_set_id>[^/]+)$": Route53().reusable_delegation_set, ),
r"{0}/(?P<api_version>[\d_-]+)/queryloggingconfig$": Route53.method_dispatch(
Route53.list_or_create_query_logging_config_response
),
r"{0}/(?P<api_version>[\d_-]+)/queryloggingconfig/(?P<query_id>[^/]+)$": Route53.method_dispatch(
Route53.get_or_delete_query_logging_config_response
),
r"{0}/(?P<api_version>[\d_-]+)/delegationset$": Route53.method_dispatch(
Route53.reusable_delegation_sets
),
r"{0}/(?P<api_version>[\d_-]+)/delegationset/(?P<delegation_set_id>[^/]+)$": Route53.method_dispatch(
Route53.reusable_delegation_set
),
} }

View File

@ -1,6 +1,6 @@
from moto import settings from moto import settings
from .responses import S3ResponseInstance from .responses import S3Response
# Catch s3.amazonaws.com, but not s3-control.amazonaws.com # Catch s3.amazonaws.com, but not s3-control.amazonaws.com
url_bases = [ url_bases = [
@ -12,12 +12,18 @@ url_bases.extend(settings.get_s3_custom_endpoints())
url_paths = { url_paths = {
# subdomain bucket # subdomain bucket
"{0}/$": S3ResponseInstance.bucket_response, "{0}/$": S3Response.method_dispatch(S3Response.bucket_response),
# subdomain key of path-based bucket # subdomain key of path-based bucket
"{0}/(?P<key_or_bucket_name>[^/]+)$": S3ResponseInstance.ambiguous_response, "{0}/(?P<key_or_bucket_name>[^/]+)$": S3Response.method_dispatch(
"{0}/(?P<key_or_bucket_name>[^/]+)/$": S3ResponseInstance.ambiguous_response, S3Response.ambiguous_response
),
"{0}/(?P<key_or_bucket_name>[^/]+)/$": S3Response.method_dispatch(
S3Response.ambiguous_response
),
# path-based bucket + key # path-based bucket + key
"{0}/(?P<bucket_name_path>[^/]+)/(?P<key_name>.+)": S3ResponseInstance.key_response, "{0}/(?P<bucket_name_path>[^/]+)/(?P<key_name>.+)": S3Response.method_dispatch(
S3Response.key_response
),
# subdomain bucket + key with empty first part of path # subdomain bucket + key with empty first part of path
"{0}/(?P<key_name>/.*)$": S3ResponseInstance.key_response, "{0}/(?P<key_name>/.*)$": S3Response.method_dispatch(S3Response.key_response),
} }

View File

@ -155,9 +155,6 @@ class S3ControlResponse(BaseResponse):
return account_id, name return account_id, name
S3ControlResponseInstance = S3ControlResponse()
CREATE_ACCESS_POINT_TEMPLATE = """<CreateAccessPointResult> CREATE_ACCESS_POINT_TEMPLATE = """<CreateAccessPointResult>
<ResponseMetadata> <ResponseMetadata>
<RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId> <RequestId>1549581b-12b7-11e3-895e-1334aEXAMPLE</RequestId>

View File

@ -1,5 +1,5 @@
"""s3control base URL and path.""" """s3control base URL and path."""
from .responses import S3ControlResponseInstance from .responses import S3ControlResponse
url_bases = [ url_bases = [
r"https?://([0-9]+)\.s3-control\.(.+)\.amazonaws\.com", r"https?://([0-9]+)\.s3-control\.(.+)\.amazonaws\.com",
@ -7,8 +7,16 @@ url_bases = [
url_paths = { url_paths = {
r"{0}/v20180820/configuration/publicAccessBlock$": S3ControlResponseInstance.public_access_block, r"{0}/v20180820/configuration/publicAccessBlock$": S3ControlResponse.method_dispatch(
r"{0}/v20180820/accesspoint/(?P<name>[\w_:%-]+)$": S3ControlResponseInstance.access_point, S3ControlResponse.public_access_block
r"{0}/v20180820/accesspoint/(?P<name>[\w_:%-]+)/policy$": S3ControlResponseInstance.access_point_policy, ),
r"{0}/v20180820/accesspoint/(?P<name>[\w_:%-]+)/policyStatus$": S3ControlResponseInstance.access_point_policy_status, r"{0}/v20180820/accesspoint/(?P<name>[\w_:%-]+)$": S3ControlResponse.method_dispatch(
S3ControlResponse.access_point
),
r"{0}/v20180820/accesspoint/(?P<name>[\w_:%-]+)/policy$": S3ControlResponse.method_dispatch(
S3ControlResponse.access_point_policy
),
r"{0}/v20180820/accesspoint/(?P<name>[\w_:%-]+)/policyStatus$": S3ControlResponse.method_dispatch(
S3ControlResponse.access_point_policy_status
),
} }

View File

@ -6,14 +6,15 @@ url_bases = [
] ]
response = EventBridgeSchedulerResponse()
url_paths = { url_paths = {
"{0}/schedules$": response.dispatch, "{0}/schedules$": EventBridgeSchedulerResponse.dispatch,
"{0}/schedules/(?P<name>[^/]+)$": response.dispatch, "{0}/schedules/(?P<name>[^/]+)$": EventBridgeSchedulerResponse.dispatch,
"{0}/schedule-groups$": response.dispatch, "{0}/schedule-groups$": EventBridgeSchedulerResponse.dispatch,
"{0}/schedule-groups/(?P<name>[^/]+)$": response.dispatch, "{0}/schedule-groups/(?P<name>[^/]+)$": EventBridgeSchedulerResponse.dispatch,
"{0}/tags/(?P<ResourceArn>.+)$": response.tags, "{0}/tags/(?P<ResourceArn>.+)$": EventBridgeSchedulerResponse.method_dispatch(
"{0}/tags/arn:aws:scheduler:(?P<region_name>[^/]+):(?P<account_id>[^/]+):schedule/(?P<group_name>[^/]+)/(?P<schedule_name>[^/]+)/?$": response.tags, EventBridgeSchedulerResponse.tags
),
"{0}/tags/arn:aws:scheduler:(?P<region_name>[^/]+):(?P<account_id>[^/]+):schedule/(?P<group_name>[^/]+)/(?P<schedule_name>[^/]+)/?$": EventBridgeSchedulerResponse.method_dispatch(
EventBridgeSchedulerResponse.tags
),
} }

View File

@ -43,4 +43,4 @@ def test_domain_dispatched_with_service():
dispatcher = DomainDispatcherApplication(create_backend_app, service="s3") dispatcher = DomainDispatcherApplication(create_backend_app, service="s3")
backend_app = dispatcher.get_application({"HTTP_HOST": "s3.us-east1.amazonaws.com"}) backend_app = dispatcher.get_application({"HTTP_HOST": "s3.us-east1.amazonaws.com"})
keys = set(backend_app.view_functions.keys()) keys = set(backend_app.view_functions.keys())
assert "S3Response.key_response" in keys assert "moto.s3.responses.key_response" in keys

View File

@ -9,7 +9,7 @@ import boto3
from moto import settings, mock_s3 from moto import settings, mock_s3
from moto.dynamodb.models import DynamoDBBackend from moto.dynamodb.models import DynamoDBBackend
from moto.s3 import models as s3model, s3_backends from moto.s3 import models as s3model, s3_backends
from moto.s3.responses import S3ResponseInstance from moto.s3.responses import S3Response
from tests import DEFAULT_ACCOUNT_ID from tests import DEFAULT_ACCOUNT_ID
@ -182,7 +182,7 @@ class TestS3FileHandleClosures(TestCase):
f"<Part><ETag>{etag}</ETag><PartNumber>1</PartNumber></Part>" f"<Part><ETag>{etag}</ETag><PartNumber>1</PartNumber></Part>"
"</CompleteMultipartUpload>" "</CompleteMultipartUpload>"
) )
body = S3ResponseInstance._complete_multipart_body(mp_body) body = S3Response()._complete_multipart_body(mp_body)
self.s3_client.complete_multipart_upload( self.s3_client.complete_multipart_upload(
bucket_name=TEST_BUCKET, multipart_id=multipart_id, body=body bucket_name=TEST_BUCKET, multipart_id=multipart_id, body=body
) )