Describe the Bug
It seems that if you fetch episodes as part of a show or season, the Episode objects don't have all the relevant information (for e.g. Guids). When I debugged this issue, I found this issue is because of the XML returned by the Plex Media Server.
It boils down to the API call /library/metadata/<show or season ratingkey>/allLeaves. This API call returns partial Episode details and hence the object itself doesn't have many key relevant information missing
Code Snippets
Use the following function call to return episodes of a season or show
library.section(plex_tv_lib).get(show.title).episodes()
Expected Behavior
Expect to see all of the Episode attributes returned
Video._loadData(self, data)
Playable._loadData(self, data)
self._seasonNumber = None # cached season number
self.audienceRating = utils.cast(float, data.attrib.get('audienceRating'))
self.audienceRatingImage = data.attrib.get('audienceRatingImage')
self.chapters = self.findItems(data, media.Chapter)
self.chapterSource = data.attrib.get('chapterSource')
self.collections = self.findItems(data, media.Collection)
self.contentRating = data.attrib.get('contentRating')
self.directors = self.findItems(data, media.Director)
self.duration = utils.cast(int, data.attrib.get('duration'))
self.grandparentArt = data.attrib.get('grandparentArt')
self.grandparentGuid = data.attrib.get('grandparentGuid')
self.grandparentKey = data.attrib.get('grandparentKey')
self.grandparentRatingKey = utils.cast(int, data.attrib.get('grandparentRatingKey'))
self.grandparentTheme = data.attrib.get('grandparentTheme')
self.grandparentThumb = data.attrib.get('grandparentThumb')
self.grandparentTitle = data.attrib.get('grandparentTitle')
self.guids = self.findItems(data, media.Guid)
self.index = utils.cast(int, data.attrib.get('index'))
self.labels = self.findItems(data, media.Label)
self.markers = self.findItems(data, media.Marker)
self.media = self.findItems(data, media.Media)
self.originallyAvailableAt = utils.toDatetime(data.attrib.get('originallyAvailableAt'), '%Y-%m-%d')
self.parentGuid = data.attrib.get('parentGuid')
self.parentIndex = utils.cast(int, data.attrib.get('parentIndex'))
self.parentKey = data.attrib.get('parentKey')
self.parentRatingKey = utils.cast(int, data.attrib.get('parentRatingKey'))
self.parentThumb = data.attrib.get('parentThumb')
self.parentTitle = data.attrib.get('parentTitle')
self.parentYear = utils.cast(int, data.attrib.get('parentYear'))
self.producers = self.findItems(data, media.Producer)
self.rating = utils.cast(float, data.attrib.get('rating'))
self.ratingKey = utils.cast(int, data.attrib.get('ratingKey'))
self.roles = self.findItems(data, media.Role)
self.skipParent = utils.cast(bool, data.attrib.get('skipParent', '0'))
self.viewOffset = utils.cast(int, data.attrib.get('viewOffset', 0))
self.writers = self.findItems(data, media.Writer)
self.year = utils.cast(int, data.attrib.get('year'))
Additional Context
I modified the episodes method of Show and Season object to the following, to individually query metdata of each episode and copy it over. This obviously is quite expensive depending on the total number of episodes returned by the original query, but I am not familiar enough with the plex rest api to know whether there is an allLeaves alternate which will return well hydrated Episode information
def episodes(self, **kwargs):
""" Returns a list of :class:`~plexapi.video.Episode` objects in the show. """
key = f'{self.key}/allLeaves'
print("key:", key)
episodes = self.fetchItems(key, Episode, **kwargs)
for e in episodes:
episode = self.fetchItem(e.ratingKey, Episode)
e.guids = episode.guids
...
...
return episodes
Episode XML as part of the allLeaves query
<Video ratingKey="50856" key="/library/metadata/50856" parentRatingKey="50855" grandparentRatingKey="50490" guid="plex://episode/5d9c12b902391c001f5fa3fb" studio="Warner Bros. Television" type="episode" title="Pilot" grandparentKey="/library/metadata/50490" parentKey="/library/metadata/50855" grandparentTitle="The 100" parentTitle="Season 1" contentRating="TV-14" summary="97 years after a nuclear war, human kind is living in space. 100 juvenile delinquents are sent down to Earth to see if the planet is habitable." index="1" parentIndex="1" audienceRating="7.4" viewCount="1" lastViewedAt="1474750793" parentYear="2014" thumb="/library/metadata/50856/thumb/1632507116" art="/library/metadata/50490/art/1469648223" parentThumb="/library/metadata/50855/thumb/1632507114" grandparentThumb="/library/metadata/50490/thumb/1469648223" grandparentArt="/library/metadata/50490/art/1469648223" grandparentTheme="/library/metadata/50490/theme/1469648223" duration="2476478" originallyAvailableAt="2014-03-19" addedAt="1469648223" updatedAt="1632507116" audienceRatingImage="thetvdb://image.rating" chapterSource="media">
<Media id="71309" duration="2476478" bitrate="11360" width="1920" height="1080" aspectRatio="1.78" audioChannels="6" audioCodec="dca" videoCodec="h264" videoResolution="1080" container="mkv" videoFrameRate="24p" audioProfile="dts" videoProfile="high">
<Part id="216855" key="/library/parts/216855/1469506462/file.mkv" duration="2476478" file="..." size="3517310304" audioProfile="dts" container="mkv" videoProfile="high"/>
</Media>
<Director tag="Bharat Nalluri"/>
<Writer tag="Jason Rothenberg"/>
<Role tag="Terry Chen"/>
<Role tag="Kelly Hu"/>
<Role tag="Aaron Miko"/>
</Video>
Episode XML as a direct Episode metdata query
<Video ratingKey="50856" key="/library/metadata/50856" parentRatingKey="50855" grandparentRatingKey="50490" guid="plex://episode/5d9c12b902391c001f5fa3fb" parentGuid="plex://season/602e6816fdd281002cdf6852" grandparentGuid="plex://show/5d9c086d705e7a001e6dc723" type="episode" title="Pilot" grandparentKey="/library/metadata/50490" parentKey="/library/metadata/50855" librarySectionTitle="TV Shows" librarySectionID="2" librarySectionKey="/library/sections/2" grandparentTitle="The 100" parentTitle="Season 1" contentRating="TV-14" summary="97 years after a nuclear war, human kind is living in space. 100 juvenile delinquents are sent down to Earth to see if the planet is habitable." index="1" parentIndex="1" audienceRating="7.4" viewCount="1" lastViewedAt="1474750793" parentYear="2014" thumb="/library/metadata/50856/thumb/1632507116" art="/library/metadata/50490/art/1632507112" parentThumb="/library/metadata/50855/thumb/1632507114" grandparentThumb="/library/metadata/50490/thumb/1632507112" grandparentArt="/library/metadata/50490/art/1632507112" grandparentTheme="/library/metadata/50490/theme/1632507112" duration="2476478" originallyAvailableAt="2014-03-19" addedAt="1469648223" updatedAt="1632507116" audienceRatingImage="thetvdb://image.rating" chapterSource="media">
<Media id="71309" duration="2476478" bitrate="11360" width="1920" height="1080" aspectRatio="1.78" audioChannels="6" audioCodec="dca" videoCodec="h264" videoResolution="1080" container="mkv" videoFrameRate="24p" audioProfile="dts" videoProfile="high">
<Part accessible="1" exists="1" id="216855" key="/library/parts/216855/1469506462/file.mkv" duration="2476478" file="..." size="3517310304" audioProfile="dts" container="mkv" deepAnalysisVersion="6" requiredBandwidths="20597,17390,15016,13626,12661,12575,12575,12575" videoProfile="high">
<Stream id="495581" streamType="1" default="1" codec="h264" index="0" bitrate="9851" language="English" languageTag="en" languageCode="eng" bitDepth="8" chromaLocation="left" chromaSubsampling="4:2:0" codedHeight="1088" codedWidth="1920" frameRate="23.976" hasScalingMatrix="0" height="1080" level="41" profile="high" refFrames="4" requiredBandwidths="19088,15881,13506,12116,11152,11081,11081,11081" scanType="progressive" width="1920" displayTitle="1080p (H.264)" extendedDisplayTitle="1080p (H.264)"> </Stream>
<Stream id="495582" streamType="2" selected="1" default="1" codec="dca" index="1" channels="6" bitrate="1509" language="English" languageTag="en" languageCode="eng" audioChannelLayout="5.1(side)" bitDepth="24" profile="dts" requiredBandwidths="1507,1507,1507,1507,1507,1507,1507,1507" samplingRate="48000" displayTitle="English (DTS 5.1)" extendedDisplayTitle="English (DTS 5.1)"> </Stream>
</Part>
</Media>
<Director id="110593" filter="director=110593" tag="Bharat Nalluri"/>
<Writer id="12167" filter="writer=12167" tag="Jason Rothenberg"/>
<Producer id="110597" filter="producer=110597" tag="Jae Marchant"/>
<Guid id="imdb://tt2912494"/>
<Guid id="tmdb://972730"/>
<Guid id="tvdb://4543295"/>
<Role id="207969" filter="actor=207969" tag="Terry Chen" role="Commander Shumway" thumb="https://metadata-static.plex.tv/people/5d7768254de0ee001fcc84fe.jpg"/>
<Role id="218383" filter="actor=218383" tag="Kelly Hu" role="Callie 'Cece' Cartwig" thumb="https://metadata-static.plex.tv/9/people/9aea42eb970f07be06971b27c81ec1cf.jpg"/>
<Role id="110579" filter="actor=110579" tag="Aaron Miko" role="John Mbege" thumb="https://metadata-static.plex.tv/a/people/a949280aabc2f82c34d75eaed02c08d2.jpg"/>
<Role id="110580" filter="actor=110580" tag="Austin J.M. Ross" role="Tim Barlet (uncredited)"/>
<Role id="110581" filter="actor=110581" tag="Conrad Whitaker" role="Tranq Gun Guard"/>
<Role id="110582" filter="actor=110582" tag="Jojo Ahenkorah" role="Costa (uncredited)" thumb="https://metadata-static.plex.tv/people/5d7768c696b655001fdc16b2.jpg"/>
<Role id="110583" filter="actor=110583" tag="Genevieve Buechner" role="Fox" thumb="https://metadata-static.plex.tv/people/5d77683f103a2d001f56a3eb.jpg"/>
<Role id="110584" filter="actor=110584" tag="Reese Alexander" role="Guard #1" thumb="https://metadata-static.plex.tv/people/5d77682d8718ba001e312f89.jpg"/>
<Role id="230531" filter="actor=230531" tag="Kett Turton" role="Apprentice" thumb="https://image.tmdb.org/t/p/original/dsmW4TgzKUcLpWyE3hhZ8POmjS2.jpg"/>
<Role id="110585" filter="actor=110585" tag="Shaw Madson" role="Angry Parent #2" thumb="https://metadata-static.plex.tv/people/5d7768385af944001f1faa8d.jpg"/>
<Role id="110586" filter="actor=110586" tag="Tatiana Turner" role="Angry Parent #1" thumb="https://metadata-static.plex.tv/7/people/79d47bb72e42c995fc43322bf581506d.jpg"/>
<Role id="110587" filter="actor=110587" tag="Fred Cruz" role="Louis Montgomery (uncredited)"/>
<Role id="12198" filter="actor=12198" tag="Richard Harmon" role="John Murphy" thumb="https://metadata-static.plex.tv/0/people/05151900908cd11eb29e4d76ec974cef.jpg"/>
<Role id="213265" filter="actor=213265" tag="Eli Goree" role="Wells Jaha" thumb="https://metadata-static.plex.tv/a/people/a9229d416883c57799d5e1f4c9976cfd.jpg"/>
<Role id="110588" filter="actor=110588" tag="James Forrester" role="Juvenile Delinquent (uncredited)"/>
<Role id="247576" filter="actor=247576" tag="Alessandro Juliani" role="Jacapo Sinclair" thumb="https://metadata-static.plex.tv/people/5d776833103a2d001f567561.jpg"/>
<Role id="110589" filter="actor=110589" tag="Sachin Sahel" role="Dr. Eric Jackson" thumb="https://metadata-static.plex.tv/people/5d776903f617c9002015bf85.jpg"/>
<Chapter id="67" filter="thumb=67" index="1" startTimeOffset="0" endTimeOffset="162662" thumb="/library/media/71309/chapterImages/1"/>
<Chapter id="67" filter="thumb=67" index="2" startTimeOffset="162662" endTimeOffset="609108" thumb="/library/media/71309/chapterImages/2"/>
<Chapter id="67" filter="thumb=67" index="3" startTimeOffset="609108" endTimeOffset="1067316" thumb="/library/media/71309/chapterImages/3"/>
<Chapter id="67" filter="thumb=67" index="4" startTimeOffset="1067316" endTimeOffset="1473180" thumb="/library/media/71309/chapterImages/4"/>
<Chapter id="67" filter="thumb=67" index="5" startTimeOffset="1473180" endTimeOffset="1812477" thumb="/library/media/71309/chapterImages/5"/>
<Chapter id="67" filter="thumb=67" index="6" startTimeOffset="1812477" endTimeOffset="2134090" thumb="/library/media/71309/chapterImages/6"/>
<Chapter id="67" filter="thumb=67" index="7" startTimeOffset="2134090" endTimeOffset="2447070" thumb="/library/media/71309/chapterImages/7"/>
<Chapter id="67" filter="thumb=67" index="8" startTimeOffset="2447070" endTimeOffset="2476480" thumb="/library/media/71309/chapterImages/8"/>
<Extras size="0"> </Extras>
<Related> </Related>
</Video>
Operating System and Version
Windows 10
Plex Media Server Version
1.51.1.3185-700af1eb
Python Version
3.10
PlexAPI Version
4.12.1
Describe the Bug
It seems that if you fetch episodes as part of a show or season, the Episode objects don't have all the relevant information (for e.g. Guids). When I debugged this issue, I found this issue is because of the XML returned by the Plex Media Server.
It boils down to the API call
/library/metadata/<show or season ratingkey>/allLeaves. This API call returns partial Episode details and hence the object itself doesn't have many key relevant information missingCode Snippets
Expected Behavior
Expect to see all of the Episode attributes returned
Additional Context
I modified the episodes method of Show and Season object to the following, to individually query metdata of each episode and copy it over. This obviously is quite expensive depending on the total number of episodes returned by the original query, but I am not familiar enough with the plex rest api to know whether there is an allLeaves alternate which will return well hydrated Episode information
Episode XML as part of the allLeaves query
Episode XML as a direct Episode metdata query
Operating System and Version
Windows 10
Plex Media Server Version
1.51.1.3185-700af1eb
Python Version
3.10
PlexAPI Version
4.12.1