TechDebt: MyPy CostExplorer (#5593)
This commit is contained in:
		
							parent
							
								
									6f3b250fc7
								
							
						
					
					
						commit
						c0b581aa08
					
				@ -3,7 +3,7 @@ from moto.core.exceptions import JsonRESTError
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CostCategoryNotFound(JsonRESTError):
 | 
					class CostCategoryNotFound(JsonRESTError):
 | 
				
			||||||
    def __init__(self, ccd_id):
 | 
					    def __init__(self, ccd_id: str):
 | 
				
			||||||
        super().__init__(
 | 
					        super().__init__(
 | 
				
			||||||
            "ResourceNotFoundException", f"No Cost Categories found with ID {ccd_id}"
 | 
					            "ResourceNotFoundException", f"No Cost Categories found with ID {ccd_id}"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
				
			|||||||
@ -5,11 +5,18 @@ from moto.core import BaseBackend, BaseModel
 | 
				
			|||||||
from moto.core.utils import BackendDict
 | 
					from moto.core.utils import BackendDict
 | 
				
			||||||
from moto.utilities.tagging_service import TaggingService
 | 
					from moto.utilities.tagging_service import TaggingService
 | 
				
			||||||
from moto.moto_api._internal import mock_random
 | 
					from moto.moto_api._internal import mock_random
 | 
				
			||||||
 | 
					from typing import Any, Dict, List, Tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CostCategoryDefinition(BaseModel):
 | 
					class CostCategoryDefinition(BaseModel):
 | 
				
			||||||
    def __init__(
 | 
					    def __init__(
 | 
				
			||||||
        self, account_id, name, rule_version, rules, default_value, split_charge_rules
 | 
					        self,
 | 
				
			||||||
 | 
					        account_id: str,
 | 
				
			||||||
 | 
					        name: str,
 | 
				
			||||||
 | 
					        rule_version: str,
 | 
				
			||||||
 | 
					        rules: List[Dict[str, Any]],
 | 
				
			||||||
 | 
					        default_value: str,
 | 
				
			||||||
 | 
					        split_charge_rules: List[Dict[str, Any]],
 | 
				
			||||||
    ):
 | 
					    ):
 | 
				
			||||||
        self.name = name
 | 
					        self.name = name
 | 
				
			||||||
        self.rule_version = rule_version
 | 
					        self.rule_version = rule_version
 | 
				
			||||||
@ -18,13 +25,19 @@ class CostCategoryDefinition(BaseModel):
 | 
				
			|||||||
        self.split_charge_rules = split_charge_rules
 | 
					        self.split_charge_rules = split_charge_rules
 | 
				
			||||||
        self.arn = f"arn:aws:ce::{account_id}:costcategory/{str(mock_random.uuid4())}"
 | 
					        self.arn = f"arn:aws:ce::{account_id}:costcategory/{str(mock_random.uuid4())}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def update(self, rule_version, rules, default_value, split_charge_rules):
 | 
					    def update(
 | 
				
			||||||
 | 
					        self,
 | 
				
			||||||
 | 
					        rule_version: str,
 | 
				
			||||||
 | 
					        rules: List[Dict[str, Any]],
 | 
				
			||||||
 | 
					        default_value: str,
 | 
				
			||||||
 | 
					        split_charge_rules: List[Dict[str, Any]],
 | 
				
			||||||
 | 
					    ) -> None:
 | 
				
			||||||
        self.rule_version = rule_version
 | 
					        self.rule_version = rule_version
 | 
				
			||||||
        self.rules = rules
 | 
					        self.rules = rules
 | 
				
			||||||
        self.default_value = default_value
 | 
					        self.default_value = default_value
 | 
				
			||||||
        self.split_charge_rules = split_charge_rules
 | 
					        self.split_charge_rules = split_charge_rules
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def to_json(self):
 | 
					    def to_json(self) -> Dict[str, Any]:
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            "CostCategoryArn": self.arn,
 | 
					            "CostCategoryArn": self.arn,
 | 
				
			||||||
            "Name": self.name,
 | 
					            "Name": self.name,
 | 
				
			||||||
@ -38,20 +51,20 @@ class CostCategoryDefinition(BaseModel):
 | 
				
			|||||||
class CostExplorerBackend(BaseBackend):
 | 
					class CostExplorerBackend(BaseBackend):
 | 
				
			||||||
    """Implementation of CostExplorer APIs."""
 | 
					    """Implementation of CostExplorer APIs."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, region_name, account_id):
 | 
					    def __init__(self, region_name: str, account_id: str):
 | 
				
			||||||
        super().__init__(region_name, account_id)
 | 
					        super().__init__(region_name, account_id)
 | 
				
			||||||
        self.cost_categories = dict()
 | 
					        self.cost_categories: Dict[str, CostCategoryDefinition] = dict()
 | 
				
			||||||
        self.tagger = TaggingService()
 | 
					        self.tagger = TaggingService()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def create_cost_category_definition(
 | 
					    def create_cost_category_definition(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        name,
 | 
					        name: str,
 | 
				
			||||||
        rule_version,
 | 
					        rule_version: str,
 | 
				
			||||||
        rules,
 | 
					        rules: List[Dict[str, Any]],
 | 
				
			||||||
        default_value,
 | 
					        default_value: str,
 | 
				
			||||||
        split_charge_rules,
 | 
					        split_charge_rules: List[Dict[str, Any]],
 | 
				
			||||||
        tags,
 | 
					        tags: List[Dict[str, str]],
 | 
				
			||||||
    ):
 | 
					    ) -> Tuple[str, str]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        The EffectiveOn and ResourceTags-parameters are not yet implemented
 | 
					        The EffectiveOn and ResourceTags-parameters are not yet implemented
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@ -67,7 +80,9 @@ class CostExplorerBackend(BaseBackend):
 | 
				
			|||||||
        self.tag_resource(ccd.arn, tags)
 | 
					        self.tag_resource(ccd.arn, tags)
 | 
				
			||||||
        return ccd.arn, ""
 | 
					        return ccd.arn, ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def describe_cost_category_definition(self, cost_category_arn):
 | 
					    def describe_cost_category_definition(
 | 
				
			||||||
 | 
					        self, cost_category_arn: str
 | 
				
			||||||
 | 
					    ) -> CostCategoryDefinition:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        The EffectiveOn-parameter is not yet implemented
 | 
					        The EffectiveOn-parameter is not yet implemented
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@ -76,7 +91,9 @@ class CostExplorerBackend(BaseBackend):
 | 
				
			|||||||
            raise CostCategoryNotFound(ccd_id)
 | 
					            raise CostCategoryNotFound(ccd_id)
 | 
				
			||||||
        return self.cost_categories[cost_category_arn]
 | 
					        return self.cost_categories[cost_category_arn]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def delete_cost_category_definition(self, cost_category_arn):
 | 
					    def delete_cost_category_definition(
 | 
				
			||||||
 | 
					        self, cost_category_arn: str
 | 
				
			||||||
 | 
					    ) -> Tuple[str, str]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        The EffectiveOn-parameter is not yet implemented
 | 
					        The EffectiveOn-parameter is not yet implemented
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@ -84,8 +101,13 @@ class CostExplorerBackend(BaseBackend):
 | 
				
			|||||||
        return cost_category_arn, ""
 | 
					        return cost_category_arn, ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def update_cost_category_definition(
 | 
					    def update_cost_category_definition(
 | 
				
			||||||
        self, cost_category_arn, rule_version, rules, default_value, split_charge_rules
 | 
					        self,
 | 
				
			||||||
    ):
 | 
					        cost_category_arn: str,
 | 
				
			||||||
 | 
					        rule_version: str,
 | 
				
			||||||
 | 
					        rules: List[Dict[str, Any]],
 | 
				
			||||||
 | 
					        default_value: str,
 | 
				
			||||||
 | 
					        split_charge_rules: List[Dict[str, Any]],
 | 
				
			||||||
 | 
					    ) -> Tuple[str, str]:
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        The EffectiveOn-parameter is not yet implemented
 | 
					        The EffectiveOn-parameter is not yet implemented
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@ -94,13 +116,13 @@ class CostExplorerBackend(BaseBackend):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return cost_category_arn, ""
 | 
					        return cost_category_arn, ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def list_tags_for_resource(self, resource_arn):
 | 
					    def list_tags_for_resource(self, resource_arn: str) -> List[Dict[str, str]]:
 | 
				
			||||||
        return self.tagger.list_tags_for_resource(arn=resource_arn)["Tags"]
 | 
					        return self.tagger.list_tags_for_resource(arn=resource_arn)["Tags"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def tag_resource(self, resource_arn, tags):
 | 
					    def tag_resource(self, resource_arn: str, tags: List[Dict[str, str]]) -> None:
 | 
				
			||||||
        self.tagger.tag_resource(resource_arn, tags)
 | 
					        self.tagger.tag_resource(resource_arn, tags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def untag_resource(self, resource_arn, tag_keys):
 | 
					    def untag_resource(self, resource_arn: str, tag_keys: List[str]) -> None:
 | 
				
			||||||
        self.tagger.untag_resource_using_names(resource_arn, tag_keys)
 | 
					        self.tagger.untag_resource_using_names(resource_arn, tag_keys)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,18 +2,18 @@
 | 
				
			|||||||
import json
 | 
					import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from moto.core.responses import BaseResponse
 | 
					from moto.core.responses import BaseResponse
 | 
				
			||||||
from .models import ce_backends
 | 
					from .models import ce_backends, CostExplorerBackend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CostExplorerResponse(BaseResponse):
 | 
					class CostExplorerResponse(BaseResponse):
 | 
				
			||||||
    """Handler for CostExplorer requests and responses."""
 | 
					    """Handler for CostExplorer requests and responses."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def ce_backend(self):
 | 
					    def ce_backend(self) -> CostExplorerBackend:
 | 
				
			||||||
        """Return backend instance specific for this region."""
 | 
					        """Return backend instance specific for this region."""
 | 
				
			||||||
        return ce_backends[self.current_account]["global"]
 | 
					        return ce_backends[self.current_account]["global"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def create_cost_category_definition(self):
 | 
					    def create_cost_category_definition(self) -> str:
 | 
				
			||||||
        params = json.loads(self.body)
 | 
					        params = json.loads(self.body)
 | 
				
			||||||
        name = params.get("Name")
 | 
					        name = params.get("Name")
 | 
				
			||||||
        rule_version = params.get("RuleVersion")
 | 
					        rule_version = params.get("RuleVersion")
 | 
				
			||||||
@ -36,7 +36,7 @@ class CostExplorerResponse(BaseResponse):
 | 
				
			|||||||
            dict(CostCategoryArn=cost_category_arn, EffectiveStart=effective_start)
 | 
					            dict(CostCategoryArn=cost_category_arn, EffectiveStart=effective_start)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def describe_cost_category_definition(self):
 | 
					    def describe_cost_category_definition(self) -> str:
 | 
				
			||||||
        params = json.loads(self.body)
 | 
					        params = json.loads(self.body)
 | 
				
			||||||
        cost_category_arn = params.get("CostCategoryArn")
 | 
					        cost_category_arn = params.get("CostCategoryArn")
 | 
				
			||||||
        cost_category = self.ce_backend.describe_cost_category_definition(
 | 
					        cost_category = self.ce_backend.describe_cost_category_definition(
 | 
				
			||||||
@ -44,7 +44,7 @@ class CostExplorerResponse(BaseResponse):
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
        return json.dumps(dict(CostCategory=cost_category.to_json()))
 | 
					        return json.dumps(dict(CostCategory=cost_category.to_json()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def delete_cost_category_definition(self):
 | 
					    def delete_cost_category_definition(self) -> str:
 | 
				
			||||||
        params = json.loads(self.body)
 | 
					        params = json.loads(self.body)
 | 
				
			||||||
        cost_category_arn = params.get("CostCategoryArn")
 | 
					        cost_category_arn = params.get("CostCategoryArn")
 | 
				
			||||||
        (
 | 
					        (
 | 
				
			||||||
@ -57,7 +57,7 @@ class CostExplorerResponse(BaseResponse):
 | 
				
			|||||||
            dict(CostCategoryArn=cost_category_arn, EffectiveEnd=effective_end)
 | 
					            dict(CostCategoryArn=cost_category_arn, EffectiveEnd=effective_end)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def update_cost_category_definition(self):
 | 
					    def update_cost_category_definition(self) -> str:
 | 
				
			||||||
        params = json.loads(self.body)
 | 
					        params = json.loads(self.body)
 | 
				
			||||||
        cost_category_arn = params.get("CostCategoryArn")
 | 
					        cost_category_arn = params.get("CostCategoryArn")
 | 
				
			||||||
        rule_version = params.get("RuleVersion")
 | 
					        rule_version = params.get("RuleVersion")
 | 
				
			||||||
@ -78,20 +78,20 @@ class CostExplorerResponse(BaseResponse):
 | 
				
			|||||||
            dict(CostCategoryArn=cost_category_arn, EffectiveStart=effective_start)
 | 
					            dict(CostCategoryArn=cost_category_arn, EffectiveStart=effective_start)
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def list_tags_for_resource(self):
 | 
					    def list_tags_for_resource(self) -> str:
 | 
				
			||||||
        params = json.loads(self.body)
 | 
					        params = json.loads(self.body)
 | 
				
			||||||
        resource_arn = params.get("ResourceArn")
 | 
					        resource_arn = params.get("ResourceArn")
 | 
				
			||||||
        tags = self.ce_backend.list_tags_for_resource(resource_arn)
 | 
					        tags = self.ce_backend.list_tags_for_resource(resource_arn)
 | 
				
			||||||
        return json.dumps({"ResourceTags": tags})
 | 
					        return json.dumps({"ResourceTags": tags})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def tag_resource(self):
 | 
					    def tag_resource(self) -> str:
 | 
				
			||||||
        params = json.loads(self.body)
 | 
					        params = json.loads(self.body)
 | 
				
			||||||
        resource_arn = params.get("ResourceArn")
 | 
					        resource_arn = params.get("ResourceArn")
 | 
				
			||||||
        tags = params.get("ResourceTags")
 | 
					        tags = params.get("ResourceTags")
 | 
				
			||||||
        self.ce_backend.tag_resource(resource_arn, tags)
 | 
					        self.ce_backend.tag_resource(resource_arn, tags)
 | 
				
			||||||
        return json.dumps({})
 | 
					        return json.dumps({})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def untag_resource(self):
 | 
					    def untag_resource(self) -> str:
 | 
				
			||||||
        params = json.loads(self.body)
 | 
					        params = json.loads(self.body)
 | 
				
			||||||
        resource_arn = params.get("ResourceArn")
 | 
					        resource_arn = params.get("ResourceArn")
 | 
				
			||||||
        tag_names = params.get("ResourceTagKeys")
 | 
					        tag_names = params.get("ResourceTagKeys")
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ class TaggingService:
 | 
				
			|||||||
                result[key] = val
 | 
					                result[key] = val
 | 
				
			||||||
        return result
 | 
					        return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def list_tags_for_resource(self, arn: str) -> List[Dict[str, str]]:
 | 
					    def list_tags_for_resource(self, arn: str) -> Dict[str, List[Dict[str, str]]]:
 | 
				
			||||||
        """Return list of tags inside dict with key of "tag_name".
 | 
					        """Return list of tags inside dict with key of "tag_name".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Useful for describe functions; this return value can be added to
 | 
					        Useful for describe functions; this return value can be added to
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ 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]
 | 
				
			||||||
files= moto/a*,moto/b*
 | 
					files= moto/a*,moto/b*,moto/ce
 | 
				
			||||||
show_column_numbers=True
 | 
					show_column_numbers=True
 | 
				
			||||||
show_error_codes = True
 | 
					show_error_codes = True
 | 
				
			||||||
disable_error_code=abstract
 | 
					disable_error_code=abstract
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user