MouseTools 3.1.0.dev1__tar.gz → 4.0.0__tar.gz

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 (57) hide show
  1. {mousetools-3.1.0.dev1 → mousetools-4.0.0}/LICENSE +1 -1
  2. mousetools-4.0.0/PKG-INFO +108 -0
  3. mousetools-4.0.0/README.md +90 -0
  4. {mousetools-3.1.0.dev1 → mousetools-4.0.0}/mousetools/__init__.py +1 -1
  5. mousetools-4.0.0/mousetools/api/menu.py +433 -0
  6. mousetools-4.0.0/mousetools/auth.py +112 -0
  7. mousetools-4.0.0/mousetools/channels/__init__.py +46 -0
  8. mousetools-4.0.0/mousetools/channels/enums.py +67 -0
  9. mousetools-4.0.0/mousetools/channels/facilities/__init__.py +520 -0
  10. mousetools-4.0.0/mousetools/channels/facilities/enums.py +30 -0
  11. mousetools-4.0.0/mousetools/channels/facilitystatus/__init__.py +153 -0
  12. mousetools-4.0.0/mousetools/mixins/__init__.py +0 -0
  13. mousetools-4.0.0/mousetools/mixins/couchbase.py +80 -0
  14. mousetools-4.0.0/mousetools/mixins/disney.py +36 -0
  15. mousetools-4.0.0/mousetools/resources/environments.bin +0 -0
  16. mousetools-4.0.0/mousetools.egg-info/PKG-INFO +108 -0
  17. mousetools-4.0.0/mousetools.egg-info/SOURCES.txt +22 -0
  18. {mousetools-3.1.0.dev1/MouseTools.egg-info → mousetools-4.0.0/mousetools.egg-info}/requires.txt +1 -0
  19. mousetools-4.0.0/pyproject.toml +113 -0
  20. mousetools-4.0.0/tests/test_mixins.py +24 -0
  21. mousetools-3.1.0.dev1/MouseTools.egg-info/PKG-INFO +0 -77
  22. mousetools-3.1.0.dev1/MouseTools.egg-info/SOURCES.txt +0 -38
  23. mousetools-3.1.0.dev1/PKG-INFO +0 -77
  24. mousetools-3.1.0.dev1/README.md +0 -62
  25. mousetools-3.1.0.dev1/mousetools/auth.py +0 -70
  26. mousetools-3.1.0.dev1/mousetools/entities/__init__.py +0 -43
  27. mousetools-3.1.0.dev1/mousetools/entities/attraction.py +0 -12
  28. mousetools-3.1.0.dev1/mousetools/entities/base.py +0 -487
  29. mousetools-3.1.0.dev1/mousetools/entities/character.py +0 -12
  30. mousetools-3.1.0.dev1/mousetools/entities/destination.py +0 -16
  31. mousetools-3.1.0.dev1/mousetools/entities/dining_event.py +0 -12
  32. mousetools-3.1.0.dev1/mousetools/entities/dinner_show.py +0 -12
  33. mousetools-3.1.0.dev1/mousetools/entities/entertainment.py +0 -12
  34. mousetools-3.1.0.dev1/mousetools/entities/entertainment_venue.py +0 -12
  35. mousetools-3.1.0.dev1/mousetools/entities/event.py +0 -12
  36. mousetools-3.1.0.dev1/mousetools/entities/guest_services.py +0 -12
  37. mousetools-3.1.0.dev1/mousetools/entities/land.py +0 -12
  38. mousetools-3.1.0.dev1/mousetools/entities/menu.py +0 -223
  39. mousetools-3.1.0.dev1/mousetools/entities/merchandise_facility.py +0 -12
  40. mousetools-3.1.0.dev1/mousetools/entities/park.py +0 -42
  41. mousetools-3.1.0.dev1/mousetools/entities/point_of_interest.py +0 -12
  42. mousetools-3.1.0.dev1/mousetools/entities/resort.py +0 -12
  43. mousetools-3.1.0.dev1/mousetools/entities/resort_area.py +0 -12
  44. mousetools-3.1.0.dev1/mousetools/entities/restaurant.py +0 -52
  45. mousetools-3.1.0.dev1/mousetools/exceptions.py +0 -17
  46. mousetools-3.1.0.dev1/mousetools/ids.py +0 -96
  47. mousetools-3.1.0.dev1/mousetools/mixins/disney.py +0 -55
  48. mousetools-3.1.0.dev1/mousetools/mixins/themeparksapi.py +0 -128
  49. mousetools-3.1.0.dev1/mousetools/urls.py +0 -4
  50. mousetools-3.1.0.dev1/pyproject.toml +0 -115
  51. mousetools-3.1.0.dev1/tests/test_auth.py +0 -8
  52. mousetools-3.1.0.dev1/tests/test_entities.py +0 -239
  53. mousetools-3.1.0.dev1/tests/test_ids.py +0 -103
  54. {mousetools-3.1.0.dev1/mousetools/mixins → mousetools-4.0.0/mousetools/api}/__init__.py +0 -0
  55. {mousetools-3.1.0.dev1/MouseTools.egg-info → mousetools-4.0.0/mousetools.egg-info}/dependency_links.txt +0 -0
  56. {mousetools-3.1.0.dev1/MouseTools.egg-info → mousetools-4.0.0/mousetools.egg-info}/top_level.txt +0 -0
  57. {mousetools-3.1.0.dev1 → mousetools-4.0.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Scott Caratozzolo
3
+ Copyright (c) 2018-2025 Scott Caratozzolo
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: mousetools
3
+ Version: 4.0.0
4
+ Summary: An unofficial Python wrapper for Disney's API
5
+ Author: Scott Caratozzolo
6
+ License-Expression: MIT
7
+ Project-URL: repository, https://gitlab.com/caratozzoloxyz/public/MouseTools
8
+ Project-URL: documentation, https://caratozzoloxyz.gitlab.io/public/MouseTools/
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: <4.0,>=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: httpx>=0.27.2
15
+ Requires-Dist: pycryptodome>=3.22.0
16
+ Requires-Dist: tzdata>=2024.1
17
+ Dynamic: license-file
18
+
19
+ # MouseTools
20
+
21
+ [![PyPI version](https://badge.fury.io/py/MouseTools.svg)](https://badge.fury.io/py/MouseTools) [![Downloads](https://pepy.tech/badge/mousetools)](https://pepy.tech/project/mousetools)
22
+
23
+
24
+ An unofficial Python wrapper for the Disney API. Data is pulled directly from Disney. This package supports Walt Disney World and Disneyland.
25
+
26
+ ### Installation
27
+ You can install using pip:
28
+ ```bash
29
+ pip install mousetools
30
+ ```
31
+ You can also install directly from this repo in case of any changes not uploaded to Pypi.
32
+ ```bash
33
+ pip install git+https://gitlab.com/caratozzoloxyz/public/MouseTools
34
+ ```
35
+
36
+ # Usage
37
+
38
+ The Disney API considers everything an entity. Attractions, resorts, restaurants, etc, are all entities. Entities belong to channels, or a group of entities.
39
+
40
+ ## Getting Started
41
+
42
+ You'll want to create a facility channel object.
43
+
44
+ ```python
45
+ from mousetools.channels.facilities import Attraction
46
+
47
+ pirates = Attraction("wdw.facilities.1_0.en_us.attraction.80010177;entityType=Attraction")
48
+ ```
49
+
50
+
51
+ All Facility Entities inherit from [FacilityChildChannel][mousetools.channels.facilities.FacilityChildChannel].
52
+
53
+ ```python
54
+ print(pirates.name)
55
+ # 'Pirates of the Caribbean'
56
+
57
+ print(big_thunder.ancestor_theme_park_id)
58
+ # '80007944;entityType=theme-park'
59
+ ```
60
+
61
+ In order to access a facility's live data, you'll need a [FacilityStatusChildChannel][mousetools.channels.facilitystatus.FacilityStatusChildChannel]. Fortunately for you, this can be quickly done from the facility object.
62
+ ```python
63
+ fs = a.get_facility_status_channel()
64
+ print(fs.get_wait_time())
65
+ # 15
66
+
67
+ print(fs.get_status())
68
+ # 'Operating'
69
+ ```
70
+
71
+ Alternatively, you can create the object yourself.
72
+ ```python
73
+ from mousetools.channels.facilitystatus import FacilityStatusChannel
74
+
75
+ fsc = FacilityStatusChannel("wdw.facilitystatus.1_0.80010177;entityType=Attraction", lazy_load=False)
76
+ print(fs.last_update)
77
+ # 2025-05-15 22:52:52.176069-04:00
78
+ ```
79
+
80
+ ***NOTE: All channels are lazy loaded, meaning there is no request sent to load the data until an object's attributes are accessed. This allows objects to be created faster, and reduce requests to Disney's servers until the data is actually needed.***
81
+
82
+
83
+ For ease of use, you can use the available [channel enums][mousetools.channels.enums] or [facility enums][mousetools.channels.facilities.enums] to get access to a destination facility's children channels.
84
+
85
+ ```python
86
+ from mousetools.channels.facilities import FacilityChannel, ThemePark
87
+ from mousetools.channel.facilities.enums import WaltDisneyWorldParkChannelIds
88
+ from mousetools.channels.facilitystatus import FacilityStatusChannel
89
+ from mousetools.channels.enums import WDWCouchbaseChannels, DLRCouchbaseChannels
90
+
91
+ wdw = FacilityChannel(WDWCouchbaseChannels.FACILITIES)
92
+ print(list(wdw.get_children_attractions()))
93
+ # [Attraction(wdw.facilities.1_0.en_us.123), Attraction(wdw.facilities.1_0.en_us.456), ...]
94
+
95
+ dlr = FacilityStatusChannel(DLRCouchbaseChannels.FACILITY_STATUS)
96
+ print(dlr.get_children_channel_ids())
97
+ # ["dlr.facilitystatus.1_0.123", "dlr.facilitystatus.1_0.456", ...]
98
+
99
+ mk = ThemePark(WaltDisneyWorldParkChannelIds.MAGIC_KINGDOM, lazy_load=False)
100
+ print(mk.description)
101
+ # "Enter a Land Where Fantasy Reigns"
102
+ ```
103
+
104
+ ### License
105
+ This project is distributed under the MIT license. For more information see [LICENSE](https://gitlab.com/caratozzoloxyz/public/MouseTools/-/blob/master/LICENSE?ref_type=heads)
106
+
107
+ ### Disclaimer
108
+ This project is in no way affiliated with The Walt Disney Company and all use of Disney Services is subject to the [Disney Terms of Use](https://disneytermsofuse.com/).
@@ -0,0 +1,90 @@
1
+ # MouseTools
2
+
3
+ [![PyPI version](https://badge.fury.io/py/MouseTools.svg)](https://badge.fury.io/py/MouseTools) [![Downloads](https://pepy.tech/badge/mousetools)](https://pepy.tech/project/mousetools)
4
+
5
+
6
+ An unofficial Python wrapper for the Disney API. Data is pulled directly from Disney. This package supports Walt Disney World and Disneyland.
7
+
8
+ ### Installation
9
+ You can install using pip:
10
+ ```bash
11
+ pip install mousetools
12
+ ```
13
+ You can also install directly from this repo in case of any changes not uploaded to Pypi.
14
+ ```bash
15
+ pip install git+https://gitlab.com/caratozzoloxyz/public/MouseTools
16
+ ```
17
+
18
+ # Usage
19
+
20
+ The Disney API considers everything an entity. Attractions, resorts, restaurants, etc, are all entities. Entities belong to channels, or a group of entities.
21
+
22
+ ## Getting Started
23
+
24
+ You'll want to create a facility channel object.
25
+
26
+ ```python
27
+ from mousetools.channels.facilities import Attraction
28
+
29
+ pirates = Attraction("wdw.facilities.1_0.en_us.attraction.80010177;entityType=Attraction")
30
+ ```
31
+
32
+
33
+ All Facility Entities inherit from [FacilityChildChannel][mousetools.channels.facilities.FacilityChildChannel].
34
+
35
+ ```python
36
+ print(pirates.name)
37
+ # 'Pirates of the Caribbean'
38
+
39
+ print(big_thunder.ancestor_theme_park_id)
40
+ # '80007944;entityType=theme-park'
41
+ ```
42
+
43
+ In order to access a facility's live data, you'll need a [FacilityStatusChildChannel][mousetools.channels.facilitystatus.FacilityStatusChildChannel]. Fortunately for you, this can be quickly done from the facility object.
44
+ ```python
45
+ fs = a.get_facility_status_channel()
46
+ print(fs.get_wait_time())
47
+ # 15
48
+
49
+ print(fs.get_status())
50
+ # 'Operating'
51
+ ```
52
+
53
+ Alternatively, you can create the object yourself.
54
+ ```python
55
+ from mousetools.channels.facilitystatus import FacilityStatusChannel
56
+
57
+ fsc = FacilityStatusChannel("wdw.facilitystatus.1_0.80010177;entityType=Attraction", lazy_load=False)
58
+ print(fs.last_update)
59
+ # 2025-05-15 22:52:52.176069-04:00
60
+ ```
61
+
62
+ ***NOTE: All channels are lazy loaded, meaning there is no request sent to load the data until an object's attributes are accessed. This allows objects to be created faster, and reduce requests to Disney's servers until the data is actually needed.***
63
+
64
+
65
+ For ease of use, you can use the available [channel enums][mousetools.channels.enums] or [facility enums][mousetools.channels.facilities.enums] to get access to a destination facility's children channels.
66
+
67
+ ```python
68
+ from mousetools.channels.facilities import FacilityChannel, ThemePark
69
+ from mousetools.channel.facilities.enums import WaltDisneyWorldParkChannelIds
70
+ from mousetools.channels.facilitystatus import FacilityStatusChannel
71
+ from mousetools.channels.enums import WDWCouchbaseChannels, DLRCouchbaseChannels
72
+
73
+ wdw = FacilityChannel(WDWCouchbaseChannels.FACILITIES)
74
+ print(list(wdw.get_children_attractions()))
75
+ # [Attraction(wdw.facilities.1_0.en_us.123), Attraction(wdw.facilities.1_0.en_us.456), ...]
76
+
77
+ dlr = FacilityStatusChannel(DLRCouchbaseChannels.FACILITY_STATUS)
78
+ print(dlr.get_children_channel_ids())
79
+ # ["dlr.facilitystatus.1_0.123", "dlr.facilitystatus.1_0.456", ...]
80
+
81
+ mk = ThemePark(WaltDisneyWorldParkChannelIds.MAGIC_KINGDOM, lazy_load=False)
82
+ print(mk.description)
83
+ # "Enter a Land Where Fantasy Reigns"
84
+ ```
85
+
86
+ ### License
87
+ This project is distributed under the MIT license. For more information see [LICENSE](https://gitlab.com/caratozzoloxyz/public/MouseTools/-/blob/master/LICENSE?ref_type=heads)
88
+
89
+ ### Disclaimer
90
+ This project is in no way affiliated with The Walt Disney Company and all use of Disney Services is subject to the [Disney Terms of Use](https://disneytermsofuse.com/).
@@ -3,5 +3,5 @@ import logging
3
3
  logger = logging.getLogger(__name__)
4
4
  logger.addHandler(logging.NullHandler())
5
5
 
6
- __version__ = "3.1.0-dev.1" # will be set at runtime
6
+ __version__ = "0.0.0" # will be set at runtime
7
7
  logger.info(f"MouseTools version: {__version__}")
@@ -0,0 +1,433 @@
1
+ import typing
2
+
3
+ from mousetools.auth import auth_obj
4
+ from mousetools.mixins.disney import DisneyAPIMixin
5
+
6
+ # menus -> menu -> menugroups -> menuitems
7
+
8
+
9
+ class MenuItem:
10
+ def __init__(self, raw_item_data: dict, parent_resturant_id: typing.Optional[str] = None):
11
+ self._raw_item_data = raw_item_data
12
+ self._parent_restaurant_id = parent_resturant_id
13
+
14
+ def __repr__(self) -> str:
15
+ return f"MenuItem(entity_id={self.entity_id}, parent_resturant_id={self._parent_restaurant_id})"
16
+
17
+ @property
18
+ def entity_id(self) -> typing.Optional[str]:
19
+ """
20
+ The entity id of the menu item.
21
+
22
+ Returns:
23
+ (typing.Optional[str]): The entity id of the menu item.
24
+ """
25
+ try:
26
+ return self._raw_item_data["id"]
27
+ except KeyError:
28
+ return None
29
+
30
+ @property
31
+ def pc_short_name(self) -> typing.Optional[str]:
32
+ """
33
+ The short name of the menu item.
34
+
35
+ Returns:
36
+ (typing.Optional[str]): The short name of the menu item.
37
+ """
38
+ try:
39
+ return self._raw_item_data["names"]["PCShort"]
40
+ except KeyError:
41
+ return None
42
+
43
+ @property
44
+ def pc_long_name(self) -> typing.Optional[str]:
45
+ """
46
+ The long name of the menu item.
47
+
48
+ Returns:
49
+ (typing.Optional[str]): The long name of the menu item.
50
+ """
51
+ try:
52
+ return self._raw_item_data["names"]["PCLong"]
53
+ except KeyError:
54
+ return None
55
+
56
+ @property
57
+ def mobile_short_name(self) -> typing.Optional[str]:
58
+ """
59
+ The short name of the menu item.
60
+
61
+ Returns:
62
+ (typing.Optional[str]): The short name of the menu item.
63
+ """
64
+ try:
65
+ return self._raw_item_data["names"]["MobileShort"]
66
+ except KeyError:
67
+ return None
68
+
69
+ @property
70
+ def mobile_long_name(self) -> typing.Optional[str]:
71
+ """
72
+ The long name of the menu item.
73
+
74
+ Returns:
75
+ (typing.Optional[str]): The long name of the menu item.
76
+ """
77
+ try:
78
+ return self._raw_item_data["names"]["MobileLong"]
79
+ except KeyError:
80
+ return None
81
+
82
+ @property
83
+ def mickey_check(self) -> typing.Optional[bool]:
84
+ """
85
+ Whether the menu item is mickey check.
86
+
87
+ Returns:
88
+ (typing.Optional[bool]): Whether the menu item is mickey check.
89
+ """
90
+ try:
91
+ return self._raw_item_data["mickeyCheck"]
92
+ except KeyError:
93
+ return None
94
+
95
+ @property
96
+ def pc_long_description(self) -> typing.Optional[str]:
97
+ """
98
+ The long description of the menu item.
99
+
100
+ Returns:
101
+ (typing.Optional[str]): The long description of the menu item.
102
+ """
103
+ try:
104
+ return self._raw_item_data["descriptions"]["PCLong"]["text"]
105
+ except KeyError:
106
+ return None
107
+
108
+ @property
109
+ def mobile_short_description(self) -> typing.Optional[str]:
110
+ """
111
+ The short description of the menu item.
112
+
113
+ Returns:
114
+ (typing.Optional[str]): The short description of the menu item.
115
+ """
116
+ try:
117
+ return self._raw_item_data["descriptions"]["MobileShort"]["text"]
118
+ except KeyError:
119
+ return None
120
+
121
+ @property
122
+ def default_selection(self) -> typing.Optional[bool]:
123
+ """
124
+ Whether the menu item is the default selection.
125
+
126
+ Returns:
127
+ (typing.Optional[bool]): Whether the menu item is the default selection.
128
+ """
129
+ try:
130
+ return self._raw_item_data["defaultSelection"]
131
+ except KeyError:
132
+ return None
133
+
134
+ @property
135
+ def prices(self) -> typing.Optional[dict]:
136
+ """
137
+ The prices of the menu item.
138
+
139
+ Returns:
140
+ (typing.Optional[dict]): The prices of the menu item.
141
+ """
142
+ try:
143
+ return self._raw_item_data["prices"]
144
+ except KeyError:
145
+ return None
146
+
147
+ @property
148
+ def per_serving_without_tax(self) -> typing.Optional[float]:
149
+ """
150
+ The per serving without tax of the menu item.
151
+
152
+ Returns:
153
+ (typing.Optional[float]): The per serving without tax of the menu item.
154
+ """
155
+ try:
156
+ return self._raw_item_data["prices"]["PerServing"]["withoutTax"]
157
+ except KeyError:
158
+ return None
159
+
160
+
161
+ class MenuGroup:
162
+ def __init__(self, raw_menu_group_data: dict, parent_restaurant_id: typing.Optional[str] = None):
163
+ self._raw_menu_group_data = raw_menu_group_data
164
+ self._parent_restaurant_id = parent_restaurant_id
165
+
166
+ def __str__(self) -> str:
167
+ return f"MenuGroup(menu_group_type={self.menu_group_type}, parent_restaurant_id={self._parent_restaurant_id})"
168
+
169
+ @property
170
+ def menu_group_type(self) -> typing.Optional[str]:
171
+ """
172
+ The type of the menu group.
173
+
174
+ Returns:
175
+ (typing.Optional[str]): The type of the menu group.
176
+ """
177
+ try:
178
+ return self._raw_menu_group_data["menuGroupType"]
179
+ except KeyError:
180
+ return None
181
+
182
+ @property
183
+ def multiple_price_types(self) -> typing.Optional[bool]:
184
+ """
185
+ Whether the menu group has multiple price types.
186
+
187
+ Returns:
188
+ (typing.Optional[bool]): Whether the menu group has multiple price types.
189
+ """
190
+ try:
191
+ return self._raw_menu_group_data["multiplePriceTypes"]
192
+ except KeyError:
193
+ return None
194
+
195
+ @property
196
+ def mickey_check_items(self) -> typing.Optional[bool]:
197
+ """
198
+ Whether the menu group has mickey check items.
199
+
200
+ Returns:
201
+ (typing.Optional[bool]): Whether the menu group has mickey check items.
202
+ """
203
+ try:
204
+ return self._raw_menu_group_data["mickeyCheckItems"]
205
+ except KeyError:
206
+ return None
207
+
208
+ @property
209
+ def names(self) -> typing.Optional[dict]:
210
+ """
211
+ The names of the menu group.
212
+
213
+ Returns:
214
+ (typing.Optional[dict]): The names of the menu group.
215
+ """
216
+ try:
217
+ return self._raw_menu_group_data["names"]
218
+ except KeyError:
219
+ return None
220
+
221
+ @property
222
+ def pc_short_name(self) -> typing.Optional[str]:
223
+ """
224
+ The short name of the menu group.
225
+
226
+ Returns:
227
+ (typing.Optional[str]): The short name of the menu group.
228
+ """
229
+ try:
230
+ return self._raw_menu_group_data["names"]["PCShort"]
231
+ except KeyError:
232
+ return None
233
+
234
+ @property
235
+ def pc_long_name(self) -> typing.Optional[str]:
236
+ """
237
+ The long name of the menu group.
238
+
239
+ Returns:
240
+ (typing.Optional[str]): The long name of the menu group.
241
+ """
242
+ try:
243
+ return self._raw_menu_group_data["names"]["PCLong"]
244
+ except KeyError:
245
+ return None
246
+
247
+ @property
248
+ def mobile_short_name(self) -> typing.Optional[str]:
249
+ """
250
+ The short name of the menu group.
251
+
252
+ Returns:
253
+ (typing.Optional[str]): The short name of the menu group.
254
+ """
255
+ try:
256
+ return self._raw_menu_group_data["names"]["MobileShort"]
257
+ except KeyError:
258
+ return None
259
+
260
+ @property
261
+ def mobile_long_name(self) -> typing.Optional[str]:
262
+ """
263
+ The long name of the menu group.
264
+
265
+ Returns:
266
+ (typing.Optional[str]): The long name of the menu group.
267
+ """
268
+ try:
269
+ return self._raw_menu_group_data["names"]["MobileLong"]
270
+ except KeyError:
271
+ return None
272
+
273
+ @property
274
+ def menu_items(self) -> typing.Optional[list[MenuItem]]:
275
+ """
276
+ The menu items of the menu group.
277
+
278
+ Returns:
279
+ (typing.Optional[list[MenuItem]]): The menu items of the menu group.
280
+ """
281
+ try:
282
+ return [MenuItem(i, self._parent_restaurant_id) for i in self._raw_menu_group_data["menuItems"]]
283
+ except KeyError:
284
+ return None
285
+
286
+
287
+ class Menu:
288
+ def __init__(self, raw_menu_data: dict, parent_restaurant_id: typing.Optional[str] = None):
289
+ self._raw_menu_data = raw_menu_data
290
+ self._parent_restaurant_id = parent_restaurant_id
291
+
292
+ def __str__(self):
293
+ return f"Menu(entity_id={self.entity_id}, menu_type={self.menu_type}, parent_restaurant_id={self._parent_restaurant_id})"
294
+
295
+ @property
296
+ def entity_id(self) -> typing.Optional[str]:
297
+ """
298
+ The entity id of the menu.
299
+
300
+ Returns:
301
+ (typing.Optional[str]): The entity id of the menu.
302
+ """
303
+ try:
304
+ return self._raw_menu_data["id"]
305
+ except KeyError:
306
+ return None
307
+
308
+ @property
309
+ def menu_type(self) -> typing.Optional[str]:
310
+ """
311
+ The type of the menu.
312
+
313
+ Returns:
314
+ (typing.Optional[str]): The type of the menu.
315
+ """
316
+ try:
317
+ return self._raw_menu_data["menuType"]
318
+ except KeyError:
319
+ return None
320
+
321
+ @property
322
+ def localized_menu_type(self) -> typing.Optional[str]:
323
+ """
324
+ The localized type of the menu.
325
+
326
+ Returns:
327
+ (typing.Optional[str]): The localized type of the menu.
328
+ """
329
+ try:
330
+ return self._raw_menu_data["localizedMenuType"]
331
+ except KeyError:
332
+ return None
333
+
334
+ @property
335
+ def experience_type(self) -> typing.Optional[str]:
336
+ """
337
+ The experience type of the menu.
338
+
339
+ Returns:
340
+ (typing.Optional[str]): The experience type of the menu.
341
+ """
342
+ try:
343
+ return self._raw_menu_data["experienceType"]
344
+ except KeyError:
345
+ return None
346
+
347
+ @property
348
+ def service_style(self) -> typing.Optional[str]:
349
+ """
350
+ The service style of the menu.
351
+
352
+ Returns:
353
+ (typing.Optional[str]): The service style of the menu.
354
+ """
355
+ try:
356
+ return self._raw_menu_data["serviceStyle"]
357
+ except KeyError:
358
+ return None
359
+
360
+ @property
361
+ def primary_cuisine_type(self) -> typing.Optional[str]:
362
+ """
363
+ The primary cuisine type of the menu.
364
+
365
+ Returns:
366
+ (typing.Optional[str]): The primary cuisine type of the menu.
367
+ """
368
+ try:
369
+ return self._raw_menu_data["primaryCuisineType"]
370
+ except KeyError:
371
+ return None
372
+
373
+ @property
374
+ def secondary_cuisine_type(self) -> typing.Optional[str]:
375
+ """
376
+ The secondary cuisine type of the menu.
377
+
378
+ Returns:
379
+ (typing.Optional[str]): The secondary cuisine type of the menu.
380
+ """
381
+ try:
382
+ return self._raw_menu_data["secondaryCuisineType"]
383
+ except KeyError:
384
+ return None
385
+
386
+ @property
387
+ def menu_groups(self) -> list[MenuGroup]:
388
+ """
389
+ The menu groups of the menu.
390
+
391
+ Returns:
392
+ (list[MenuGroup]): The menu items of the menu.
393
+ """
394
+ try:
395
+ return [MenuGroup(i, self._parent_restaurant_id) for i in self._raw_menu_data["menuGroups"]]
396
+ except KeyError:
397
+ return []
398
+
399
+
400
+ class Menus(DisneyAPIMixin):
401
+ """Class for Menu Entities."""
402
+
403
+ _menu_service_base = f"{auth_obj._environments['serviceMenuUrl']}/diningMenuSvc/orchestration/menus"
404
+
405
+ def __init__(self, restaurant_channel_id: str, lazy_load: bool = True):
406
+ self.entity_id = restaurant_channel_id.rsplit(".", 1)[-1]
407
+ self._menu_service_url = f"{self._menu_service_base}/{self.entity_id}"
408
+
409
+ if lazy_load:
410
+ self.disney_data: typing.Optional[dict] = None
411
+ else:
412
+ self.disney_data = self.get_disney_data(self.entity_id)
413
+
414
+ def __str__(self):
415
+ return f"Menus(entity_id={self.entity_id})"
416
+
417
+ def __repr__(self):
418
+ return f"Menus(restaurant_channel_id={self.entity_id})"
419
+
420
+ @property
421
+ def menus(self) -> list[Menu]:
422
+ """
423
+ Returns a list of all the menus associated with this entity.
424
+
425
+ Returns:
426
+ (list[Menu]): List of Menu objects that are associated with this entity.
427
+ """
428
+ if self.disney_data is None:
429
+ self.disney_data = self.get_disney_data(self._menu_service_url)
430
+ try:
431
+ return [Menu(i, self.entity_id) for i in self.disney_data["menus"]]
432
+ except KeyError:
433
+ return []