TechDebt: Enable MyPy on APIGateway-module (#5549)
This commit is contained in:
parent
d60aa64abb
commit
56ca48cfdd
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
## apigateway
|
## apigateway
|
||||||
<details>
|
<details>
|
||||||
<summary>65% implemented</summary>
|
<summary>62% implemented</summary>
|
||||||
|
|
||||||
- [X] create_api_key
|
- [X] create_api_key
|
||||||
- [X] create_authorizer
|
- [X] create_authorizer
|
||||||
@ -157,12 +157,12 @@
|
|||||||
- [ ] update_deployment
|
- [ ] update_deployment
|
||||||
- [ ] update_documentation_part
|
- [ ] update_documentation_part
|
||||||
- [ ] update_documentation_version
|
- [ ] update_documentation_version
|
||||||
- [X] update_domain_name
|
- [ ] update_domain_name
|
||||||
- [ ] update_gateway_response
|
- [ ] update_gateway_response
|
||||||
- [ ] update_integration
|
- [ ] update_integration
|
||||||
- [ ] update_integration_response
|
- [ ] update_integration_response
|
||||||
- [X] update_method
|
- [ ] update_method
|
||||||
- [X] update_method_response
|
- [ ] update_method_response
|
||||||
- [ ] update_model
|
- [ ] update_model
|
||||||
- [X] update_request_validator
|
- [X] update_request_validator
|
||||||
- [ ] update_resource
|
- [ ] update_resource
|
||||||
|
2
Makefile
2
Makefile
@ -28,7 +28,7 @@ lint:
|
|||||||
@echo "Running pylint..."
|
@echo "Running pylint..."
|
||||||
pylint -j 0 moto tests
|
pylint -j 0 moto tests
|
||||||
@echo "Running MyPy..."
|
@echo "Running MyPy..."
|
||||||
mypy --install-types --non-interactive moto/acm moto/amp moto/applicationautoscaling/
|
mypy --install-types --non-interactive
|
||||||
|
|
||||||
format:
|
format:
|
||||||
black moto/ tests/
|
black moto/ tests/
|
||||||
|
@ -149,12 +149,12 @@ apigateway
|
|||||||
- [ ] update_deployment
|
- [ ] update_deployment
|
||||||
- [ ] update_documentation_part
|
- [ ] update_documentation_part
|
||||||
- [ ] update_documentation_version
|
- [ ] update_documentation_version
|
||||||
- [X] update_domain_name
|
- [ ] update_domain_name
|
||||||
- [ ] update_gateway_response
|
- [ ] update_gateway_response
|
||||||
- [ ] update_integration
|
- [ ] update_integration
|
||||||
- [ ] update_integration_response
|
- [ ] update_integration_response
|
||||||
- [X] update_method
|
- [ ] update_method
|
||||||
- [X] update_method_response
|
- [ ] update_method_response
|
||||||
- [ ] update_model
|
- [ ] update_model
|
||||||
- [X] update_request_validator
|
- [X] update_request_validator
|
||||||
- [ ] update_resource
|
- [ ] update_resource
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from moto.core.exceptions import JsonRESTError
|
from moto.core.exceptions import JsonRESTError
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
class ApiGatewayException(JsonRESTError):
|
class ApiGatewayException(JsonRESTError):
|
||||||
@ -6,12 +7,12 @@ class ApiGatewayException(JsonRESTError):
|
|||||||
|
|
||||||
|
|
||||||
class BadRequestException(ApiGatewayException):
|
class BadRequestException(ApiGatewayException):
|
||||||
def __init__(self, message):
|
def __init__(self, message: str):
|
||||||
super().__init__("BadRequestException", message)
|
super().__init__("BadRequestException", message)
|
||||||
|
|
||||||
|
|
||||||
class NotFoundException(ApiGatewayException):
|
class NotFoundException(ApiGatewayException):
|
||||||
def __init__(self, message):
|
def __init__(self, message: str):
|
||||||
super().__init__("NotFoundException", message)
|
super().__init__("NotFoundException", message)
|
||||||
|
|
||||||
|
|
||||||
@ -22,199 +23,199 @@ class AccessDeniedException(ApiGatewayException):
|
|||||||
class ConflictException(ApiGatewayException):
|
class ConflictException(ApiGatewayException):
|
||||||
code = 409
|
code = 409
|
||||||
|
|
||||||
def __init__(self, message):
|
def __init__(self, message: str):
|
||||||
super().__init__("ConflictException", message)
|
super().__init__("ConflictException", message)
|
||||||
|
|
||||||
|
|
||||||
class AwsProxyNotAllowed(BadRequestException):
|
class AwsProxyNotAllowed(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
"Integrations of type 'AWS_PROXY' currently only supports Lambda function and Firehose stream invocations."
|
"Integrations of type 'AWS_PROXY' currently only supports Lambda function and Firehose stream invocations."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class CrossAccountNotAllowed(AccessDeniedException):
|
class CrossAccountNotAllowed(AccessDeniedException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
"AccessDeniedException", "Cross-account pass role is not allowed."
|
"AccessDeniedException", "Cross-account pass role is not allowed."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class RoleNotSpecified(BadRequestException):
|
class RoleNotSpecified(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Role ARN must be specified for AWS integrations")
|
super().__init__("Role ARN must be specified for AWS integrations")
|
||||||
|
|
||||||
|
|
||||||
class IntegrationMethodNotDefined(BadRequestException):
|
class IntegrationMethodNotDefined(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Enumeration value for HttpMethod must be non-empty")
|
super().__init__("Enumeration value for HttpMethod must be non-empty")
|
||||||
|
|
||||||
|
|
||||||
class InvalidOpenAPIDocumentException(BadRequestException):
|
class InvalidOpenAPIDocumentException(BadRequestException):
|
||||||
def __init__(self, cause):
|
def __init__(self, cause: Any):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
f"Failed to parse the uploaded OpenAPI document due to: {cause.message}"
|
f"Failed to parse the uploaded OpenAPI document due to: {cause.message}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class InvalidOpenApiDocVersionException(BadRequestException):
|
class InvalidOpenApiDocVersionException(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Only OpenAPI 3.x.x are currently supported")
|
super().__init__("Only OpenAPI 3.x.x are currently supported")
|
||||||
|
|
||||||
|
|
||||||
class InvalidOpenApiModeException(BadRequestException):
|
class InvalidOpenApiModeException(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
'Enumeration value of OpenAPI import mode must be "overwrite" or "merge"',
|
'Enumeration value of OpenAPI import mode must be "overwrite" or "merge"',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class InvalidResourcePathException(BadRequestException):
|
class InvalidResourcePathException(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
"Resource's path part only allow a-zA-Z0-9._- and curly braces at the beginning and the end and an optional plus sign before the closing brace."
|
"Resource's path part only allow a-zA-Z0-9._- and curly braces at the beginning and the end and an optional plus sign before the closing brace."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class InvalidHttpEndpoint(BadRequestException):
|
class InvalidHttpEndpoint(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid HTTP endpoint specified for URI")
|
super().__init__("Invalid HTTP endpoint specified for URI")
|
||||||
|
|
||||||
|
|
||||||
class InvalidArn(BadRequestException):
|
class InvalidArn(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid ARN specified in the request")
|
super().__init__("Invalid ARN specified in the request")
|
||||||
|
|
||||||
|
|
||||||
class InvalidIntegrationArn(BadRequestException):
|
class InvalidIntegrationArn(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("AWS ARN for integration must contain path or action")
|
super().__init__("AWS ARN for integration must contain path or action")
|
||||||
|
|
||||||
|
|
||||||
class InvalidRequestInput(BadRequestException):
|
class InvalidRequestInput(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid request input")
|
super().__init__("Invalid request input")
|
||||||
|
|
||||||
|
|
||||||
class NoIntegrationDefined(NotFoundException):
|
class NoIntegrationDefined(NotFoundException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("No integration defined for method")
|
super().__init__("No integration defined for method")
|
||||||
|
|
||||||
|
|
||||||
class NoIntegrationResponseDefined(NotFoundException):
|
class NoIntegrationResponseDefined(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid Response status code specified")
|
super().__init__("Invalid Response status code specified")
|
||||||
|
|
||||||
|
|
||||||
class NoMethodDefined(BadRequestException):
|
class NoMethodDefined(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("The REST API doesn't contain any methods")
|
super().__init__("The REST API doesn't contain any methods")
|
||||||
|
|
||||||
|
|
||||||
class AuthorizerNotFoundException(NotFoundException):
|
class AuthorizerNotFoundException(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid Authorizer identifier specified")
|
super().__init__("Invalid Authorizer identifier specified")
|
||||||
|
|
||||||
|
|
||||||
class StageNotFoundException(NotFoundException):
|
class StageNotFoundException(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid stage identifier specified")
|
super().__init__("Invalid stage identifier specified")
|
||||||
|
|
||||||
|
|
||||||
class ApiKeyNotFoundException(NotFoundException):
|
class ApiKeyNotFoundException(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid API Key identifier specified")
|
super().__init__("Invalid API Key identifier specified")
|
||||||
|
|
||||||
|
|
||||||
class UsagePlanNotFoundException(NotFoundException):
|
class UsagePlanNotFoundException(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid Usage Plan ID specified")
|
super().__init__("Invalid Usage Plan ID specified")
|
||||||
|
|
||||||
|
|
||||||
class ApiKeyAlreadyExists(ApiGatewayException):
|
class ApiKeyAlreadyExists(ApiGatewayException):
|
||||||
code = 409
|
code = 409
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("ConflictException", "API Key already exists")
|
super().__init__("ConflictException", "API Key already exists")
|
||||||
|
|
||||||
|
|
||||||
class InvalidDomainName(BadRequestException):
|
class InvalidDomainName(BadRequestException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("No Domain Name specified")
|
super().__init__("No Domain Name specified")
|
||||||
|
|
||||||
|
|
||||||
class DomainNameNotFound(NotFoundException):
|
class DomainNameNotFound(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid domain name identifier specified")
|
super().__init__("Invalid domain name identifier specified")
|
||||||
|
|
||||||
|
|
||||||
class InvalidRestApiId(BadRequestException):
|
class InvalidRestApiId(BadRequestException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("No Rest API Id specified")
|
super().__init__("No Rest API Id specified")
|
||||||
|
|
||||||
|
|
||||||
class InvalidModelName(BadRequestException):
|
class InvalidModelName(BadRequestException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("No Model Name specified")
|
super().__init__("No Model Name specified")
|
||||||
|
|
||||||
|
|
||||||
class RestAPINotFound(NotFoundException):
|
class RestAPINotFound(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid Rest API Id specified")
|
super().__init__("Invalid Rest API Id specified")
|
||||||
|
|
||||||
|
|
||||||
class RequestValidatorNotFound(BadRequestException):
|
class RequestValidatorNotFound(BadRequestException):
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid Request Validator Id specified")
|
super().__init__("Invalid Request Validator Id specified")
|
||||||
|
|
||||||
|
|
||||||
class ModelNotFound(NotFoundException):
|
class ModelNotFound(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid Model Name specified")
|
super().__init__("Invalid Model Name specified")
|
||||||
|
|
||||||
|
|
||||||
class ApiKeyValueMinLength(BadRequestException):
|
class ApiKeyValueMinLength(BadRequestException):
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("API Key value should be at least 20 characters")
|
super().__init__("API Key value should be at least 20 characters")
|
||||||
|
|
||||||
|
|
||||||
class MethodNotFoundException(NotFoundException):
|
class MethodNotFoundException(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid Method identifier specified")
|
super().__init__("Invalid Method identifier specified")
|
||||||
|
|
||||||
|
|
||||||
class InvalidBasePathException(BadRequestException):
|
class InvalidBasePathException(BadRequestException):
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
"API Gateway V1 doesn't support the slash character (/) in base path mappings. "
|
"API Gateway V1 doesn't support the slash character (/) in base path mappings. "
|
||||||
"To create a multi-level base path mapping, use API Gateway V2."
|
"To create a multi-level base path mapping, use API Gateway V2."
|
||||||
@ -222,64 +223,64 @@ class InvalidBasePathException(BadRequestException):
|
|||||||
|
|
||||||
|
|
||||||
class DeploymentNotFoundException(NotFoundException):
|
class DeploymentNotFoundException(NotFoundException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid Deployment identifier specified")
|
super().__init__("Invalid Deployment identifier specified")
|
||||||
|
|
||||||
|
|
||||||
class InvalidRestApiIdForBasePathMappingException(BadRequestException):
|
class InvalidRestApiIdForBasePathMappingException(BadRequestException):
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid REST API identifier specified")
|
super().__init__("Invalid REST API identifier specified")
|
||||||
|
|
||||||
|
|
||||||
class InvalidStageException(BadRequestException):
|
class InvalidStageException(BadRequestException):
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid stage identifier specified")
|
super().__init__("Invalid stage identifier specified")
|
||||||
|
|
||||||
|
|
||||||
class BasePathConflictException(ConflictException):
|
class BasePathConflictException(ConflictException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Base path already exists for this domain name")
|
super().__init__("Base path already exists for this domain name")
|
||||||
|
|
||||||
|
|
||||||
class BasePathNotFoundException(NotFoundException):
|
class BasePathNotFoundException(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid base path mapping identifier specified")
|
super().__init__("Invalid base path mapping identifier specified")
|
||||||
|
|
||||||
|
|
||||||
class ResourceIdNotFoundException(NotFoundException):
|
class ResourceIdNotFoundException(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("Invalid resource identifier specified")
|
super().__init__("Invalid resource identifier specified")
|
||||||
|
|
||||||
|
|
||||||
class VpcLinkNotFound(NotFoundException):
|
class VpcLinkNotFound(NotFoundException):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("VPCLink not found")
|
super().__init__("VPCLink not found")
|
||||||
|
|
||||||
|
|
||||||
class ValidationException(ApiGatewayException):
|
class ValidationException(ApiGatewayException):
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
def __init__(self, message):
|
def __init__(self, message: str):
|
||||||
super().__init__("ValidationException", message)
|
super().__init__("ValidationException", message)
|
||||||
|
|
||||||
|
|
||||||
class StageStillActive(BadRequestException):
|
class StageStillActive(BadRequestException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
"Active stages pointing to this deployment must be moved or deleted"
|
"Active stages pointing to this deployment must be moved or deleted"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class GatewayResponseNotFound(NotFoundException):
|
class GatewayResponseNotFound(NotFoundException):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__("GatewayResponse not found")
|
super().__init__("GatewayResponse not found")
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
import abc
|
import abc
|
||||||
|
from typing import Tuple, Union
|
||||||
|
from requests.models import PreparedRequest
|
||||||
|
from ..models import Integration
|
||||||
|
|
||||||
|
|
||||||
class IntegrationParser:
|
class IntegrationParser:
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def invoke(self, request, integration):
|
def invoke(
|
||||||
|
self, request: PreparedRequest, integration: Integration
|
||||||
|
) -> Tuple[int, Union[str, bytes]]:
|
||||||
pass
|
pass
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
import requests
|
import requests
|
||||||
|
|
||||||
from . import IntegrationParser
|
from . import IntegrationParser
|
||||||
|
from ..models import Integration
|
||||||
|
from typing import Tuple, Union
|
||||||
|
|
||||||
|
|
||||||
class TypeAwsParser(IntegrationParser):
|
class TypeAwsParser(IntegrationParser):
|
||||||
def invoke(self, request, integration):
|
def invoke(
|
||||||
|
self, request: requests.PreparedRequest, integration: Integration
|
||||||
|
) -> Tuple[int, Union[str, bytes]]:
|
||||||
# integration.uri = arn:aws:apigateway:{region}:{subdomain.service|service}:path|action/{service_api}
|
# integration.uri = arn:aws:apigateway:{region}:{subdomain.service|service}:path|action/{service_api}
|
||||||
# example value = 'arn:aws:apigateway:us-west-2:dynamodb:action/PutItem'
|
# example value = 'arn:aws:apigateway:us-west-2:dynamodb:action/PutItem'
|
||||||
try:
|
try:
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import requests
|
import requests
|
||||||
|
from typing import Tuple, Union
|
||||||
|
|
||||||
from . import IntegrationParser
|
from . import IntegrationParser
|
||||||
|
from ..models import Integration
|
||||||
|
|
||||||
|
|
||||||
class TypeHttpParser(IntegrationParser):
|
class TypeHttpParser(IntegrationParser):
|
||||||
@ -8,7 +10,9 @@ class TypeHttpParser(IntegrationParser):
|
|||||||
Parse invocations to a APIGateway resource with integration type HTTP
|
Parse invocations to a APIGateway resource with integration type HTTP
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def invoke(self, request, integration):
|
def invoke(
|
||||||
|
self, request: requests.PreparedRequest, integration: Integration
|
||||||
|
) -> Tuple[int, Union[str, bytes]]:
|
||||||
uri = integration["uri"]
|
uri = integration["uri"]
|
||||||
requests_func = getattr(requests, integration["httpMethod"].lower())
|
requests_func = getattr(requests, integration["httpMethod"].lower())
|
||||||
response = requests_func(uri)
|
response = requests_func(uri)
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
import requests
|
||||||
|
from typing import Tuple, Union
|
||||||
from . import IntegrationParser
|
from . import IntegrationParser
|
||||||
|
from ..models import Integration
|
||||||
|
|
||||||
|
|
||||||
class TypeUnknownParser(IntegrationParser):
|
class TypeUnknownParser(IntegrationParser):
|
||||||
@ -6,6 +9,8 @@ class TypeUnknownParser(IntegrationParser):
|
|||||||
Parse invocations to a APIGateway resource with an unknown integration type
|
Parse invocations to a APIGateway resource with an unknown integration type
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def invoke(self, request, integration):
|
def invoke(
|
||||||
|
self, request: requests.PreparedRequest, integration: Integration
|
||||||
|
) -> Tuple[int, Union[str, bytes]]:
|
||||||
_type = integration["type"]
|
_type = integration["type"]
|
||||||
raise NotImplementedError("The {0} type has not been implemented".format(_type))
|
raise NotImplementedError("The {0} type has not been implemented".format(_type))
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,10 @@
|
|||||||
import json
|
import json
|
||||||
|
from typing import Any, Dict, List, Tuple
|
||||||
from urllib.parse import unquote
|
from urllib.parse import unquote
|
||||||
|
|
||||||
from moto.utilities.utils import merge_multiple_dicts
|
from moto.utilities.utils import merge_multiple_dicts
|
||||||
from moto.core.responses import BaseResponse
|
from moto.core.responses import BaseResponse
|
||||||
from .models import apigateway_backends
|
from .models import apigateway_backends, APIGatewayBackend
|
||||||
from .utils import deserialize_body
|
from .utils import deserialize_body
|
||||||
from .exceptions import InvalidRequestInput
|
from .exceptions import InvalidRequestInput
|
||||||
|
|
||||||
@ -11,21 +12,23 @@ API_KEY_SOURCES = ["AUTHORIZER", "HEADER"]
|
|||||||
AUTHORIZER_TYPES = ["TOKEN", "REQUEST", "COGNITO_USER_POOLS"]
|
AUTHORIZER_TYPES = ["TOKEN", "REQUEST", "COGNITO_USER_POOLS"]
|
||||||
ENDPOINT_CONFIGURATION_TYPES = ["PRIVATE", "EDGE", "REGIONAL"]
|
ENDPOINT_CONFIGURATION_TYPES = ["PRIVATE", "EDGE", "REGIONAL"]
|
||||||
|
|
||||||
|
RESPONSE_TYPE = Tuple[int, Dict[str, str], str]
|
||||||
|
|
||||||
|
|
||||||
class APIGatewayResponse(BaseResponse):
|
class APIGatewayResponse(BaseResponse):
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
super().__init__(service_name="apigateway")
|
super().__init__(service_name="apigateway")
|
||||||
|
|
||||||
def error(self, type_, message, status=400):
|
def error(self, type_: str, message: str, status: int = 400) -> RESPONSE_TYPE:
|
||||||
headers = self.response_headers or {}
|
headers = self.response_headers or {}
|
||||||
headers["X-Amzn-Errortype"] = type_
|
headers["X-Amzn-Errortype"] = type_
|
||||||
return (status, headers, json.dumps({"__type": type_, "message": message}))
|
return (status, headers, json.dumps({"__type": type_, "message": message}))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def backend(self):
|
def backend(self) -> APIGatewayBackend:
|
||||||
return apigateway_backends[self.current_account][self.region]
|
return apigateway_backends[self.current_account][self.region]
|
||||||
|
|
||||||
def __validate_api_key_source(self, api_key_source):
|
def __validate_api_key_source(self, api_key_source: str) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
if api_key_source and api_key_source not in API_KEY_SOURCES:
|
if api_key_source and api_key_source not in API_KEY_SOURCES:
|
||||||
return self.error(
|
return self.error(
|
||||||
"ValidationException",
|
"ValidationException",
|
||||||
@ -37,7 +40,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
).format(api_key_source=api_key_source),
|
).format(api_key_source=api_key_source),
|
||||||
)
|
)
|
||||||
|
|
||||||
def __validate_endpoint_configuration(self, endpoint_configuration):
|
def __validate_endpoint_configuration(self, endpoint_configuration: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
if endpoint_configuration and "types" in endpoint_configuration:
|
if endpoint_configuration and "types" in endpoint_configuration:
|
||||||
invalid_types = list(
|
invalid_types = list(
|
||||||
set(endpoint_configuration["types"]) - set(ENDPOINT_CONFIGURATION_TYPES)
|
set(endpoint_configuration["types"]) - set(ENDPOINT_CONFIGURATION_TYPES)
|
||||||
@ -53,7 +56,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
).format(endpoint_type=invalid_types[0]),
|
).format(endpoint_type=invalid_types[0]),
|
||||||
)
|
)
|
||||||
|
|
||||||
def restapis(self, request, full_url, headers):
|
def restapis(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
if self.method == "GET":
|
if self.method == "GET":
|
||||||
@ -62,7 +65,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
elif self.method == "POST":
|
elif self.method == "POST":
|
||||||
api_doc = deserialize_body(self.body)
|
api_doc = deserialize_body(self.body)
|
||||||
if api_doc:
|
if api_doc:
|
||||||
fail_on_warnings = self._get_bool_param("failonwarnings")
|
fail_on_warnings = self._get_bool_param("failonwarnings") or False
|
||||||
rest_api = self.backend.import_rest_api(api_doc, fail_on_warnings)
|
rest_api = self.backend.import_rest_api(api_doc, fail_on_warnings)
|
||||||
|
|
||||||
return 200, {}, json.dumps(rest_api.to_dict())
|
return 200, {}, json.dumps(rest_api.to_dict())
|
||||||
@ -97,14 +100,16 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
|
|
||||||
return 200, {}, json.dumps(rest_api.to_dict())
|
return 200, {}, json.dumps(rest_api.to_dict())
|
||||||
|
|
||||||
def __validte_rest_patch_operations(self, patch_operations):
|
def __validte_rest_patch_operations(self, patch_operations: List[Dict[str, str]]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
for op in patch_operations:
|
for op in patch_operations:
|
||||||
path = op["path"]
|
path = op["path"]
|
||||||
if "apiKeySource" in path:
|
if "apiKeySource" in path:
|
||||||
value = op["value"]
|
value = op["value"]
|
||||||
return self.__validate_api_key_source(value)
|
return self.__validate_api_key_source(value)
|
||||||
|
|
||||||
def restapis_individual(self, request, full_url, headers):
|
def restapis_individual(
|
||||||
|
self, request: Any, full_url: str, headers: Dict[str, str]
|
||||||
|
) -> RESPONSE_TYPE:
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
function_id = self.path.replace("/restapis/", "", 1).split("/")[0]
|
function_id = self.path.replace("/restapis/", "", 1).split("/")[0]
|
||||||
|
|
||||||
@ -114,12 +119,12 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
rest_api = self.backend.delete_rest_api(function_id)
|
rest_api = self.backend.delete_rest_api(function_id)
|
||||||
elif self.method == "PUT":
|
elif self.method == "PUT":
|
||||||
mode = self._get_param("mode", "merge")
|
mode = self._get_param("mode", "merge")
|
||||||
fail_on_warnings = self._get_bool_param("failonwarnings", False)
|
fail_on_warnings = self._get_bool_param("failonwarnings") or False
|
||||||
|
|
||||||
api_doc = deserialize_body(self.body)
|
api_doc = deserialize_body(self.body)
|
||||||
|
|
||||||
rest_api = self.backend.put_rest_api(
|
rest_api = self.backend.put_rest_api(
|
||||||
function_id, api_doc, mode, fail_on_warnings
|
function_id, api_doc, mode=mode, fail_on_warnings=fail_on_warnings
|
||||||
)
|
)
|
||||||
elif self.method == "PATCH":
|
elif self.method == "PATCH":
|
||||||
patch_operations = self._get_param("patchOperations")
|
patch_operations = self._get_param("patchOperations")
|
||||||
@ -130,7 +135,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
|
|
||||||
return 200, {}, json.dumps(rest_api.to_dict())
|
return 200, {}, json.dumps(rest_api.to_dict())
|
||||||
|
|
||||||
def resources(self, request, full_url, headers):
|
def resources(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
function_id = self.path.replace("/restapis/", "", 1).split("/")[0]
|
function_id = self.path.replace("/restapis/", "", 1).split("/")[0]
|
||||||
|
|
||||||
@ -142,7 +147,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
json.dumps({"item": [resource.to_dict() for resource in resources]}),
|
json.dumps({"item": [resource.to_dict() for resource in resources]}),
|
||||||
)
|
)
|
||||||
|
|
||||||
def gateway_response(self, request, full_url, headers):
|
def gateway_response(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
if request.method == "PUT":
|
if request.method == "PUT":
|
||||||
return self.put_gateway_response()
|
return self.put_gateway_response()
|
||||||
@ -151,12 +156,12 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
elif request.method == "DELETE":
|
elif request.method == "DELETE":
|
||||||
return self.delete_gateway_response()
|
return self.delete_gateway_response()
|
||||||
|
|
||||||
def gateway_responses(self, request, full_url, headers):
|
def gateway_responses(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
return self.get_gateway_responses()
|
return self.get_gateway_responses()
|
||||||
|
|
||||||
def resource_individual(self, request, full_url, headers):
|
def resource_individual(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
function_id = self.path.replace("/restapis/", "", 1).split("/")[0]
|
function_id = self.path.replace("/restapis/", "", 1).split("/")[0]
|
||||||
resource_id = self.path.split("/")[-1]
|
resource_id = self.path.split("/")[-1]
|
||||||
@ -172,7 +177,9 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
resource = self.backend.delete_resource(function_id, resource_id)
|
resource = self.backend.delete_resource(function_id, resource_id)
|
||||||
return 202, {}, json.dumps(resource.to_dict())
|
return 202, {}, json.dumps(resource.to_dict())
|
||||||
|
|
||||||
def resource_methods(self, request, full_url, headers):
|
def resource_methods(
|
||||||
|
self, request: Any, full_url: str, headers: Dict[str, str]
|
||||||
|
) -> RESPONSE_TYPE:
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
function_id = url_path_parts[2]
|
function_id = url_path_parts[2]
|
||||||
@ -210,15 +217,11 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
self.backend.delete_method(function_id, resource_id, method_type)
|
self.backend.delete_method(function_id, resource_id, method_type)
|
||||||
return 204, {}, ""
|
return 204, {}, ""
|
||||||
|
|
||||||
elif self.method == "PATCH":
|
|
||||||
patch_operations = self._get_param("patchOperations")
|
|
||||||
self.backend.update_method(
|
|
||||||
function_id, resource_id, method_type, patch_operations
|
|
||||||
)
|
|
||||||
|
|
||||||
return 200, {}, ""
|
return 200, {}, ""
|
||||||
|
|
||||||
def resource_method_responses(self, request, full_url, headers):
|
def resource_method_responses(
|
||||||
|
self, request: Any, full_url: str, headers: Dict[str, str]
|
||||||
|
) -> RESPONSE_TYPE:
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
function_id = url_path_parts[2]
|
function_id = url_path_parts[2]
|
||||||
@ -248,15 +251,9 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
function_id, resource_id, method_type, response_code
|
function_id, resource_id, method_type, response_code
|
||||||
)
|
)
|
||||||
return 204, {}, json.dumps(method_response)
|
return 204, {}, json.dumps(method_response)
|
||||||
elif self.method == "PATCH":
|
|
||||||
patch_operations = self._get_param("patchOperations")
|
|
||||||
method_response = self.backend.update_method_response(
|
|
||||||
function_id, resource_id, method_type, response_code, patch_operations
|
|
||||||
)
|
|
||||||
return 201, {}, json.dumps(method_response)
|
|
||||||
raise Exception('Unexpected HTTP method "%s"' % self.method)
|
raise Exception('Unexpected HTTP method "%s"' % self.method)
|
||||||
|
|
||||||
def restapis_authorizers(self, request, full_url, headers):
|
def restapis_authorizers(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
restapi_id = url_path_parts[2]
|
restapi_id = url_path_parts[2]
|
||||||
@ -306,7 +303,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
authorizers = self.backend.get_authorizers(restapi_id)
|
authorizers = self.backend.get_authorizers(restapi_id)
|
||||||
return 200, {}, json.dumps({"item": authorizers})
|
return 200, {}, json.dumps({"item": authorizers})
|
||||||
|
|
||||||
def request_validators(self, request, full_url, headers):
|
def request_validators(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
restapi_id = url_path_parts[2]
|
restapi_id = url_path_parts[2]
|
||||||
@ -326,7 +323,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
return 201, {}, json.dumps(validator)
|
return 201, {}, json.dumps(validator)
|
||||||
|
|
||||||
def request_validator_individual(self, request, full_url, headers):
|
def request_validator_individual(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
restapi_id = url_path_parts[2]
|
restapi_id = url_path_parts[2]
|
||||||
@ -345,7 +342,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
return 200, {}, json.dumps(validator)
|
return 200, {}, json.dumps(validator)
|
||||||
|
|
||||||
def authorizers(self, request, full_url, headers):
|
def authorizers(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
restapi_id = url_path_parts[2]
|
restapi_id = url_path_parts[2]
|
||||||
@ -364,7 +361,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
self.backend.delete_authorizer(restapi_id, authorizer_id)
|
self.backend.delete_authorizer(restapi_id, authorizer_id)
|
||||||
return 202, {}, "{}"
|
return 202, {}, "{}"
|
||||||
|
|
||||||
def restapis_stages(self, request, full_url, headers):
|
def restapis_stages(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
function_id = url_path_parts[2]
|
function_id = url_path_parts[2]
|
||||||
@ -395,7 +392,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
stages = self.backend.get_stages(function_id)
|
stages = self.backend.get_stages(function_id)
|
||||||
return 200, {}, json.dumps({"item": stages})
|
return 200, {}, json.dumps({"item": stages})
|
||||||
|
|
||||||
def restapis_stages_tags(self, request, full_url, headers):
|
def restapis_stages_tags(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
function_id = url_path_parts[4]
|
function_id = url_path_parts[4]
|
||||||
@ -408,12 +405,12 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
return 200, {}, json.dumps({"item": tags})
|
return 200, {}, json.dumps({"item": tags})
|
||||||
if self.method == "DELETE":
|
if self.method == "DELETE":
|
||||||
stage = self.backend.get_stage(function_id, stage_name)
|
stage = self.backend.get_stage(function_id, stage_name)
|
||||||
for tag in stage.get("tags").copy():
|
for tag in stage.get("tags", {}).copy():
|
||||||
if tag in self.querystring.get("tagKeys"):
|
if tag in (self.querystring.get("tagKeys") or {}):
|
||||||
stage["tags"].pop(tag, None)
|
stage["tags"].pop(tag, None)
|
||||||
return 200, {}, json.dumps({"item": ""})
|
return 200, {}, json.dumps({"item": ""})
|
||||||
|
|
||||||
def stages(self, request, full_url, headers):
|
def stages(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
function_id = url_path_parts[2]
|
function_id = url_path_parts[2]
|
||||||
@ -432,15 +429,13 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
self.backend.delete_stage(function_id, stage_name)
|
self.backend.delete_stage(function_id, stage_name)
|
||||||
return 202, {}, "{}"
|
return 202, {}, "{}"
|
||||||
|
|
||||||
def integrations(self, request, full_url, headers):
|
def integrations(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
function_id = url_path_parts[2]
|
function_id = url_path_parts[2]
|
||||||
resource_id = url_path_parts[4]
|
resource_id = url_path_parts[4]
|
||||||
method_type = url_path_parts[6]
|
method_type = url_path_parts[6]
|
||||||
|
|
||||||
integration_response = {}
|
|
||||||
|
|
||||||
if self.method == "GET":
|
if self.method == "GET":
|
||||||
integration_response = self.backend.get_integration(
|
integration_response = self.backend.get_integration(
|
||||||
function_id, resource_id, method_type
|
function_id, resource_id, method_type
|
||||||
@ -484,7 +479,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
return 204, {}, json.dumps(integration_response)
|
return 204, {}, json.dumps(integration_response)
|
||||||
|
|
||||||
def integration_responses(self, request, full_url, headers):
|
def integration_responses(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
function_id = url_path_parts[2]
|
function_id = url_path_parts[2]
|
||||||
@ -520,7 +515,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
return 204, {}, json.dumps(integration_response)
|
return 204, {}, json.dumps(integration_response)
|
||||||
|
|
||||||
def deployments(self, request, full_url, headers):
|
def deployments(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
function_id = self.path.replace("/restapis/", "", 1).split("/")[0]
|
function_id = self.path.replace("/restapis/", "", 1).split("/")[0]
|
||||||
|
|
||||||
@ -536,7 +531,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
return 201, {}, json.dumps(deployment)
|
return 201, {}, json.dumps(deployment)
|
||||||
|
|
||||||
def individual_deployment(self, request, full_url, headers):
|
def individual_deployment(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
function_id = url_path_parts[2]
|
function_id = url_path_parts[2]
|
||||||
@ -549,7 +544,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
deployment = self.backend.delete_deployment(function_id, deployment_id)
|
deployment = self.backend.delete_deployment(function_id, deployment_id)
|
||||||
return 202, {}, json.dumps(deployment)
|
return 202, {}, json.dumps(deployment)
|
||||||
|
|
||||||
def apikeys(self, request, full_url, headers):
|
def apikeys(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
if self.method == "POST":
|
if self.method == "POST":
|
||||||
@ -557,19 +552,20 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
return 201, {}, json.dumps(apikey_response)
|
return 201, {}, json.dumps(apikey_response)
|
||||||
|
|
||||||
elif self.method == "GET":
|
elif self.method == "GET":
|
||||||
include_values = self._get_bool_param("includeValues")
|
include_values = self._get_bool_param("includeValues") or False
|
||||||
apikeys_response = self.backend.get_api_keys(include_values=include_values)
|
apikeys_response = self.backend.get_api_keys(include_values=include_values)
|
||||||
return 200, {}, json.dumps({"item": apikeys_response})
|
return 200, {}, json.dumps({"item": apikeys_response})
|
||||||
|
|
||||||
def apikey_individual(self, request, full_url, headers):
|
def apikey_individual(
|
||||||
|
self, request: Any, full_url: str, headers: Dict[str, str]
|
||||||
|
) -> RESPONSE_TYPE:
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
apikey = url_path_parts[2]
|
apikey = url_path_parts[2]
|
||||||
|
|
||||||
status_code = 200
|
|
||||||
if self.method == "GET":
|
if self.method == "GET":
|
||||||
include_value = self._get_bool_param("includeValue")
|
include_value = self._get_bool_param("includeValue") or False
|
||||||
apikey_response = self.backend.get_api_key(
|
apikey_response = self.backend.get_api_key(
|
||||||
apikey, include_value=include_value
|
apikey, include_value=include_value
|
||||||
)
|
)
|
||||||
@ -577,12 +573,12 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
patch_operations = self._get_param("patchOperations")
|
patch_operations = self._get_param("patchOperations")
|
||||||
apikey_response = self.backend.update_api_key(apikey, patch_operations)
|
apikey_response = self.backend.update_api_key(apikey, patch_operations)
|
||||||
elif self.method == "DELETE":
|
elif self.method == "DELETE":
|
||||||
apikey_response = self.backend.delete_api_key(apikey)
|
self.backend.delete_api_key(apikey)
|
||||||
status_code = 202
|
return 202, {}, "{}"
|
||||||
|
|
||||||
return status_code, {}, json.dumps(apikey_response)
|
return 200, {}, json.dumps(apikey_response)
|
||||||
|
|
||||||
def usage_plans(self, request, full_url, headers):
|
def usage_plans(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
if self.method == "POST":
|
if self.method == "POST":
|
||||||
usage_plan_response = self.backend.create_usage_plan(json.loads(self.body))
|
usage_plan_response = self.backend.create_usage_plan(json.loads(self.body))
|
||||||
@ -592,7 +588,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
usage_plans_response = self.backend.get_usage_plans(api_key_id=api_key_id)
|
usage_plans_response = self.backend.get_usage_plans(api_key_id=api_key_id)
|
||||||
return 200, {}, json.dumps({"item": usage_plans_response})
|
return 200, {}, json.dumps({"item": usage_plans_response})
|
||||||
|
|
||||||
def usage_plan_individual(self, request, full_url, headers):
|
def usage_plan_individual(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
@ -602,8 +598,8 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
usage_plan_response = self.backend.get_usage_plan(usage_plan)
|
usage_plan_response = self.backend.get_usage_plan(usage_plan)
|
||||||
return 200, {}, json.dumps(usage_plan_response)
|
return 200, {}, json.dumps(usage_plan_response)
|
||||||
elif self.method == "DELETE":
|
elif self.method == "DELETE":
|
||||||
usage_plan_response = self.backend.delete_usage_plan(usage_plan)
|
self.backend.delete_usage_plan(usage_plan)
|
||||||
return 202, {}, json.dumps(usage_plan_response)
|
return 202, {}, "{}"
|
||||||
elif self.method == "PATCH":
|
elif self.method == "PATCH":
|
||||||
patch_operations = self._get_param("patchOperations")
|
patch_operations = self._get_param("patchOperations")
|
||||||
usage_plan_response = self.backend.update_usage_plan(
|
usage_plan_response = self.backend.update_usage_plan(
|
||||||
@ -611,7 +607,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
return 200, {}, json.dumps(usage_plan_response)
|
return 200, {}, json.dumps(usage_plan_response)
|
||||||
|
|
||||||
def usage_plan_keys(self, request, full_url, headers):
|
def usage_plan_keys(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
@ -626,7 +622,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
usage_plans_response = self.backend.get_usage_plan_keys(usage_plan_id)
|
usage_plans_response = self.backend.get_usage_plan_keys(usage_plan_id)
|
||||||
return 200, {}, json.dumps({"item": usage_plans_response})
|
return 200, {}, json.dumps({"item": usage_plans_response})
|
||||||
|
|
||||||
def usage_plan_key_individual(self, request, full_url, headers):
|
def usage_plan_key_individual(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
@ -637,12 +633,10 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
usage_plan_response = self.backend.get_usage_plan_key(usage_plan_id, key_id)
|
usage_plan_response = self.backend.get_usage_plan_key(usage_plan_id, key_id)
|
||||||
return 200, {}, json.dumps(usage_plan_response)
|
return 200, {}, json.dumps(usage_plan_response)
|
||||||
elif self.method == "DELETE":
|
elif self.method == "DELETE":
|
||||||
usage_plan_response = self.backend.delete_usage_plan_key(
|
self.backend.delete_usage_plan_key(usage_plan_id, key_id)
|
||||||
usage_plan_id, key_id
|
return 202, {}, "{}"
|
||||||
)
|
|
||||||
return 202, {}, json.dumps(usage_plan_response)
|
|
||||||
|
|
||||||
def domain_names(self, request, full_url, headers):
|
def domain_names(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
if self.method == "GET":
|
if self.method == "GET":
|
||||||
@ -661,7 +655,6 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
regional_certificate_arn = self._get_param("regionalCertificateArn")
|
regional_certificate_arn = self._get_param("regionalCertificateArn")
|
||||||
endpoint_configuration = self._get_param("endpointConfiguration")
|
endpoint_configuration = self._get_param("endpointConfiguration")
|
||||||
security_policy = self._get_param("securityPolicy")
|
security_policy = self._get_param("securityPolicy")
|
||||||
generate_cli_skeleton = self._get_param("generateCliSkeleton")
|
|
||||||
domain_name_resp = self.backend.create_domain_name(
|
domain_name_resp = self.backend.create_domain_name(
|
||||||
domain_name,
|
domain_name,
|
||||||
certificate_name,
|
certificate_name,
|
||||||
@ -674,35 +667,31 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
regional_certificate_arn,
|
regional_certificate_arn,
|
||||||
endpoint_configuration,
|
endpoint_configuration,
|
||||||
security_policy,
|
security_policy,
|
||||||
generate_cli_skeleton,
|
|
||||||
)
|
)
|
||||||
return 201, {}, json.dumps(domain_name_resp)
|
return 201, {}, json.dumps(domain_name_resp)
|
||||||
|
|
||||||
def domain_name_induvidual(self, request, full_url, headers):
|
def domain_name_induvidual(
|
||||||
|
self, request: Any, full_url: str, headers: Dict[str, str]
|
||||||
|
) -> RESPONSE_TYPE:
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
domain_name = url_path_parts[2]
|
domain_name = url_path_parts[2]
|
||||||
domain_names = {}
|
|
||||||
|
|
||||||
if self.method == "GET":
|
if self.method == "GET":
|
||||||
if domain_name is not None:
|
if domain_name is not None:
|
||||||
domain_names = self.backend.get_domain_name(domain_name)
|
domain_names = self.backend.get_domain_name(domain_name)
|
||||||
return 200, {}, json.dumps(domain_names)
|
return 200, {}, json.dumps(domain_names)
|
||||||
|
return 200, {}, "{}"
|
||||||
elif self.method == "DELETE":
|
elif self.method == "DELETE":
|
||||||
if domain_name is not None:
|
if domain_name is not None:
|
||||||
self.backend.delete_domain_name(domain_name)
|
self.backend.delete_domain_name(domain_name)
|
||||||
return 202, {}, json.dumps({})
|
return 202, {}, json.dumps({})
|
||||||
elif self.method == "PATCH":
|
|
||||||
if domain_name is not None:
|
|
||||||
patch_operations = self._get_param("patchOperations")
|
|
||||||
self.backend.update_domain_name(domain_name, patch_operations)
|
|
||||||
return 200, {}, json.dumps(domain_name)
|
|
||||||
else:
|
else:
|
||||||
msg = 'Method "%s" for API GW domain names not implemented' % self.method
|
msg = 'Method "%s" for API GW domain names not implemented' % self.method
|
||||||
return 404, {}, json.dumps({"error": msg})
|
return 404, {}, json.dumps({"error": msg})
|
||||||
|
|
||||||
def models(self, request, full_url, headers):
|
def models(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
rest_api_id = self.path.replace("/restapis/", "", 1).split("/")[0]
|
rest_api_id = self.path.replace("/restapis/", "", 1).split("/")[0]
|
||||||
|
|
||||||
@ -715,30 +704,29 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
description = self._get_param("description")
|
description = self._get_param("description")
|
||||||
schema = self._get_param("schema")
|
schema = self._get_param("schema")
|
||||||
content_type = self._get_param("contentType")
|
content_type = self._get_param("contentType")
|
||||||
cli_input_json = self._get_param("cliInputJson")
|
|
||||||
generate_cli_skeleton = self._get_param("generateCliSkeleton")
|
|
||||||
model = self.backend.create_model(
|
model = self.backend.create_model(
|
||||||
rest_api_id,
|
rest_api_id,
|
||||||
name,
|
name,
|
||||||
content_type,
|
content_type,
|
||||||
description,
|
description,
|
||||||
schema,
|
schema,
|
||||||
cli_input_json,
|
|
||||||
generate_cli_skeleton,
|
|
||||||
)
|
)
|
||||||
return 201, {}, json.dumps(model)
|
return 201, {}, json.dumps(model)
|
||||||
|
|
||||||
def model_induvidual(self, request, full_url, headers):
|
def model_induvidual(
|
||||||
|
self, request: Any, full_url: str, headers: Dict[str, str]
|
||||||
|
) -> RESPONSE_TYPE:
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
rest_api_id = url_path_parts[2]
|
rest_api_id = url_path_parts[2]
|
||||||
model_name = url_path_parts[4]
|
model_name = url_path_parts[4]
|
||||||
model_info = {}
|
|
||||||
if self.method == "GET":
|
if self.method == "GET":
|
||||||
model_info = self.backend.get_model(rest_api_id, model_name)
|
model_info = self.backend.get_model(rest_api_id, model_name)
|
||||||
return 200, {}, json.dumps(model_info)
|
return 200, {}, json.dumps(model_info)
|
||||||
|
return 200, {}, "{}"
|
||||||
|
|
||||||
def base_path_mappings(self, request, full_url, headers):
|
def base_path_mappings(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
@ -757,7 +745,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
return 201, {}, json.dumps(base_path_mapping_resp)
|
return 201, {}, json.dumps(base_path_mapping_resp)
|
||||||
|
|
||||||
def base_path_mapping_individual(self, request, full_url, headers):
|
def base_path_mapping_individual(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
|
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
@ -780,7 +768,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
return 200, {}, json.dumps(base_path_mapping)
|
return 200, {}, json.dumps(base_path_mapping)
|
||||||
|
|
||||||
def vpc_link(self, request, full_url, headers):
|
def vpc_link(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
url_path_parts = self.path.split("/")
|
url_path_parts = self.path.split("/")
|
||||||
vpc_link_id = url_path_parts[-1]
|
vpc_link_id = url_path_parts[-1]
|
||||||
@ -792,7 +780,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
vpc_link = self.backend.get_vpc_link(vpc_link_id=vpc_link_id)
|
vpc_link = self.backend.get_vpc_link(vpc_link_id=vpc_link_id)
|
||||||
return 200, {}, json.dumps(vpc_link)
|
return 200, {}, json.dumps(vpc_link)
|
||||||
|
|
||||||
def vpc_links(self, request, full_url, headers):
|
def vpc_links(self, request: Any, full_url: str, headers: Dict[str, str]) -> RESPONSE_TYPE: # type: ignore[return]
|
||||||
self.setup_class(request, full_url, headers)
|
self.setup_class(request, full_url, headers)
|
||||||
|
|
||||||
if self.method == "GET":
|
if self.method == "GET":
|
||||||
@ -808,7 +796,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
return 202, {}, json.dumps(vpc_link)
|
return 202, {}, json.dumps(vpc_link)
|
||||||
|
|
||||||
def put_gateway_response(self):
|
def put_gateway_response(self) -> RESPONSE_TYPE:
|
||||||
rest_api_id = self.path.split("/")[-3]
|
rest_api_id = self.path.split("/")[-3]
|
||||||
response_type = self.path.split("/")[-1]
|
response_type = self.path.split("/")[-1]
|
||||||
params = json.loads(self.body)
|
params = json.loads(self.body)
|
||||||
@ -824,7 +812,7 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
return 201, {}, json.dumps(response)
|
return 201, {}, json.dumps(response)
|
||||||
|
|
||||||
def get_gateway_response(self):
|
def get_gateway_response(self) -> RESPONSE_TYPE:
|
||||||
rest_api_id = self.path.split("/")[-3]
|
rest_api_id = self.path.split("/")[-3]
|
||||||
response_type = self.path.split("/")[-1]
|
response_type = self.path.split("/")[-1]
|
||||||
response = self.backend.get_gateway_response(
|
response = self.backend.get_gateway_response(
|
||||||
@ -832,12 +820,12 @@ class APIGatewayResponse(BaseResponse):
|
|||||||
)
|
)
|
||||||
return 200, {}, json.dumps(response)
|
return 200, {}, json.dumps(response)
|
||||||
|
|
||||||
def get_gateway_responses(self):
|
def get_gateway_responses(self) -> RESPONSE_TYPE:
|
||||||
rest_api_id = self.path.split("/")[-2]
|
rest_api_id = self.path.split("/")[-2]
|
||||||
responses = self.backend.get_gateway_responses(rest_api_id=rest_api_id)
|
responses = self.backend.get_gateway_responses(rest_api_id=rest_api_id)
|
||||||
return 200, {}, json.dumps(dict(item=responses))
|
return 200, {}, json.dumps(dict(item=responses))
|
||||||
|
|
||||||
def delete_gateway_response(self):
|
def delete_gateway_response(self) -> RESPONSE_TYPE:
|
||||||
rest_api_id = self.path.split("/")[-3]
|
rest_api_id = self.path.split("/")[-3]
|
||||||
response_type = self.path.split("/")[-1]
|
response_type = self.path.split("/")[-1]
|
||||||
self.backend.delete_gateway_response(
|
self.backend.delete_gateway_response(
|
||||||
|
@ -2,15 +2,16 @@ import string
|
|||||||
import json
|
import json
|
||||||
import yaml
|
import yaml
|
||||||
from moto.moto_api._internal import mock_random as random
|
from moto.moto_api._internal import mock_random as random
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
|
||||||
def create_id():
|
def create_id() -> str:
|
||||||
size = 10
|
size = 10
|
||||||
chars = list(range(10)) + list(string.ascii_lowercase)
|
chars = list(range(10)) + list(string.ascii_lowercase)
|
||||||
return "".join(str(random.choice(chars)) for x in range(size))
|
return "".join(str(random.choice(chars)) for x in range(size))
|
||||||
|
|
||||||
|
|
||||||
def deserialize_body(body):
|
def deserialize_body(body: str) -> Dict[str, Any]:
|
||||||
try:
|
try:
|
||||||
api_doc = json.loads(body)
|
api_doc = json.loads(body)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
@ -19,8 +20,8 @@ def deserialize_body(body):
|
|||||||
if "openapi" in api_doc or "swagger" in api_doc:
|
if "openapi" in api_doc or "swagger" in api_doc:
|
||||||
return api_doc
|
return api_doc
|
||||||
|
|
||||||
return None
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def to_path(prop):
|
def to_path(prop: str) -> str:
|
||||||
return "/" + prop
|
return "/" + prop
|
||||||
|
@ -29,7 +29,7 @@ class CloudFormationModel(BaseModel):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def has_cfn_attr(cls, attr):
|
def has_cfn_attr(cls, attr): # pylint: disable=unused-argument
|
||||||
# Used for validation
|
# Used for validation
|
||||||
# If a template creates an Output for an attribute that does not exist, an error should be thrown
|
# If a template creates an Output for an attribute that does not exist, an error should be thrown
|
||||||
return True
|
return True
|
||||||
|
@ -186,7 +186,7 @@ def unix_time_millis(dt=None):
|
|||||||
return unix_time(dt) * 1000.0
|
return unix_time(dt) * 1000.0
|
||||||
|
|
||||||
|
|
||||||
def path_url(url):
|
def path_url(url: str) -> str:
|
||||||
parsed_url = urlparse(url)
|
parsed_url = urlparse(url)
|
||||||
path = parsed_url.path
|
path = parsed_url.path
|
||||||
if not path:
|
if not path:
|
||||||
|
@ -2,8 +2,8 @@ import json
|
|||||||
import hashlib
|
import hashlib
|
||||||
import pkgutil
|
import pkgutil
|
||||||
|
|
||||||
|
|
||||||
from collections.abc import MutableMapping
|
from collections.abc import MutableMapping
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
|
||||||
def str2bool(v):
|
def str2bool(v):
|
||||||
@ -23,7 +23,7 @@ def load_resource(package, resource, as_json=True):
|
|||||||
return json.loads(resource) if as_json else resource.decode("utf-8")
|
return json.loads(resource) if as_json else resource.decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
def merge_multiple_dicts(*args):
|
def merge_multiple_dicts(*args: Any) -> Dict[str, any]:
|
||||||
result = {}
|
result = {}
|
||||||
for d in args:
|
for d in args:
|
||||||
result.update(d)
|
result.update(d)
|
||||||
|
@ -18,9 +18,10 @@ disable = W,C,R,E
|
|||||||
enable = anomalous-backslash-in-string, arguments-renamed, dangerous-default-value, deprecated-module, function-redefined, import-self, redefined-builtin, redefined-outer-name, reimported, pointless-statement, super-with-arguments, unused-argument, unused-import, unused-variable, useless-else-on-loop, wildcard-import
|
enable = anomalous-backslash-in-string, arguments-renamed, dangerous-default-value, deprecated-module, function-redefined, import-self, redefined-builtin, redefined-outer-name, reimported, pointless-statement, super-with-arguments, unused-argument, unused-import, unused-variable, useless-else-on-loop, wildcard-import
|
||||||
|
|
||||||
[mypy]
|
[mypy]
|
||||||
exclude = tests
|
files= moto/acm,moto/amp,moto/apigateway,moto/applicationautoscaling/
|
||||||
show_column_numbers=True
|
show_column_numbers=True
|
||||||
show_error_codes = True
|
show_error_codes = True
|
||||||
|
disable_error_code=abstract
|
||||||
|
|
||||||
disallow_any_unimported=False
|
disallow_any_unimported=False
|
||||||
disallow_any_expr=False
|
disallow_any_expr=False
|
||||||
|
@ -842,9 +842,21 @@ def test_non_existent_authorizer():
|
|||||||
response = client.create_rest_api(name="my_api", description="this is my api")
|
response = client.create_rest_api(name="my_api", description="this is my api")
|
||||||
api_id = response["id"]
|
api_id = response["id"]
|
||||||
|
|
||||||
client.get_authorizer.when.called_with(
|
with pytest.raises(ClientError) as exc:
|
||||||
restApiId=api_id, authorizerId="xxx"
|
client.get_authorizer(restApiId=api_id, authorizerId="xxx")
|
||||||
).should.throw(ClientError)
|
err = exc.value.response["Error"]
|
||||||
|
err["Code"].should.equal("NotFoundException")
|
||||||
|
err["Message"].should.equal("Invalid Authorizer identifier specified")
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client.update_authorizer(
|
||||||
|
restApiId=api_id,
|
||||||
|
authorizerId="xxx",
|
||||||
|
patchOperations=[{"op": "add", "path": "/type", "value": "sth"}],
|
||||||
|
)
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
err["Code"].should.equal("NotFoundException")
|
||||||
|
err["Message"].should.equal("Invalid Authorizer identifier specified")
|
||||||
|
|
||||||
|
|
||||||
@mock_apigateway
|
@mock_apigateway
|
||||||
@ -1878,18 +1890,6 @@ def test_get_domain_name_unknown_domainname():
|
|||||||
ex.value.response["Error"]["Code"].should.equal("NotFoundException")
|
ex.value.response["Error"]["Code"].should.equal("NotFoundException")
|
||||||
|
|
||||||
|
|
||||||
@mock_apigateway
|
|
||||||
def test_update_domain_name_unknown_domainname():
|
|
||||||
client = boto3.client("apigateway", region_name="us-east-1")
|
|
||||||
with pytest.raises(ClientError) as ex:
|
|
||||||
client.update_domain_name(domainName="www.google.fr", patchOperations=[])
|
|
||||||
|
|
||||||
ex.value.response["Error"]["Message"].should.equal(
|
|
||||||
"Invalid domain name identifier specified"
|
|
||||||
)
|
|
||||||
ex.value.response["Error"]["Code"].should.equal("NotFoundException")
|
|
||||||
|
|
||||||
|
|
||||||
@mock_apigateway
|
@mock_apigateway
|
||||||
def test_delete_domain_name_unknown_domainname():
|
def test_delete_domain_name_unknown_domainname():
|
||||||
client = boto3.client("apigateway", region_name="us-east-1")
|
client = boto3.client("apigateway", region_name="us-east-1")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user