nadeshiko-sdk 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. nadeshiko/__init__.py +10 -0
  2. nadeshiko/_version.py +1 -0
  3. nadeshiko/api/__init__.py +1 -0
  4. nadeshiko/api/auth/__init__.py +3 -0
  5. nadeshiko/api/auth/internal/__init__.py +11 -0
  6. nadeshiko/api/auth/internal/get_discord_auth_url.py +176 -0
  7. nadeshiko/api/auth/internal/login.py +213 -0
  8. nadeshiko/api/auth/internal/login_discord.py +204 -0
  9. nadeshiko/api/auth/internal/login_google.py +204 -0
  10. nadeshiko/api/auth/internal/register.py +212 -0
  11. nadeshiko/api/auth_jwt/__init__.py +3 -0
  12. nadeshiko/api/auth_jwt/internal/__init__.py +7 -0
  13. nadeshiko/api/auth_jwt/internal/logout.py +151 -0
  14. nadeshiko/api/lists/__init__.py +8 -0
  15. nadeshiko/api/lists/internal/__init__.py +12 -0
  16. nadeshiko/api/lists/internal/list_add_item.py +215 -0
  17. nadeshiko/api/lists/internal/list_create.py +194 -0
  18. nadeshiko/api/lists/internal/list_destroy.py +193 -0
  19. nadeshiko/api/lists/internal/list_remove_item.py +207 -0
  20. nadeshiko/api/lists/internal/list_update.py +215 -0
  21. nadeshiko/api/lists/internal/list_update_item.py +229 -0
  22. nadeshiko/api/lists/list_index.py +257 -0
  23. nadeshiko/api/lists/list_show.py +193 -0
  24. nadeshiko/api/media/__init__.py +14 -0
  25. nadeshiko/api/media/character_show.py +193 -0
  26. nadeshiko/api/media/episode_index.py +229 -0
  27. nadeshiko/api/media/episode_show.py +207 -0
  28. nadeshiko/api/media/internal/__init__.py +16 -0
  29. nadeshiko/api/media/internal/episode_create.py +215 -0
  30. nadeshiko/api/media/internal/episode_destroy.py +205 -0
  31. nadeshiko/api/media/internal/episode_update.py +229 -0
  32. nadeshiko/api/media/internal/media_create.py +194 -0
  33. nadeshiko/api/media/internal/media_destroy.py +197 -0
  34. nadeshiko/api/media/internal/media_update.py +219 -0
  35. nadeshiko/api/media/internal/segment_create.py +229 -0
  36. nadeshiko/api/media/internal/segment_destroy.py +219 -0
  37. nadeshiko/api/media/internal/segment_index.py +243 -0
  38. nadeshiko/api/media/internal/segment_update.py +243 -0
  39. nadeshiko/api/media/media_index.py +232 -0
  40. nadeshiko/api/media/media_show.py +193 -0
  41. nadeshiko/api/media/segment_show.py +221 -0
  42. nadeshiko/api/media/segment_show_by_uuid.py +193 -0
  43. nadeshiko/api/media/seiyuu_show.py +193 -0
  44. nadeshiko/api/search/__init__.py +11 -0
  45. nadeshiko/api/search/fetch_media_info.py +278 -0
  46. nadeshiko/api/search/fetch_sentence_context.py +219 -0
  47. nadeshiko/api/search/internal/__init__.py +6 -0
  48. nadeshiko/api/search/search.py +295 -0
  49. nadeshiko/api/search/search_health_check.py +168 -0
  50. nadeshiko/api/search/search_multiple.py +238 -0
  51. nadeshiko/api/user/__init__.py +3 -0
  52. nadeshiko/api/user/internal/__init__.py +11 -0
  53. nadeshiko/api/user/internal/create_api_key.py +199 -0
  54. nadeshiko/api/user/internal/deactivate_api_key.py +194 -0
  55. nadeshiko/api/user/internal/get_api_keys.py +151 -0
  56. nadeshiko/api/user/internal/get_identity_me.py +156 -0
  57. nadeshiko/api/user/internal/get_user_info.py +156 -0
  58. nadeshiko/client.py +138 -0
  59. nadeshiko/errors.py +16 -0
  60. nadeshiko/models/__init__.py +215 -0
  61. nadeshiko/models/api_key.py +118 -0
  62. nadeshiko/models/api_key_permission.py +70 -0
  63. nadeshiko/models/auth_user.py +107 -0
  64. nadeshiko/models/basic_info.py +132 -0
  65. nadeshiko/models/category_statistic.py +71 -0
  66. nadeshiko/models/character.py +100 -0
  67. nadeshiko/models/character_input.py +130 -0
  68. nadeshiko/models/character_input_character_role.py +10 -0
  69. nadeshiko/models/character_with_media.py +124 -0
  70. nadeshiko/models/character_with_media_media_appearances_item.py +93 -0
  71. nadeshiko/models/character_with_media_media_appearances_item_role.py +10 -0
  72. nadeshiko/models/create_api_key_request.py +75 -0
  73. nadeshiko/models/create_api_key_response.py +70 -0
  74. nadeshiko/models/deactivate_api_key_request.py +62 -0
  75. nadeshiko/models/deactivate_api_key_response.py +62 -0
  76. nadeshiko/models/discord_auth_url_response.py +62 -0
  77. nadeshiko/models/discord_login_request.py +62 -0
  78. nadeshiko/models/episode.py +253 -0
  79. nadeshiko/models/episode_create_request.py +145 -0
  80. nadeshiko/models/episode_list_response.py +94 -0
  81. nadeshiko/models/episode_update_request.py +135 -0
  82. nadeshiko/models/error.py +128 -0
  83. nadeshiko/models/error_errors.py +46 -0
  84. nadeshiko/models/fetch_media_info_response.py +115 -0
  85. nadeshiko/models/fetch_media_info_type.py +10 -0
  86. nadeshiko/models/fetch_sentence_context_request.py +96 -0
  87. nadeshiko/models/fetch_sentence_context_response.py +75 -0
  88. nadeshiko/models/get_api_keys_response.py +86 -0
  89. nadeshiko/models/google_login_request.py +62 -0
  90. nadeshiko/models/list_.py +97 -0
  91. nadeshiko/models/list_add_item_body.py +69 -0
  92. nadeshiko/models/list_add_item_response_201.py +61 -0
  93. nadeshiko/models/list_create_request.py +107 -0
  94. nadeshiko/models/list_create_request_type.py +9 -0
  95. nadeshiko/models/list_create_request_visibility.py +9 -0
  96. nadeshiko/models/list_destroy_response_200.py +70 -0
  97. nadeshiko/models/list_index_type.py +9 -0
  98. nadeshiko/models/list_index_visibility.py +9 -0
  99. nadeshiko/models/list_input.py +138 -0
  100. nadeshiko/models/list_input_list_type.py +9 -0
  101. nadeshiko/models/list_input_list_visibility.py +9 -0
  102. nadeshiko/models/list_remove_item_response_200.py +61 -0
  103. nadeshiko/models/list_type.py +9 -0
  104. nadeshiko/models/list_update_body.py +78 -0
  105. nadeshiko/models/list_update_body_visibility.py +9 -0
  106. nadeshiko/models/list_update_item_body.py +61 -0
  107. nadeshiko/models/list_update_item_response_200.py +61 -0
  108. nadeshiko/models/list_visibility.py +9 -0
  109. nadeshiko/models/list_with_media.py +119 -0
  110. nadeshiko/models/list_with_media_media_item.py +83 -0
  111. nadeshiko/models/list_with_media_type.py +9 -0
  112. nadeshiko/models/list_with_media_visibility.py +9 -0
  113. nadeshiko/models/login_request.py +70 -0
  114. nadeshiko/models/login_response.py +84 -0
  115. nadeshiko/models/logout_response.py +73 -0
  116. nadeshiko/models/media.py +288 -0
  117. nadeshiko/models/media_category.py +11 -0
  118. nadeshiko/models/media_character.py +78 -0
  119. nadeshiko/models/media_character_role.py +10 -0
  120. nadeshiko/models/media_create_request.py +270 -0
  121. nadeshiko/models/media_create_request_category.py +11 -0
  122. nadeshiko/models/media_destroy_response_200.py +70 -0
  123. nadeshiko/models/media_index_category.py +9 -0
  124. nadeshiko/models/media_info_data.py +307 -0
  125. nadeshiko/models/media_info_path.py +83 -0
  126. nadeshiko/models/media_info_stats.py +89 -0
  127. nadeshiko/models/media_list_response.py +94 -0
  128. nadeshiko/models/media_update_request.py +297 -0
  129. nadeshiko/models/media_update_request_category.py +9 -0
  130. nadeshiko/models/quota_info.py +87 -0
  131. nadeshiko/models/quota_info_quota_limit_type_1.py +8 -0
  132. nadeshiko/models/register_request.py +78 -0
  133. nadeshiko/models/register_response.py +76 -0
  134. nadeshiko/models/register_response_user.py +46 -0
  135. nadeshiko/models/search_health_check_response.py +138 -0
  136. nadeshiko/models/search_multiple_request.py +72 -0
  137. nadeshiko/models/search_multiple_response.py +79 -0
  138. nadeshiko/models/search_request.py +253 -0
  139. nadeshiko/models/search_request_content_sort.py +13 -0
  140. nadeshiko/models/search_request_media_item.py +85 -0
  141. nadeshiko/models/search_request_media_item_seasons_item.py +69 -0
  142. nadeshiko/models/search_response.py +158 -0
  143. nadeshiko/models/segment.py +303 -0
  144. nadeshiko/models/segment_create_request.py +203 -0
  145. nadeshiko/models/segment_create_request_status.py +13 -0
  146. nadeshiko/models/segment_info.py +207 -0
  147. nadeshiko/models/segment_list_response.py +94 -0
  148. nadeshiko/models/segment_status.py +13 -0
  149. nadeshiko/models/segment_update_request.py +198 -0
  150. nadeshiko/models/segment_update_request_status.py +13 -0
  151. nadeshiko/models/seiyuu.py +86 -0
  152. nadeshiko/models/seiyuu_with_roles.py +108 -0
  153. nadeshiko/models/seiyuu_with_roles_roles_item.py +109 -0
  154. nadeshiko/models/seiyuu_with_roles_roles_item_role.py +10 -0
  155. nadeshiko/models/sentence.py +88 -0
  156. nadeshiko/models/statistic.py +132 -0
  157. nadeshiko/models/statistic_season_with_episode_hits.py +74 -0
  158. nadeshiko/models/statistic_season_with_episode_hits_additional_property.py +46 -0
  159. nadeshiko/models/user_info_response.py +79 -0
  160. nadeshiko/models/user_info_response_user.py +91 -0
  161. nadeshiko/models/user_role.py +71 -0
  162. nadeshiko/models/word_match.py +107 -0
  163. nadeshiko/models/word_match_media.py +98 -0
  164. nadeshiko/types.py +54 -0
  165. nadeshiko_sdk-0.1.0.dist-info/METADATA +147 -0
  166. nadeshiko_sdk-0.1.0.dist-info/RECORD +167 -0
  167. nadeshiko_sdk-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,62 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ T = TypeVar("T", bound="DeactivateApiKeyRequest")
10
+
11
+
12
+ @_attrs_define
13
+ class DeactivateApiKeyRequest:
14
+ """Deactivate API key request
15
+
16
+ Attributes:
17
+ api_key_id (int): ID of the API key to deactivate
18
+ """
19
+
20
+ api_key_id: int
21
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
22
+
23
+ def to_dict(self) -> dict[str, Any]:
24
+ api_key_id = self.api_key_id
25
+
26
+ field_dict: dict[str, Any] = {}
27
+ field_dict.update(self.additional_properties)
28
+ field_dict.update(
29
+ {
30
+ "api_key_id": api_key_id,
31
+ }
32
+ )
33
+
34
+ return field_dict
35
+
36
+ @classmethod
37
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
38
+ d = dict(src_dict)
39
+ api_key_id = d.pop("api_key_id")
40
+
41
+ deactivate_api_key_request = cls(
42
+ api_key_id=api_key_id,
43
+ )
44
+
45
+ deactivate_api_key_request.additional_properties = d
46
+ return deactivate_api_key_request
47
+
48
+ @property
49
+ def additional_keys(self) -> list[str]:
50
+ return list(self.additional_properties.keys())
51
+
52
+ def __getitem__(self, key: str) -> Any:
53
+ return self.additional_properties[key]
54
+
55
+ def __setitem__(self, key: str, value: Any) -> None:
56
+ self.additional_properties[key] = value
57
+
58
+ def __delitem__(self, key: str) -> None:
59
+ del self.additional_properties[key]
60
+
61
+ def __contains__(self, key: str) -> bool:
62
+ return key in self.additional_properties
@@ -0,0 +1,62 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ T = TypeVar("T", bound="DeactivateApiKeyResponse")
10
+
11
+
12
+ @_attrs_define
13
+ class DeactivateApiKeyResponse:
14
+ """Deactivate API key response
15
+
16
+ Attributes:
17
+ message (str): Success message
18
+ """
19
+
20
+ message: str
21
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
22
+
23
+ def to_dict(self) -> dict[str, Any]:
24
+ message = self.message
25
+
26
+ field_dict: dict[str, Any] = {}
27
+ field_dict.update(self.additional_properties)
28
+ field_dict.update(
29
+ {
30
+ "message": message,
31
+ }
32
+ )
33
+
34
+ return field_dict
35
+
36
+ @classmethod
37
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
38
+ d = dict(src_dict)
39
+ message = d.pop("message")
40
+
41
+ deactivate_api_key_response = cls(
42
+ message=message,
43
+ )
44
+
45
+ deactivate_api_key_response.additional_properties = d
46
+ return deactivate_api_key_response
47
+
48
+ @property
49
+ def additional_keys(self) -> list[str]:
50
+ return list(self.additional_properties.keys())
51
+
52
+ def __getitem__(self, key: str) -> Any:
53
+ return self.additional_properties[key]
54
+
55
+ def __setitem__(self, key: str, value: Any) -> None:
56
+ self.additional_properties[key] = value
57
+
58
+ def __delitem__(self, key: str) -> None:
59
+ del self.additional_properties[key]
60
+
61
+ def __contains__(self, key: str) -> bool:
62
+ return key in self.additional_properties
@@ -0,0 +1,62 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ T = TypeVar("T", bound="DiscordAuthUrlResponse")
10
+
11
+
12
+ @_attrs_define
13
+ class DiscordAuthUrlResponse:
14
+ """Discord OAuth URL Response
15
+
16
+ Attributes:
17
+ url (str): Discord OAuth Authorization URL
18
+ """
19
+
20
+ url: str
21
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
22
+
23
+ def to_dict(self) -> dict[str, Any]:
24
+ url = self.url
25
+
26
+ field_dict: dict[str, Any] = {}
27
+ field_dict.update(self.additional_properties)
28
+ field_dict.update(
29
+ {
30
+ "url": url,
31
+ }
32
+ )
33
+
34
+ return field_dict
35
+
36
+ @classmethod
37
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
38
+ d = dict(src_dict)
39
+ url = d.pop("url")
40
+
41
+ discord_auth_url_response = cls(
42
+ url=url,
43
+ )
44
+
45
+ discord_auth_url_response.additional_properties = d
46
+ return discord_auth_url_response
47
+
48
+ @property
49
+ def additional_keys(self) -> list[str]:
50
+ return list(self.additional_properties.keys())
51
+
52
+ def __getitem__(self, key: str) -> Any:
53
+ return self.additional_properties[key]
54
+
55
+ def __setitem__(self, key: str, value: Any) -> None:
56
+ self.additional_properties[key] = value
57
+
58
+ def __delitem__(self, key: str) -> None:
59
+ del self.additional_properties[key]
60
+
61
+ def __contains__(self, key: str) -> bool:
62
+ return key in self.additional_properties
@@ -0,0 +1,62 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Mapping
4
+ from typing import Any, TypeVar
5
+
6
+ from attrs import define as _attrs_define
7
+ from attrs import field as _attrs_field
8
+
9
+ T = TypeVar("T", bound="DiscordLoginRequest")
10
+
11
+
12
+ @_attrs_define
13
+ class DiscordLoginRequest:
14
+ """Discord OAuth Login Request
15
+
16
+ Attributes:
17
+ code (str): Discord OAuth authorization code Example: 1234567890.
18
+ """
19
+
20
+ code: str
21
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
22
+
23
+ def to_dict(self) -> dict[str, Any]:
24
+ code = self.code
25
+
26
+ field_dict: dict[str, Any] = {}
27
+ field_dict.update(self.additional_properties)
28
+ field_dict.update(
29
+ {
30
+ "code": code,
31
+ }
32
+ )
33
+
34
+ return field_dict
35
+
36
+ @classmethod
37
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
38
+ d = dict(src_dict)
39
+ code = d.pop("code")
40
+
41
+ discord_login_request = cls(
42
+ code=code,
43
+ )
44
+
45
+ discord_login_request.additional_properties = d
46
+ return discord_login_request
47
+
48
+ @property
49
+ def additional_keys(self) -> list[str]:
50
+ return list(self.additional_properties.keys())
51
+
52
+ def __getitem__(self, key: str) -> Any:
53
+ return self.additional_properties[key]
54
+
55
+ def __setitem__(self, key: str, value: Any) -> None:
56
+ self.additional_properties[key] = value
57
+
58
+ def __delitem__(self, key: str) -> None:
59
+ del self.additional_properties[key]
60
+
61
+ def __contains__(self, key: str) -> bool:
62
+ return key in self.additional_properties
@@ -0,0 +1,253 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ from collections.abc import Mapping
5
+ from typing import Any, TypeVar, cast
6
+
7
+ from attrs import define as _attrs_define
8
+ from attrs import field as _attrs_field
9
+ from dateutil.parser import isoparse
10
+
11
+ from ..types import UNSET, Unset
12
+
13
+ T = TypeVar("T", bound="Episode")
14
+
15
+
16
+ @_attrs_define
17
+ class Episode:
18
+ """
19
+ Attributes:
20
+ media_id (int): ID of the media this episode belongs to Example: 7674.
21
+ episode_number (int): Episode number within the media Example: 1.
22
+ num_segments (int): Number of segments in this episode Example: 450.
23
+ anilist_episode_id (int | None | Unset): AniList episode ID for external reference Example: 123456.
24
+ title_english (None | str | Unset): English title of the episode Example: The Beginning.
25
+ title_romaji (None | str | Unset): Romanized title of the episode Example: Hajimari.
26
+ title_japanese (None | str | Unset): Japanese title of the episode Example: 始まり.
27
+ description (None | str | Unset): Episode description or synopsis Example: The hero begins their journey.
28
+ aired_at (datetime.datetime | None | Unset): When the episode originally aired Example: 2024-01-15
29
+ 09:00:00+00:00.
30
+ length_seconds (int | None | Unset): Episode duration in seconds Example: 1420.
31
+ thumbnail_url (None | str | Unset): URL to episode thumbnail image Example:
32
+ https://example.com/thumbnails/episode1.jpg.
33
+ """
34
+
35
+ media_id: int
36
+ episode_number: int
37
+ num_segments: int
38
+ anilist_episode_id: int | None | Unset = UNSET
39
+ title_english: None | str | Unset = UNSET
40
+ title_romaji: None | str | Unset = UNSET
41
+ title_japanese: None | str | Unset = UNSET
42
+ description: None | str | Unset = UNSET
43
+ aired_at: datetime.datetime | None | Unset = UNSET
44
+ length_seconds: int | None | Unset = UNSET
45
+ thumbnail_url: None | str | Unset = UNSET
46
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
47
+
48
+ def to_dict(self) -> dict[str, Any]:
49
+ media_id = self.media_id
50
+
51
+ episode_number = self.episode_number
52
+
53
+ num_segments = self.num_segments
54
+
55
+ anilist_episode_id: int | None | Unset
56
+ if isinstance(self.anilist_episode_id, Unset):
57
+ anilist_episode_id = UNSET
58
+ else:
59
+ anilist_episode_id = self.anilist_episode_id
60
+
61
+ title_english: None | str | Unset
62
+ if isinstance(self.title_english, Unset):
63
+ title_english = UNSET
64
+ else:
65
+ title_english = self.title_english
66
+
67
+ title_romaji: None | str | Unset
68
+ if isinstance(self.title_romaji, Unset):
69
+ title_romaji = UNSET
70
+ else:
71
+ title_romaji = self.title_romaji
72
+
73
+ title_japanese: None | str | Unset
74
+ if isinstance(self.title_japanese, Unset):
75
+ title_japanese = UNSET
76
+ else:
77
+ title_japanese = self.title_japanese
78
+
79
+ description: None | str | Unset
80
+ if isinstance(self.description, Unset):
81
+ description = UNSET
82
+ else:
83
+ description = self.description
84
+
85
+ aired_at: None | str | Unset
86
+ if isinstance(self.aired_at, Unset):
87
+ aired_at = UNSET
88
+ elif isinstance(self.aired_at, datetime.datetime):
89
+ aired_at = self.aired_at.isoformat()
90
+ else:
91
+ aired_at = self.aired_at
92
+
93
+ length_seconds: int | None | Unset
94
+ if isinstance(self.length_seconds, Unset):
95
+ length_seconds = UNSET
96
+ else:
97
+ length_seconds = self.length_seconds
98
+
99
+ thumbnail_url: None | str | Unset
100
+ if isinstance(self.thumbnail_url, Unset):
101
+ thumbnail_url = UNSET
102
+ else:
103
+ thumbnail_url = self.thumbnail_url
104
+
105
+ field_dict: dict[str, Any] = {}
106
+ field_dict.update(self.additional_properties)
107
+ field_dict.update(
108
+ {
109
+ "mediaId": media_id,
110
+ "episodeNumber": episode_number,
111
+ "numSegments": num_segments,
112
+ }
113
+ )
114
+ if anilist_episode_id is not UNSET:
115
+ field_dict["anilistEpisodeId"] = anilist_episode_id
116
+ if title_english is not UNSET:
117
+ field_dict["titleEnglish"] = title_english
118
+ if title_romaji is not UNSET:
119
+ field_dict["titleRomaji"] = title_romaji
120
+ if title_japanese is not UNSET:
121
+ field_dict["titleJapanese"] = title_japanese
122
+ if description is not UNSET:
123
+ field_dict["description"] = description
124
+ if aired_at is not UNSET:
125
+ field_dict["airedAt"] = aired_at
126
+ if length_seconds is not UNSET:
127
+ field_dict["lengthSeconds"] = length_seconds
128
+ if thumbnail_url is not UNSET:
129
+ field_dict["thumbnailUrl"] = thumbnail_url
130
+
131
+ return field_dict
132
+
133
+ @classmethod
134
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
135
+ d = dict(src_dict)
136
+ media_id = d.pop("mediaId")
137
+
138
+ episode_number = d.pop("episodeNumber")
139
+
140
+ num_segments = d.pop("numSegments")
141
+
142
+ def _parse_anilist_episode_id(data: object) -> int | None | Unset:
143
+ if data is None:
144
+ return data
145
+ if isinstance(data, Unset):
146
+ return data
147
+ return cast(int | None | Unset, data)
148
+
149
+ anilist_episode_id = _parse_anilist_episode_id(d.pop("anilistEpisodeId", UNSET))
150
+
151
+ def _parse_title_english(data: object) -> None | str | Unset:
152
+ if data is None:
153
+ return data
154
+ if isinstance(data, Unset):
155
+ return data
156
+ return cast(None | str | Unset, data)
157
+
158
+ title_english = _parse_title_english(d.pop("titleEnglish", UNSET))
159
+
160
+ def _parse_title_romaji(data: object) -> None | str | Unset:
161
+ if data is None:
162
+ return data
163
+ if isinstance(data, Unset):
164
+ return data
165
+ return cast(None | str | Unset, data)
166
+
167
+ title_romaji = _parse_title_romaji(d.pop("titleRomaji", UNSET))
168
+
169
+ def _parse_title_japanese(data: object) -> None | str | Unset:
170
+ if data is None:
171
+ return data
172
+ if isinstance(data, Unset):
173
+ return data
174
+ return cast(None | str | Unset, data)
175
+
176
+ title_japanese = _parse_title_japanese(d.pop("titleJapanese", UNSET))
177
+
178
+ def _parse_description(data: object) -> None | str | Unset:
179
+ if data is None:
180
+ return data
181
+ if isinstance(data, Unset):
182
+ return data
183
+ return cast(None | str | Unset, data)
184
+
185
+ description = _parse_description(d.pop("description", UNSET))
186
+
187
+ def _parse_aired_at(data: object) -> datetime.datetime | None | Unset:
188
+ if data is None:
189
+ return data
190
+ if isinstance(data, Unset):
191
+ return data
192
+ try:
193
+ if not isinstance(data, str):
194
+ raise TypeError()
195
+ aired_at_type_0 = isoparse(data)
196
+
197
+ return aired_at_type_0
198
+ except (TypeError, ValueError, AttributeError, KeyError):
199
+ pass
200
+ return cast(datetime.datetime | None | Unset, data)
201
+
202
+ aired_at = _parse_aired_at(d.pop("airedAt", UNSET))
203
+
204
+ def _parse_length_seconds(data: object) -> int | None | Unset:
205
+ if data is None:
206
+ return data
207
+ if isinstance(data, Unset):
208
+ return data
209
+ return cast(int | None | Unset, data)
210
+
211
+ length_seconds = _parse_length_seconds(d.pop("lengthSeconds", UNSET))
212
+
213
+ def _parse_thumbnail_url(data: object) -> None | str | Unset:
214
+ if data is None:
215
+ return data
216
+ if isinstance(data, Unset):
217
+ return data
218
+ return cast(None | str | Unset, data)
219
+
220
+ thumbnail_url = _parse_thumbnail_url(d.pop("thumbnailUrl", UNSET))
221
+
222
+ episode = cls(
223
+ media_id=media_id,
224
+ episode_number=episode_number,
225
+ num_segments=num_segments,
226
+ anilist_episode_id=anilist_episode_id,
227
+ title_english=title_english,
228
+ title_romaji=title_romaji,
229
+ title_japanese=title_japanese,
230
+ description=description,
231
+ aired_at=aired_at,
232
+ length_seconds=length_seconds,
233
+ thumbnail_url=thumbnail_url,
234
+ )
235
+
236
+ episode.additional_properties = d
237
+ return episode
238
+
239
+ @property
240
+ def additional_keys(self) -> list[str]:
241
+ return list(self.additional_properties.keys())
242
+
243
+ def __getitem__(self, key: str) -> Any:
244
+ return self.additional_properties[key]
245
+
246
+ def __setitem__(self, key: str, value: Any) -> None:
247
+ self.additional_properties[key] = value
248
+
249
+ def __delitem__(self, key: str) -> None:
250
+ del self.additional_properties[key]
251
+
252
+ def __contains__(self, key: str) -> bool:
253
+ return key in self.additional_properties
@@ -0,0 +1,145 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ from collections.abc import Mapping
5
+ from typing import Any, TypeVar
6
+
7
+ from attrs import define as _attrs_define
8
+ from attrs import field as _attrs_field
9
+ from dateutil.parser import isoparse
10
+
11
+ from ..types import UNSET, Unset
12
+
13
+ T = TypeVar("T", bound="EpisodeCreateRequest")
14
+
15
+
16
+ @_attrs_define
17
+ class EpisodeCreateRequest:
18
+ """
19
+ Attributes:
20
+ episode_number (int): Episode number within the media (must be unique for this media) Example: 1.
21
+ anilist_episode_id (int | Unset): AniList episode ID for external reference Example: 123456.
22
+ title_english (str | Unset): English title of the episode Example: The Beginning.
23
+ title_romaji (str | Unset): Romanized title of the episode Example: Hajimari.
24
+ title_japanese (str | Unset): Japanese title of the episode Example: 始まり.
25
+ description (str | Unset): Episode description or synopsis Example: The hero begins their journey.
26
+ aired_at (datetime.datetime | Unset): When the episode originally aired Example: 2024-01-15 09:00:00+00:00.
27
+ length_seconds (int | Unset): Episode duration in seconds Example: 1420.
28
+ thumbnail_url (str | Unset): URL to episode thumbnail image Example:
29
+ https://example.com/thumbnails/episode1.jpg.
30
+ """
31
+
32
+ episode_number: int
33
+ anilist_episode_id: int | Unset = UNSET
34
+ title_english: str | Unset = UNSET
35
+ title_romaji: str | Unset = UNSET
36
+ title_japanese: str | Unset = UNSET
37
+ description: str | Unset = UNSET
38
+ aired_at: datetime.datetime | Unset = UNSET
39
+ length_seconds: int | Unset = UNSET
40
+ thumbnail_url: str | Unset = UNSET
41
+ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
42
+
43
+ def to_dict(self) -> dict[str, Any]:
44
+ episode_number = self.episode_number
45
+
46
+ anilist_episode_id = self.anilist_episode_id
47
+
48
+ title_english = self.title_english
49
+
50
+ title_romaji = self.title_romaji
51
+
52
+ title_japanese = self.title_japanese
53
+
54
+ description = self.description
55
+
56
+ aired_at: str | Unset = UNSET
57
+ if not isinstance(self.aired_at, Unset):
58
+ aired_at = self.aired_at.isoformat()
59
+
60
+ length_seconds = self.length_seconds
61
+
62
+ thumbnail_url = self.thumbnail_url
63
+
64
+ field_dict: dict[str, Any] = {}
65
+ field_dict.update(self.additional_properties)
66
+ field_dict.update(
67
+ {
68
+ "episodeNumber": episode_number,
69
+ }
70
+ )
71
+ if anilist_episode_id is not UNSET:
72
+ field_dict["anilistEpisodeId"] = anilist_episode_id
73
+ if title_english is not UNSET:
74
+ field_dict["titleEnglish"] = title_english
75
+ if title_romaji is not UNSET:
76
+ field_dict["titleRomaji"] = title_romaji
77
+ if title_japanese is not UNSET:
78
+ field_dict["titleJapanese"] = title_japanese
79
+ if description is not UNSET:
80
+ field_dict["description"] = description
81
+ if aired_at is not UNSET:
82
+ field_dict["airedAt"] = aired_at
83
+ if length_seconds is not UNSET:
84
+ field_dict["lengthSeconds"] = length_seconds
85
+ if thumbnail_url is not UNSET:
86
+ field_dict["thumbnailUrl"] = thumbnail_url
87
+
88
+ return field_dict
89
+
90
+ @classmethod
91
+ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
92
+ d = dict(src_dict)
93
+ episode_number = d.pop("episodeNumber")
94
+
95
+ anilist_episode_id = d.pop("anilistEpisodeId", UNSET)
96
+
97
+ title_english = d.pop("titleEnglish", UNSET)
98
+
99
+ title_romaji = d.pop("titleRomaji", UNSET)
100
+
101
+ title_japanese = d.pop("titleJapanese", UNSET)
102
+
103
+ description = d.pop("description", UNSET)
104
+
105
+ _aired_at = d.pop("airedAt", UNSET)
106
+ aired_at: datetime.datetime | Unset
107
+ if isinstance(_aired_at, Unset):
108
+ aired_at = UNSET
109
+ else:
110
+ aired_at = isoparse(_aired_at)
111
+
112
+ length_seconds = d.pop("lengthSeconds", UNSET)
113
+
114
+ thumbnail_url = d.pop("thumbnailUrl", UNSET)
115
+
116
+ episode_create_request = cls(
117
+ episode_number=episode_number,
118
+ anilist_episode_id=anilist_episode_id,
119
+ title_english=title_english,
120
+ title_romaji=title_romaji,
121
+ title_japanese=title_japanese,
122
+ description=description,
123
+ aired_at=aired_at,
124
+ length_seconds=length_seconds,
125
+ thumbnail_url=thumbnail_url,
126
+ )
127
+
128
+ episode_create_request.additional_properties = d
129
+ return episode_create_request
130
+
131
+ @property
132
+ def additional_keys(self) -> list[str]:
133
+ return list(self.additional_properties.keys())
134
+
135
+ def __getitem__(self, key: str) -> Any:
136
+ return self.additional_properties[key]
137
+
138
+ def __setitem__(self, key: str, value: Any) -> None:
139
+ self.additional_properties[key] = value
140
+
141
+ def __delitem__(self, key: str) -> None:
142
+ del self.additional_properties[key]
143
+
144
+ def __contains__(self, key: str) -> bool:
145
+ return key in self.additional_properties