File: models.py

package info (click to toggle)
python-moto 5.1.18-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 116,520 kB
  • sloc: python: 636,725; javascript: 181; makefile: 39; sh: 3
file content (115 lines) | stat: -rw-r--r-- 3,617 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import datetime
from typing import Any, Optional
from xml.etree import ElementTree as ET

from moto.core.base_backend import BackendDict, BaseBackend
from moto.core.common_models import BaseModel

from .resources import VOICE_DATA
from .utils import make_arn_for_lexicon


class Lexicon(BaseModel):
    def __init__(self, name: str, content: str, account_id: str, region_name: str):
        self.name = name
        self.content = content
        self.size = 0
        self.alphabet = None
        self.last_modified = None
        self.language_code = None
        self.lexemes_count = 0
        self.arn = make_arn_for_lexicon(account_id, name, region_name)

        self.update()

    def update(self, content: Optional[str] = None) -> None:
        if content is not None:
            self.content = content

        # Probably a very naive approach, but it'll do for now.
        try:
            root = ET.fromstring(self.content)
            self.size = len(self.content)
            self.last_modified = int(  # type: ignore
                (
                    datetime.datetime.now() - datetime.datetime(1970, 1, 1)
                ).total_seconds()
            )
            self.lexemes_count = len(root.findall("."))

            for key, value in root.attrib.items():
                if key.endswith("alphabet"):
                    self.alphabet = value  # type: ignore
                elif key.endswith("lang"):
                    self.language_code = value  # type: ignore

        except Exception as err:
            raise ValueError(f"Failure parsing XML: {err}")

    def to_dict(self) -> dict[str, Any]:
        return {
            "Attributes": {
                "Alphabet": self.alphabet,
                "LanguageCode": self.language_code,
                "LastModified": self.last_modified,
                "LexemesCount": self.lexemes_count,
                "LexiconArn": self.arn,
                "Size": self.size,
            }
        }

    def __repr__(self) -> str:
        return f"<Lexicon {self.name}>"


class PollyBackend(BaseBackend):
    def __init__(self, region_name: str, account_id: str):
        super().__init__(region_name, account_id)
        self._lexicons: dict[str, Lexicon] = {}

    def describe_voices(self, language_code: str) -> list[dict[str, Any]]:
        """
        Pagination is not yet implemented
        """
        if language_code is None:
            return VOICE_DATA

        return [item for item in VOICE_DATA if item["LanguageCode"] == language_code]

    def delete_lexicon(self, name: str) -> None:
        # implement here
        del self._lexicons[name]

    def get_lexicon(self, name: str) -> Lexicon:
        # Raises KeyError
        return self._lexicons[name]

    def list_lexicons(self) -> list[dict[str, Any]]:
        """
        Pagination is not yet implemented
        """

        result = []

        for name, lexicon in self._lexicons.items():
            lexicon_dict = lexicon.to_dict()
            lexicon_dict["Name"] = name

            result.append(lexicon_dict)

        return result

    def put_lexicon(self, name: str, content: str) -> None:
        # If lexicon content is bad, it will raise ValueError
        if name in self._lexicons:
            # Regenerated all the stats from the XML
            # but keeps the ARN
            self._lexicons[name].update(content)
        else:
            lexicon = Lexicon(
                name, content, self.account_id, region_name=self.region_name
            )
            self._lexicons[name] = lexicon


polly_backends = BackendDict(PollyBackend, "polly")