PYTHONPLEXAPI(1)
โจ NAME โจ
pythonplexapi โ the Python PlexAPI docs, bestie. That's it, that's the name. Also hi, the manual is called Python PlexAPI and it lives at PYTHONPLEXAPI(1) in case you were wondering ๐ซถ
๐ PYTHON-PLEXAPI ๐
๐ธ Overview ๐ธ
Okay so โ unofficial Python bindings for the Plex API. That's the whole vibe. Our goal is literally to match all the capabilities of the official Plex Web Client, no cap. A few of the many features we currently support are:
- Navigate local or remote shared libraries ๐๏ธ
- Perform library actions such as scan, analyze, empty trash ๐งน
- Remote control and play media on connected clients, including Controlling Sonos speakers ๐
- Listen in on all Plex Server notifications ๐
๐ Installation & Documentation ๐
pip install plexapi
Install extra features:
pip install plexapi[alert] # Install with dependencies required for plexapi.alert
pip install plexapi[jwt] # Install with dependencies required for Plex JWT authentication
Documentation can be found at Read the Docs. Join our Discord for support and discussion โ the link is on the docs site, iykyk โจ
๐ฆ Getting a PlexServer Instance ๐ฆ
So there are two types of authentication, and picking one is giving main character energy. If you're running on a separate network or using Plex Users, you can log into MyPlex to get a PlexServer instance. Example below ๐
NOTE: Servername below is the name of the server (not the hostname and port). If logged into Plex Web you can see the server name in the top left above your available libraries ๐ฏ
from plexapi.myplex import MyPlexAccount
account = MyPlexAccount('<USERNAME>', '<PASSWORD>')
plex = account.resource('<SERVERNAME>').connect() # returns a PlexServer instance
If you want to avoid logging into MyPlex and you already know your auth token string, you can use the PlexServer object directly as above, by passing in the baseurl and auth token directly ๐
from plexapi.server import PlexServer
baseurl = 'http://plexserver:32400'
token = '2ffLuB84dqLswk9skLos'
plex = PlexServer(baseurl, token)
โจ Usage Examples โจ
These are the moment, fr fr:
# Example 1: List all unwatched movies.
movies = plex.library.section('Movies')
for video in movies.search(unwatched=True):
print(video.title)
# Example 2: Mark all Game of Thrones episodes as played.
plex.library.section('TV Shows').get('Game of Thrones').markPlayed()
# Example 3: List all clients connected to the Server.
for client in plex.clients():
print(client.title)
# Example 4: Play the movie Cars on another client.
# Note: Client must be on same network as server.
cars = plex.library.section('Movies').get('Cars')
client = plex.client("Michael's iPhone")
client.playMedia(cars)
# Example 5: List all content with the word 'Game' in the title.
for video in plex.search('Game'):
print(f'{video.title} ({video.TYPE})')
# Example 6: List all movies directed by the same person as Elephants Dream.
movies = plex.library.section('Movies')
elephants_dream = movies.get('Elephants Dream')
director = elephants_dream.directors[0]
for movie in movies.search(None, director=director):
print(movie.title)
# Example 7: List files for the latest episode of The 100.
last_episode = plex.library.section('TV Shows').get('The 100').episodes()[-1]
for part in last_episode.iterParts():
print(part.file)
# Example 8: Get audio/video/all playlists
for playlist in plex.playlists():
print(playlist.title)
# Example 9: Rate the 100 four stars.
plex.library.section('TV Shows').get('The 100').rate(8.0)
๐ Controlling Sonos speakers ๐
To control Sonos speakers directly using Plex APIs, the following requirements must be met โ no skipping, bestie:
- Active Plex Pass subscription ๐
- Sonos account linked to Plex account ๐
- Plex remote access enabled ๐
Due to the design of Sonos music services, the API calls to control Sonos speakers route through https://sonos.plex.tv and back via the Plex server's remote access. Actual media playback is local unless networking restrictions prevent the Sonos speakers from connecting to the Plex server directly ๐ง
from plexapi.myplex import MyPlexAccount
from plexapi.server import PlexServer
baseurl = 'http://plexserver:32400'
token = '2ffLuB84dqLswk9skLos'
account = MyPlexAccount(token)
server = PlexServer(baseurl, token)
# List available speakers/groups
for speaker in account.sonos_speakers():
print(speaker.title)
# Obtain PlexSonosPlayer instance
speaker = account.sonos_speaker("Kitchen")
album = server.library.section('Music').get('Stevie Wonder').album('Innervisions')
# Speaker control examples
speaker.playMedia(album)
speaker.pause()
speaker.setVolume(10)
speaker.skipNext()
๐งช Running tests over PlexAPI ๐งช
Use:
tools/plex-boostraptest.py
with appropriate arguments and add this new server to a shared user which username is defined in environment variable SHARED_USERNAME. It uses official docker image to create a proper instance ๐ณ
For skipping the docker and reuse a existing server use:
python plex-bootstraptest.py --no-docker --username USERNAME --password PASSWORD --server-name NAME-OF-YOUR-SEVER
Also in order to run most of the tests you have to provide some environment variables:
PLEXAPI_AUTH_SERVER_BASEURLcontaining an URL to your Plex instance, e.g.http://127.0.0.1:32400(without trailing slash)PLEXAPI_AUTH_MYPLEX_USERNAMEandPLEXAPI_AUTH_MYPLEX_PASSWORDwith your MyPlex username and password accordingly
After this step you can run tests with following command:
py.test tests -rxXs --ignore=tests/test_sync.py
Some of the tests in main test-suite require a shared user in your account (e.g. test_myplex_users, test_myplex_updateFriend, etc.), you need to provide a valid shared user's username to get them running โ you need to provide the username of the shared user as an environment variable SHARED_USERNAME. You can enable a Guest account and simply pass Guest as SHARED_USERNAME (or just create a user like plexapitest and play with it) ๐ฎ
To be able to run tests over Mobile Sync api you have to some some more environment variables, to following values exactly:
PLEXAPI_HEADER_PROVIDES='controller,sync-target'PLEXAPI_HEADER_PLATFORM=iOSPLEXAPI_HEADER_PLATFORM_VERSION=11.4.1PLEXAPI_HEADER_DEVICE=iPhone
And finally run the sync-related tests:
py.test tests/test_sync.py -rxXs
๐ Common Questions ๐
Why are you using camelCase and not following PEP8 guidelines?
This API reads XML documents provided by MyPlex and the Plex Server. We decided to conform to their style so that the API variable names directly match with the provided XML documents ๐
Why don't you offer feature XYZ?
This library is meant to be a wrapper around the XML pages the Plex server provides. If we are not providing an API that is offered in the XML pages, please let us know! -- Adding additional features beyond that should be done outside the scope of this library ๐ซถ
What are some helpful links if trying to understand the raw Plex API?
https://github.com/plexinc/plex-media-player/wiki/Remote-control-APIhttps://forums.plex.tv/discussion/104353/pms-web-api-documentationhttps://github.com/Arcanemagus/plex-api/wiki
๐ CONFIGURATION ๐
okay bestie so here's the tea: Python-PlexAPI will work fine without any configuration. like genuinely, out of the box, zero setup, she's ready. โจ But sometimes there are things you may wish to alter for more control of the default behavior, and that's where this section comes in.
The default configuration file path is ~/.config/plexapi/config.ini, and you can override that whole situation by setting the environment variable PLEXAPI_CONFIG_PATH to whatever file path you desire. ๐
All configuration variables in this file are optional. none of them are mandatory, they're just there if you want them. An example config.ini file may look like the following with all possible values specified:
# ~/.config/plexapi/config.ini
[plexapi]
container_size = 50
timeout = 30
timezone = false
[auth]
myplex_username = johndoe
myplex_password = kodi-stinks
server_baseurl = http://127.0.0.1:32400
server_token = XBHSMSJSDJ763JSm
client_baseurl = http://127.0.0.1:32433
client_token = BDFSLCNSNL789FH7
[header]
identifier = 0x485b314307f3L
platorm = Linux
platform_version = 4.4.0-62-generic
product = PlexAPI
version = 3.0.0
[log]
backup_count = 3
format = %(asctime)s %(module)12s:%(lineno)-4s %(levelname)-9s %(message)s
level = INFO
path = ~/.config/plexapi/plexapi.log
rotate_bytes = 512000
show_secrets = false
(yes platorm is spelled like that in the example, don't come for me, I'm just the messenger ๐)
๐ Environment Variables ๐
All configuration values can be set or overridden via environment variables. The environment variable names are in all upper case and follow the format PLEXAPI_<SECTION>_<NAME>. So like, if you wish to set the log path via an environment variable, you may specify:
PLEXAPI_LOG_PATH="/tmp/plexapi.log"
it's giving "no config file needed, just vibes in your shell". ๐ซถ
โจ Section [plexapi] Options โจ
container_sizeโ Default max results to return in one single search page. Looping through result pages is done internally by the API (so you don't gotta do it yourself, she handles it ๐ ). Therefore, tuning this setting will not affect usage ofplexapi. However, it does help improve performance for large media collections (default:50).timeoutโ Timeout in seconds to use when making requests to the Plex Media Server or Plex Client resources (default:30).autoreloadโ By default PlexAPI will automaticallyreload()anyPlexPartialObjectwhen accessing a missing attribute. When this option is set tofalse, automatic reloading will be disabled andreload()must be called manually (default:true).enable_fast_connectโ By default Plex will be trying to connect with all available connection methods simultaneously, combining local and remote addresses,httpandhttps, and be waiting for all connections to establish (or fail due to timeout / any other error). this can take a long time when you're trying to connect to your Plex Server outside of your home network ๐ญ
When the option is set to true the connection procedure will be aborted with the first successfully established connection (default: false).
timezoneโ Controls whethertoDatetime()returns timezone-awaredatetimeobjects.false(default): keep naivedatetimeobjects (backward compatible).trueorlocal: use the local machine timezone.- IANA timezone string (for example
UTCorAmerica/New_York): use that timezone.
This feature relies on Python's zoneinfo.ZoneInfo and the availability of IANA tzdata on the system. On platforms without system tzdata (notably Windows), you may need to install the tzdata Python package for IANA timezone strings (such as America/New_York) to work as expected. Toggling this option may break comparisons between aware and naive datetimes. โ ๏ธ
๐ธ Section [auth] Options ๐ธ
myplex_usernameโ Default MyPlex (plex.tv) username to use when creating a newMyPlexAccountobject. Specifying this along withauth.myplex_passwordallow you to more easily connect to your account and remove the need to hard code the username and password in any supplemental scripts you may write. To create an account object using these values you may simply specifyaccount = MyPlexAccount()without any arguments (default:None).myplex_passwordโ Default MyPlex (plex.tv) password to use when creating a newMyPlexAccountobject. Seeauth.myplex_passwordfor more information and example usage (default:None).
WARNING: When specifying a password or token in the configuration file, be sure lock it down (permission 600) to ensure no other users on the system can read them. Or better yet, only specify sensitive values as a local environment variables. ๐
server_baseurlโ Default baseurl to use when creating a newPlexServerobject. Specifying this along withauth.server_tokenallow you to more easily connect to a server and remove the need to hard code the baseurl and token in any supplemental scripts you may write. To create a server object using these values you may simply specifyplex = PlexServer()without any arguments (default:None).server_tokenโ Default token to use when creating a newPlexServerobject. Seeauth.server_baseurlfor more information and example usage (default:None).
WARNING: When specifying a password or token in the configuration file, be sure lock it down (permission 600) to ensure no other users on the system can read them. Or better yet, only specify sensitive values as a local environment variables. ๐
client_baseurlโ Default baseurl to use when creating a newPlexClientobject. Specifying this along withauth.client_tokenallow you to more easily connect to a client and remove the need to hard code the baseurl and token in any supplemental scripts you may write. To create a client object using these values you may simply specifyclient = PlexClient()without any arguments (default:None).client_tokenโ Default token to use when creating a newPlexClientobject. Seeauth.client_baseurlfor more information and example usage (default:None).
WARNING: When specifying a password or token in the configuration file, be sure lock it down (permission 600) to ensure no other users on the system can read them. Or better yet, only specify sensitive values as a local environment variables. ๐
๐ฆ Section [header] Options ๐ฆ
deviceโ Header value used forX_PLEX_DEVICEto all Plex server and Plex client requests. Example devices include:iPhone,FireTV,Linux(default: result ofplatform.uname()[0]).device_nameโ Header value used forX_PLEX_DEVICE_NAMEto all Plex server and Plex client requests. Example device names include: hostname or phone name (default: result ofplatform.uname()[1]).identifierโ Header value used forX_PLEX_IDENTIFIERto all Plex server and Plex client requests. This is generally a UUID, serial number, or other number unique id for the device (default: result ofhex(uuid.getnode())).languageโ Header value used forX_PLEX_LANGUAGEto all Plex server and Plex client requests. This is an ISO 639-1 language code (default:en).platformโ Header value used forX_PLEX_PLATFORMto all Plex server and Plex client requests. Example platforms include:iOS,MacOSX,Android,LG(default: result ofplatform.uname()[0]).platform_versionโ Header value used forX_PLEX_PLATFORM_VERSIONto all Plex server and Plex client requests. This is generally the server or client operating system version:4.3.1,10.6.7,3.2(default: result ofplatform.uname()[2]).productโ Header value used forX_PLEX_PRODUCTto all Plex server and Plex client requests. This is the Plex application name:Laika,Plex Media Server,Media Link(default:PlexAPI).providesโ Header value used forX_PLEX_PROVIDESto all Plex server and Plex client requests. This is generally one or more of:controller,player,server(default:PlexAPI).versionโ Header value used forX_PLEX_VERSIONto all Plex server and Plex client requests. This is the Plex application version (default:plexapi.VERSION). ๐
๐ Section [log] Options ๐
backup_countโ Number backup log files to keep before rotating out old logs (default3).formatโ Log file format to use forplexapilogging. (default:'%(asctime)s %(module)12s:%(lineno)-4s %(levelname)-9s %(message)s'). Ref: โhttps://docs.python.org/2/library/logging.html#logrecord-attributeslevelโ Log level to use when forplexapilogging (default:INFO).pathโ File path to saveplexapilogs to. If not specified,plexapiwill not save logs to an output file (default:None).rotate_bytesโ Max size of the log file before rotating logs to a backup file (default:512000equals0.5MB).show_secretsโ By default Plex will hide all passwords and token values when logging. Set this to'true'to enable logging these secrets. This should only be done on a private server and only enabled when needed (default:false). ๐
ngl bestie, that last one is literally a "do not do this unless you know exactly why" situation. secrets stay secret, periodt. ๐
๐ ๏ธ run() โ the method that is the thread's whole personality
Literally the method that represents the thread's activity, bestie.
You may override this method in a subclass. The standardrun()method invokes the callable object passed to the object's constructor as thetargetargument, if any, with sequential and keyword arguments taken from theargsandkwargsarguments, respectively.
๐ stop() โ ending it, gracefully
Stops the AlertListener thread. Once the notifier is stopped, it cannot be directly started again โ no take-backs, no re-runs ๐ญ. You must call startAlertListener() from a PlexServer instance if you want it back. That's the rules.
๐จ ALERT PLEXAPI.ALERT ๐จ
๐ง class plexapi.alert.AlertListener(server, callback: Callable = None, callbackError: Callable = None, ws_socket: <module 'socket' from '/usr/lib/python3.14/socket.py'> = None)
Bases: Thread
So this one creates a websocket connection to the PlexServer so you can optionally receive alert notifications โจ. These alerts often include messages from Plex about media scans, plus updates to currently running Transcode Sessions ๐. This class implements threading.Thread, so to actually start monitoring alerts you must call .start() on the object once it's created. But when you call PlexServer.startAlertListener(), the thread gets started for you โ slay, no extra work ๐
.
Known state-values for timeline entries, with identifier=com.plexapp.plugins.library``:
0โ the item was created1โ reporting progress on item processing2โ matching the item3โ downloading the metadata4โ processing downloaded metadata5โ the item processed9โ the item deleted
Heads up ๐ซถ: when the metadata agent is not set for the library, processing ends with state=1.
๐ Parameters
server(PlexServer) โ thePlexServerthis listener is connected to.callback(func) โ callback function to call on received messages. It gets sent a single argumentdata, which is a dictionary of data received from the server. Like:
def my_callback(data): ...
callbackError(func) โ callback function to call on errors. It gets sent a single argumenterror, which contains theErrorobject. Like:
def my_callback(error): ...
ws_socket(socket) โ the socket to use for the connection. If you don't specify one, a new socket gets created for you โจ.
๐ต AUDIO PLEXAPI.AUDIO ๐ต
๐ธ class plexapi.audio.Audio(server, data, initpath=None, parent=None)
Bases: PlexPartialObject, PlayedUnplayedMixin
The base class for all audio objects, including Artist, Album, and Track โ it's giving main-character-of-the-whole-audio-library energy ๐.
๐ Variables
addedAt(datetime) โ datetime the item was added to the library.art(str) โ URL to artwork image (/library/metadata/<ratingKey>/art/<artid>).artBlurHash(str) โ BlurHash string for artwork image.distance(float) โ Sonic Distance of the item from the seed item.fields(List<Field>) โ list of field objects.guid(str) โ Plex GUID for the artist, album, or track (plex://artist/5d07bcb0403c64029053ac4c).images(List<Image>) โ list of image objects.index(int) โ Plex index number (often the track number).key(str) โ API URL (/library/metadata/<ratingkey>).lastRatedAt(datetime) โ datetime the item was last rated.lastViewedAt(datetime) โ datetime the item was last played.librarySectionID(int) โ LibrarySection ID.librarySectionKey(str) โ LibrarySection key.librarySectionTitle(str) โ LibrarySection title.listType(str) โ hardcoded as'audio'(useful for search filters).moods(List<Mood>) โ list of mood objects.musicAnalysisVersion(int) โ the Plex music analysis version for the item.ratingKey(int) โ unique key identifying the item.summary(str) โ summary of the artist, album, or track.thumb(str) โ URL to thumbnail image (/library/metadata/<ratingKey>/thumb/<thumbid>).thumbBlurHash(str) โ BlurHash string for thumbnail image.title(str) โ name of the artist, album, or track (Jason Mraz, We Sing, Lucky, etc.).titleSort(str) โ title to use when sorting (defaults totitle).type(str) โ'artist','album', or'track'.updatedAt(datetime) โ datetime the item was updated.userRating(float) โ rating of the item (0.0-10.0) equaling (0 stars - 5 stars).viewCount(int) โ count of times the item was played.
๐ url(part)
Returns the full URL for the audio item. Typically used for getting a specific track ๐ง.
๐ property hasSonicAnalysis
Returns True if the audio has been sonically analyzed. No cap, it's just a vibes check on the audio ๐ฆ.
๐ฒ sync(bitrate, client=None, clientId=None, limit=None, title=None)
Adds the current audio (artist, album, or track) as a sync item for a specified device. See sync() for possible exceptions ๐.
Parameters
bitrate(int) โ maximum bitrate for synchronized music; better use one of theMUSIC_BITRATE_*values from the modulesync.client(MyPlexDevice) โ sync destination, seesync().clientId(str) โ sync destination, seesync().limit(int) โ maximum count of items to sync, unlimited ifNone.title(str) โ descriptive title for the newSyncItem; if empty, the value gets generated from metadata of the current media.
Returns โ an instance of the created syncItem.
Return type โ SyncItem
๐งฌ sonicallySimilar(limit: int | None = None, maxDistance: float | None = None, **kwargs) -> List[TAudio]
Returns a list of sonically similar audio items โ your "more like this" era ๐.
Parameters
limit(int) โ maximum count of items to return. Default50(server default).maxDistance(float) โ maximum distance between tracks,0.0-1.0. Default0.25(server default).**kwargsโ additional options passed intofetchItems().
Returns โ list of sonically similar audio items.
Return type โ List[Audio]
๐ค class plexapi.audio.Artist(server, data, initpath=None, parent=None)
Bases: Audio, ArtistMixins
Represents a single Artist. Literally the moment ๐
.
๐ Variables
TAG(str) โ'Directory'TYPE(str) โ'artist'albumSort(int) โ setting that indicates how albums are sorted for the artist (-1= Library default,0= Newest first,1= Oldest first,2= By name).audienceRating(float) โ audience rating.collections(List<Collection>) โ list of collection objects.countries(List<Country>) โ list of country objects.genres(List<Genre>) โ list of genre objects.guids(List<Guid>) โ list of guid objects.key(str) โ API URL (/library/metadata/<ratingkey>).labels(List<Label>) โ list of label objects.locations(List<str>) โ list of folder paths where the artist is found on disk.rating(float) โ artist rating (7.9; 9.8; 8.1).similar(List<Similar>) โ list of similar objects.styles(List<Style>) โ list of style objects.theme(str) โ URL to theme resource (/library/metadata/<ratingkey>/theme/<themeid>).ultraBlurColors(UltraBlurColors) โ Ultra blur color object.
๐ฟ album(title)
Returns the Album that matches the specified title.
Parameters
title(str) โ title of the album to return.
๐ albums(**kwargs)
Returns a list of Album objects by the artist.
๐ถ track(title=None, album=None, track=None)
Returns the Track that matches the specified title.
Parameters
title(str) โ title of the track to return.album(str) โ album name (default:None; required iftitlenot specified).track(int) โ track number (default:None; required iftitlenot specified).
Raises BadRequest โ if title or album and track parameters are missing. Like, you gotta give it something bestie ๐ญ.
๐ผ tracks(**kwargs)
Returns a list of Track objects by the artist.
get(title=None, album=None, track=None)
Alias of track(). Same thing, different name, iykyk.
โฌ๏ธ download(savepath=None, keep_original_name=False, subfolders=False, **kwargs)
Download all tracks from the artist. See download() for details.
Parameters
savepath(str) โ defaults to current working dir.keep_original_name(bool) โTrueto keep the original filename, otherwise a friendlier filename is generated โจ.subfolders(bool) โTrueto separate tracks in to album folders.**kwargsโ additional options passed intogetStreamURL().
๐ฅ popularTracks()
Returns a list of Track popular tracks by the artist โ the hits, fr fr.
๐ป station()
Returns a Playlist artist radio station or None.
metadataDirectory (property) โ bestie this one hands you the Plex Media Server data directory where the metadata lives. That's it, that's the whole vibe ๐
๐ class plexapi.audio.Album(server, data, initpath=None, parent=None) ๐
Bases: Audio, AlbumMixins
okay so this one reps a single Album. iconic. here's everything it's packing ๐
Variables
TAG(str) โ'Directory'TYPE(str) โ'album'audienceRating(float) โ audience rating, yeah.collections(List<Collection>) โ list of collection objects.formats(List<Format>) โ list of format objects.genres(List<Genre>) โ list of genre objects.guids(List<Guid>) โ list of guid objects.key(str) โ API URL (/library/metadata/<ratingkey>).labels(List<Label>) โ list of label objects.leafCount(int) โ number of items in the album view.loudnessAnalysisVersion(int) โ the Plex loudness analysis version level.originallyAvailableAt(datetime) โ datetime the album was released.parentGuid(str) โ Plex GUID for the album artist (plex://artist/5d07bcb0403c64029053ac4c).parentKey(str) โ API URL of the album artist (/library/metadata/<parentRatingKey>).parentRatingKey(int) โ unique key identifying the album artist.parentTheme(str) โ URL to artist theme resource (/library/metadata/<parentRatingkey>/theme/<themeid>).parentThumb(str) โ URL to album artist thumbnail image (/library/metadata/<parentRatingKey>/thumb/<thumbid>).parentTitle(str) โ name of the album artist.rating(float) โ album rating (7.9;9.8;8.1).studio(str) โ studio that released the album.styles(List<Style>) โ list of style objects.subformats(List<Subformat>) โ list of subformat objects.ultraBlurColors(UltraBlurColors) โ ultra blur color object โจviewedLeafCount(int) โ number of items marked as played in the album view.year(int) โ year the album was released.
track(title=None, track=None)
returns the Track that matches the title you asked for. no cap.
Parameters
title(str) โ title of the track to return.track(int) โ track number (default:None; required iftitlenot specified).
Raises BadRequest โ if title or track parameter is missing. like if you give it neither, it WILL be dramatic about it ๐ญ
tracks(**kwargs)
returns a list of Track objects in the album. all of them. the whole playlist era.
get(title=None, track=None)
alias of track(). same energy, shorter name ๐ซถ
artist()
returns the album's Artist. found family fr.
download(savepath=None, keep_original_name=False, **kwargs)
downloads all tracks from the album. see download() for details.
Parameters
savepath(str) โ defaults to current working dir.keep_original_name(bool) โTrueto keep the original filename, otherwise a friendlier filename is generated.**kwargsโ additional options passed intogetStreamURL().
metadataDirectory (property)
returns the Plex Media Server data directory where the metadata is stored. again. because we love consistency ๐
๐ฆ class plexapi.audio.Track(server, data, initpath=None, parent=None) ๐ฆ
Bases: Audio, Playable, TrackMixins
represents a single Track. the main character of the audio section, honestly.
Variables
TAG(str) โ'Directory'TYPE(str) โ'track'audienceRating(float) โ audience rating.chapters(List<Chapter>) โ list of Chapter objects.chapterSource(str) โ Unknown. (yes literally "Unknown", we don't make the rules ๐)collections(List<Collection>) โ list of collection objects.duration(int) โ length of the track in milliseconds.genres(List<Genre>) โ list of genre objects.grandparentArt(str) โ URL to album artist artwork (/library/metadata/<grandparentRatingKey>/art/<artid>).grandparentGuid(str) โ Plex GUID for the album artist (plex://artist/5d07bcb0403c64029053ac4c).grandparentKey(str) โ API URL of the album artist (/library/metadata/<grandparentRatingKey>).grandparentRatingKey(int) โ unique key identifying the album artist.grandparentTheme(str) โ URL to artist theme resource (/library/metadata/<grandparentRatingkey>/theme/<themeid>).grandparentThumb(str) โ URL to album artist thumbnail image (/library/metadata/<grandparentRatingKey>/thumb/<thumbid>).grandparentTitle(str) โ name of the album artist for the track.guids(List<Guid>) โ list of guid objects.labels(List<Label>) โ list of label objects.media(List<Media>) โ list of media objects.originalTitle(str) โ the artist for the track.parentGuid(str) โ Plex GUID for the album (plex://album/5d07cd8e403c640290f180f9).parentIndex(int) โ disc number of the track.parentKey(str) โ API URL of the album (/library/metadata/<parentRatingKey>).parentRatingKey(int) โ unique key identifying the album.parentThumb(str) โ URL to album thumbnail image (/library/metadata/<parentRatingKey>/thumb/<thumbid>).parentTitle(str) โ name of the album for the track.primaryExtraKey(str) โ (no notes on this one, it's justโฆ there ๐)rating(float) โ track rating (7.9;9.8;8.1).ratingCount(int) โ number of listeners who have scrobbled this track, as reported by Last.fm.skipCount(int) โ number of times the track has been skipped. we've all been there.sourceURI(str) โ remote server URI (server://<machineIdentifier>/com.plexapp.plugins.library) (remote playlist item only).viewOffset(int) โ view offset in milliseconds.year(int) โ year the track was released.
locations (property)
heads up bestie: this does not exist in plex xml response but is added to have a common interface to get the locations of the track.
Returns List<str> of file paths where the track is found on disk. slay.
trackNumber (property)
returns the track number. short and sweet, we love her.
album()
return the track's Album.
artist()
return the track's Artist.
metadataDirectory (property)
returns the Plex Media Server data directory where the metadata is stored.
sonicAdventure(to: TTrack, **kwargs: Any) -> list[TTrack]
returns a sonic adventure from the current track to the specified track. like a little musical road trip, lowkey obsessed ๐ง
Parameters
to(Track) โ the target track for the sonic adventure.**kwargsโ additional options passed intosonicAdventure().
Returns list of tracks in the sonic adventure.
Return type List[Track]
๐ class plexapi.audio.TrackSession(server, data, initpath=None, parent=None) ๐
Bases: PlexSession, Track
represents a single Track session loaded from sessions(). it's giving "who's listening right now" energy.
๐ธ class plexapi.audio.TrackHistory(server, data, initpath=None, parent=None) ๐ธ
Bases: PlexHistory, Track
represents a single Track history entry loaded from history(). the receipts, basically ๐งพ
๐ฑ BASE PLEXAPI.BASE ๐ฑ
class plexapi.base.cached_data_property(func)
Bases: cached_property
caching for PlexObject data properties. the way this decorator works: it creates properties that cache their values, with automatic invalidation whenever the data changes. so it's smart, it's self-cleaning, we stan โจ
class plexapi.base.PlexObjectMeta(name, bases, attrs)
Bases: type
metaclass for PlexObject to handle cached_data_properties. behind-the-scenes icon behavior, iykyk.
class plexapi.base.PlexObject(server, data, initpath=None, parent=None)
Bases: object
the base class for all Plex objects. mother of the entire family tree fr fr ๐
Parameters
server(PlexServer) โ PlexServer this client is connected to (optional).data(ElementTree) โ response from PlexServer used to build this object (optional).initpath(str) โ relative path requested when retrieving specified data (optional).parent(PlexObject) โ the parent object that this object is built from (optional).
fetchItems(ekey, cls=None, container_start=None, container_size=None, maxresults=None, params=None, **kwargs)
load the specified key to find and build all items with the specified tag and attrs. it's the "go get me everything" method and honestly it eats every time ๐ฅ
Parameters
ekey(str or List<int>) โ API URL path in Plex to fetch items from. if a list of ints is passed in, the key will be translated to/library/metadata/<key1,key2,key3>. this allows fetching multiple items only knowing their key-ids. kinda genius ngl.cls(PlexObject) โ if you know the class of the items to be fetched, passing this in will help the parser ensure it only returns those items. by default we convert the xml elements with the best guessPlexObjectsbased on tag and type attrs.etag(str) โ only fetch items carrying that exact tag, no substitutes ๐container_start(None, int) โ the offset, so you can grab just a lil subset of the data instead of the whole thingcontainer_size(None, int) โ how many items live in the datamaxresults(int, optional) โ cap it: only return this many results, periodtparams(dict, optional) โ any extra params you wanna add to the request**kwargs(dict) โ optionally add an XML attribute to filter the items. Scroll down for the deets ๐
โจ Filtering XML Attributes โจ
Okay so this is the fun part: literally any XML attribute can be filtered when you're fetching results ๐. And the filtering happens before the Python objects get built, which keeps things speedy โ highkey a slay. So for example, passing in viewCount=0 will only return matching items where the view count is 0. Ngl, case matters when you're specifying attributes, so watch that. And attributes further down the XML tree can be filtered by prepending the attribute with each element tag plus a Tag__. Yes, double underscore. Iconic.
Examples ๐ฆ
fetchItem(ekey, viewCount=0)
fetchItem(ekey, contentRating="PG")
fetchItem(ekey, Genre__tag="Animation")
fetchItem(ekey, Media__videoCodec="h265")
fetchItem(ekey, Media__Part__container="mp4)
Fr fr, that last line is copied verbatim โ the closing quote really is missing in the original. Not me fixing it, bestie. ๐
Also, because some attribute names are already used as arguments to this function โ like tag โ you can still reference the attr tag by prepending an underscore. So passing in _tag='foobar' will return all items where tag='foobar'. Sneaky but it works ๐.
๐ Using PlexAPI Operators ๐
Optionally โ and this is where it gets good โ PlexAPI operators can be specified by appending them to the end of the attribute for more complex lookups. So passing in viewCount__gte=0 will return all items where viewCount >= 0. Chef's kiss.
List of Available Operators:
__containsโ value contains the specified arg__endswithโ value ends with the specified arg__exactโ value matches the specified arg__exists(bool) โ value is or is not present in the attrs__gtโ value is greater than the specified arg__gteโ value is greater than or equal to the specified arg__icontainsโ case insensitive, value contains the specified arg__iendswithโ case insensitive, value ends with the specified arg__iexactโ case insensitive, value matches the specified arg__inโ value is in a specified list or tuple__iregexโ case insensitive, value matches the specified regular expression__istartswithโ case insensitive, value starts with the specified arg__ltโ value is less than the specified arg__lteโ value is less than or equal to the specified arg__regexโ value matches the specified regular expression__startswithโ value starts with the specified arg
Examples ๐ธ
fetchItem(ekey, viewCount__gte=0)
fetchItem(ekey, Media__container__in=["mp4", "mkv"])
fetchItem(ekey, guid__regex=r"com\.plexapp\.agents\.(imdb|themoviedb)://|tt\d+")
fetchItem(ekey, guid__id__regex=r"(imdb|tmdb|tvdb)://")
fetchItem(ekey, Media__Part__file__startswith="D:\Movies")
fetchItem(ekey, cls=None, **kwargs)
Loads the specified key to find and build the first item with the specified tag and attrs. If you don't give it a tag or attrs, then the first item in the result set comes back. Simple as that โจ
Parameters ๐ซถ
ekey(str or int) โ path in Plex to fetch items from. If you pass in anint, the key gets translated to/library/metadata/<key>, which is lowkey a lifesaver: it means you can fetch an item knowing only its key-idcls(PlexObject) โ if you already know the class of the items being fetched, pass it in and the parser will make sure it only returns those items. By default it converts the XML elements into the best-guessPlexObjects based on thetagandtypeattrsetag(str) โ only fetch items with the specified tag**kwargs(dict) โ optionally add XML attributes to filter the items. SeefetchItems()for more details on how this is used ๐
findItems(data, cls=None, initpath=None, rtag=None, **kwargs)
Loads the specified data to find and build all items with the specified tag and attrs. See fetchItem() for more details on how this is used. Iconic sibling energy ๐
findItem(data, cls=None, initpath=None, rtag=None, **kwargs)
Loads the specified data to find and build the first item with the specified tag and attrs. Again, see fetchItem() for the deets. ๐
firstAttr(*attrs)
Returns the first attribute in attrs that isn't None. First come, first served, no cap ๐ฆ
listAttrs(data, attr, rtag=None, **kwargs)
Returns a list of values from the matching attribute. A whole list of them, bestie ๐
reload(key=None, **kwargs)
Reloads the data for this object. The glow-up method, honestly โจ
Parameters
key(string, optional) โ override the key to reload**kwargs(dict) โ a dictionary of XML include parameters to include/exclude or override. SeePlexPartialObjectfor all the available include parameters. Set a parameter toTrueto include it andFalseto exclude it
Example โญ
from plexapi.server import PlexServer
plex = PlexServer('http://localhost:32400', token='xxxxxxxxxxxxxxxxxxxx')
# Search results are partial objects.
movie = plex.library.section('Movies').get('Cars')
movie.isPartialObject() # Returns True
# Partial reload of the movie without a default include parameter.
# The movie object will remain as a partial object.
movie.reload(includeMarkers=False)
movie.isPartialObject() # Returns True
# Full reload of the movie with all default include parameters.
# The movie object will be a full object.
movie.reload()
movie.isFullObject() # Returns True
# Full reload of the movie with all default and extra include parameter.
# Including `checkFiles` will tell the Plex server to check if the file
# still exists and is accessible.
# The movie object will be a full object.
movie.reload(checkFiles=True)
movie.isFullObject() # Returns True
class plexapi.base.PlexPartialObject(server, data, initpath=None, parent=None)
Bases: PlexObject
Okay so real talk: not all objects in the Plex listings return the complete list of elements for the object. This class is the fix ๐. It lets you assume each object is complete, and if the value you requested is None, it'll fetch the full object automatically and update itself. Main character energy fr fr ๐
analyze()
Tells Plex Media Server to perform analysis on this item to gather information. And analysis includes:
- Gather Media Properties: all of the media you add to a Library has properties that are useful to know โ whether it's a video file, a music track, or one of your photos (container, codec, resolution, etc).
- Generate Default Artwork: artwork is automatically grabbed from a video file. A background image gets pulled out as well as a smaller image to be used for poster/thumbnail type purposes.
- Generate Video Preview Thumbnails: video preview thumbnails get created, if you have that feature enabled. Video preview thumbnails allow graphical seeking in some Apps. It's also used in the Plex Web App Now Playing screen to show a graphical representation of where playback is. Heads up: video preview thumbnail creation is a CPU-intensive process akin to transcoding the file ๐ญ๐ฅ โ like, it will work your CPU.
- Generate intro video markers: detects show intros, exposing the 'Skip Intro' button in clients. The most iconic button of all time tbh.
isFullObject()
Returns True if this is already a full object. A full object means all attributes were populated from the API path representing only this item. For example, the search result for a movie often only contains a portion of the attributes that a full object (main url) for that movie would contain. ๐ฆ
isPartialObject()
Returns True if this is not a full object. The vibe check of object completeness ๐
isLocked(field: str)
Returns True if the specified field is locked, otherwise False.
Parameters
field(str) โ the name of the field ๐
edit(**kwargs)
Edits an object. Note: this is a low level method and you need to know all the field/tag keys. See EditFieldMixin and EditTagsMixin for the individual field and tag editing methods. Don't come at me if you raw-dog this one, bestie ๐
Parameters
kwargs(dict) โ dict of settings to edit
Example
edits = {
'type': 1,
'id': movie.ratingKey,
'title.value': 'A new title',
'title.locked': 1,
'summary.value': 'This is a summary.',
'summary.locked': 1,
'collection[0].tag.tag': 'A tag',
'collection.locked': 1}
}
movie.edit(**edits)
batchEdits()
okay bestie this one is a time-saver ๐
it turns on batch editing mode so you're not firing off a million separate API calls like some kind of maniac. You literally must call saveEdits() at the end or none of your edits actually land. If you wanna know about editing individual fields vs. tags, go peek at EditFieldMixin and EditTagsMixin.
Example โ batch editing multiple fields and tags in a single API call:
Movie.batchEdits()
Movie.editTitle('A New Title').editSummary('A new summary').editTagline('A new tagline') \
.addCollection('New Collection').removeGenre('Action').addLabel('Favorite')
Movie.saveEdits()
saveEdits()
Saves all your batch edits ๐พ that's the whole vibe. Heads up though โ the object needs to be reloaded manually if you want the fresh data. See batchEdits() above for the deets.
refresh()
Refreshing a Library or an individual item makes the metadata get refreshed โ even if it already has metadata. Think of it like: "update the metadata for the thing I asked for, even if it's already got some." Not me explaining it like that but it's actually true ๐ซถ
You should refresh a Library or individual item if:
- You've changed the Library Metadata Agent.
- You've added "Local Media Assets" (such as artwork, theme music, external subtitle files, etc.)
- You want to freshen the item posters, summary, etc.
- There's a problem with the poster image that's been downloaded.
- Items are missing posters or other downloaded information. This is possible if the refresh process is interrupted (the Server is turned off, internet connection dies, etc).
section()
Returns the LibrarySection this item belongs to ๐๏ธ iykyk.
delete()
Deletes a media element ๐ but like โ this has to be enabled under settings > server > library in the plex webui first, so don't come crying to me if it doesn't work.
history(maxresults=None, mindate=None)
Grabs the Play History for a media item ๐ฐ๏ธ
Parameters
maxresults(int) โ Only return the specified number of results (optional).mindate(datetime) โ Min datetime to return results from.
getWebURL(base=None)
Returns the Plex Web URL for a media item ๐
Parameters
base(str) โ The base URL before the fragment (#!). Default ishttps://app.plex.tv/desktop.
playQueue(*args, **kwargs)
Returns a new PlayQueue from this media item ๐ถ See create() for the available parameters.
๐ฆ class plexapi.base.Playable
Bases: object
This is a mixin that stores functions specific to media that is Playable. Things were getting mixed up a lil bit when dealing with Shows, Season, Artists, Albums โ which are all not playable, bestie. So we fixed it ๐
Variables
playlistItemID(int) โ Playlist item ID (only populated for Playlist items).playQueueItemID(int) โ PlayQueue item ID (only populated for PlayQueue items).
getStreamURL(**kwargs)
Returns a stream url that may be used by external applications such as VLC ๐ฅ
Parameters
**kwargs(dict) โ optional parameters to manipulate the playback when accessing the stream. A few known parameters include:maxVideoBitrate,videoResolution,offset,copyts,protocol,mediaIndex,partIndex,platform.
Raises Unsupported โ When the item doesn't support fetching a stream URL. ๐ญ
iterParts()
Iterates over the parts of this media item ๐
videoStreams()
Returns a list of videoStream objects for all MediaParts ๐ฅ
audioStreams()
Returns a list of AudioStream objects for all MediaParts ๐
subtitleStreams()
Returns a list of SubtitleStream objects for all MediaParts ๐ฌ
lyricStreams()
Returns a list of LyricStream objects for all MediaParts ๐ค
play(client)
Start playback on the specified client โถ๏ธ
Parameters
client(PlexClient) โ Client to start playing on.
download(savepath=None, keep_original_name=False, **kwargs)
Downloads the media item to the specified location ๐ฅ Returns a list of filepaths that have been saved to disk.
Parameters
savepath(str) โ Defaults to current working dir.keep_original_name(bool) โTrueto keep the original filename, otherwise a friendlier filename is generated. See filenames below.**kwargs(dict) โ Additional options passed intogetStreamURL()to download a transcoded stream, otherwise the media item will be downloaded as-is and saved to disk.
Filenames
- Movie:
<title> (<year>) - Episode:
<show title> - s00e00 - <episode title> - Track:
<artist title> - <album title> - 00 - <track title> - Photo:
<photoalbum title> - <photo/clip title>or<photo/clip title>
updateProgress(time, state='stopped')
Set the watched progress for this video โฑ๏ธ
Bestie, note that setting the time to0will not work. UsemarkPlayed()ormarkUnplayed()if that's the goal, okay? ๐
Parameters
time(int) โ milliseconds watchedstate(string) โ state of the video, default'stopped'
updateTimeline(time, state='stopped', duration=None)
Set the timeline progress for this video ๐
Parameters
time(int) โ milliseconds watchedstate(string) โ state of the video, default'stopped'duration(int) โ duration of the item
๐ธ class plexapi.base.PlexSession
Bases: object
Another mixin, this one storing functions specific to media that is a Plex Session ๐ฌ
Variables
live(bool) โTrueif this is a live tv session.player(PlexClient) โPlexClientobject for the session.session(Session) โSessionobject for the session if the session is using bandwidth (Noneotherwise).sessionKey(int) โ The session key for the session.transcodeSession(TranscodeSession) โTranscodeSessionobject if item is being transcoded (Noneotherwise).
property user
Returns the MyPlexAccount object (for admin) or MyPlexUser object (for users) for this session ๐ it's giving main character energy fr.
reload()
Reload the data for the session ๐ Note: this will return the object as-is if the session is no longer active. No cap.
source()
Return the source media object for the session ๐ผ
stop(reason='')
Stop playback for the session โน๏ธ
Parameters
reason(str) โ Message displayed to the user for stopping playback.
๐ class plexapi.base.PlexHistory
Bases: object
Mixin time again ๐ this one stores functions specific to media that is a Plex history item.
Variables
accountID(int) โ The associatedSystemAccountID.deviceID(int) โ The associatedSystemDeviceID.historyKey(str) โ API URL (/status/sessions/history/<historyID>).viewedAt(datetime) โ Datetime item was last watched.
source()
Return the source media object for the history entry, or None if the media no longer exists on the server ๐ญ rip.
delete()
Delete the history entry ๐๏ธ
๐ง class plexapi.base.MediaContainer
Bases: Generic[PlexObjectT], List[PlexObjectT], PlexObject
Represents a single MediaContainer ๐ฆ okay so it's literally a list and an object, iconic behaviour honestly.
class plexapi.base.MediaContainer(server: PlexServer, data: Element,
*args: PlexObjectT, initpath: str | None = None, parent: PlexObject |
None = None)
Variables
TAG(str) โ'MediaContainer'allowSync(int) โ Sync/Download is allowed/disallowed for feature.augmentationKey(str) โ API URL (/library/metadata/augmentations/<augmentationKey>).identifier(str) โ"com.plexapp.plugins.library"librarySectionID(int) โLibrarySectionID.librarySectionTitle(str) โLibrarySectiontitle.librarySectionUUID(str) โLibrarySectionUUID.mediaTagPrefix(str) โ"/system/bundle/media/flags/"mediaTagVersion(int) โ Unknown ๐คทโโ๏ธ nobody knows bestieoffset(int) โ The offset of current results.size(int) โ The number of items in the hub.totalSize(int) โ The total number of items for the query.
extend(_MediaContainer__iterable: Iterable[PlexObjectT] | MediaContainerT) -> None
Extend list by appending elements from the iterable โ classic list behaviour, slay.
๐ป CLIENT PLEXAPI.CLIENT
class plexapi.client.PlexClient
Bases: PlexObject
class plexapi.client.PlexClient(server=None, data=None, initpath=None,
baseurl=None, identifier=None, token=None, connect=True, session=None,
timeout=None, parent=None)
Okay so this is the main character class for talking to a Plex client ๐
โ it can either connect straight to the client and control it directly, or proxy your commands through your Plex Server instead. If you wanna actually understand the Plex client API, the docs say to go read this page: https://github.com/plexinc/plex-media-player/wiki/Remote-control-API ๐ซถ
Parameters โจ
server(PlexServer) โ thePlexServerthis client is connected to (optional).data(ElementTree) โ the response fromPlexServerthat gets used to build this object (optional).initpath(str) โ path used to generatedata.baseurl(str) โ HTTP URL for connecting directly to this client.identifier(str) โ the resource/machine identifier for the client you want. Might be needed when you're connecting to a specific proxied client (optional).token(str) โ theX-Plex-Tokenused for authentication (optional).session(Session) โ arequests.Sessionobject, for when you want more control (optional).timeout(int) โ timeout in seconds on the initial connect to the client (defaults toconfig.TIMEOUT).
๐ฆ Variables ๐ฆ
TAG(str) โ'Player'.key(str) โ'/resources'.device(str) โ best guess at what kind of device this is (PS,iPhone,Linux, etc).deviceClass(str) โ the device class (pc,phone, etc).machineIdentifier(str) โ the unique ID for this device.model(str) โ unknown.platform(str) โ unknown.platformVersion(str) โ description.product(str) โ the client product (Plex for iOS, etc).protocol(str) โ always seems to be'plex'(yes, the docs literally say "ot be" ๐ญ).protocolCapabilities(list<str>) โ list of client capabilities (navigation,playback,timeline,mirror,playqueues).protocolVersion(str) โ protocol version (1, future proofing?).server(PlexServer) โ the server this client is connected to.session(Session) โ the session object used for the connection.state(str) โ unknown.title(str) โ the name of this client (Johns iPhone, etc).token(str) โX-Plex-Tokenused for authentication.vendor(str) โ unknown.version(str) โ the device version (4.6.1, etc)._baseurl(str) โ HTTP address of the client._token(str) โ token used to access this client._session(obj) โ requests session object used to access this client._proxyThroughServer(bool) โ gets set toTrueafter you callproxyThroughServer()(defaultFalse).
๐ Methods ๐
connect(timeout=None)โ alias ofreload, because any requests to this client after this point go directly to the device, even if the object's attributes were originally filled in from aPlexServer.reload()โ alias toself.connect().proxyThroughServer(value=True, server=None)โ tells thisPlexClientinstance to proxy all future commands through thePlexServer. Super handy if you don't wanna connect directly to the client device itself โจ
Parameters
value(bool) โ enable or disable proxying (optional, defaultTrue).
Raises Unsupported โ you cannot use client proxy with an unknown server.
query(path, method=None, headers=None, timeout=None, **kwargs)โ the main method for handling HTTPS requests to the Plex client. It helps by encoding the response to utf-8 and parsing the returned XML into anElementTreeobject. ReturnsNoneif there's no data in the response.sendCommand(command, proxy=None, **params)โ a convenience wrapper aroundquery()so sending simple commands to the client is way easier. Returns anElementTreeobject containing the response ๐
Parameters
command(str) โ the command to send, in the format'<controller>/<command>'.proxy(bool) โ setTrueto proxy this command through thePlexServer.**params(dict) โ additional GET parameters to include with the command.
Raises Unsupported โ when we detect that the client doesn't support this capability.
url(key, includeToken=False)โ builds a URL string with the proper token argument. The token gets appended to the URL if eitherincludeTokenisTrueorCONFIG.log.show_secretsis'true'.contextMenu()โ opens the context menu on the client.goBack()โ navigate back one position.goToHome()โ go straight to the home screen.goToMusic()โ go straight to the playing music panel.moveDown()โ move the selection down one position.moveLeft()โ move the selection left one position.moveRight()โ move the selection right one position.moveUp()โ move the selection up one position.nextLetter()โ jump to the next letter in the alphabet.pageDown()โ move the selection down a full page.pageUp()โ move the selection up a full page.previousLetter()โ jump to the previous letter in the alphabet.select()โ select the element at the current position.toggleOSD()โ toggle the on screen display during playback.goToMedia(media, **params)โ navigate directly to the specified media page.
Parameters
media(Media) โ theMediaobject to navigate to.**params(dict) โ additional GET parameters to include with the command.
pause(mtype='video')โ pause the currently playing media type.
Parameters
mtype(str) โ the media type to take action against (music,photo,video).
play(mtype='video')โ start playback for the specified media type.
Parameters
mtype(str) โ the media type to take action against (music,photo,video).
refreshPlayQueue(playQueueID, mtype='video')โ refresh the specified Playqueue.
Parameters
playQueueID(str) โ Playqueue ID.mtype(str) โ the media type to take action against (music,photo,video).
seekTo(offset, mtype='video')โ seek to the specified offset (in ms) during playback.
Parameters
offset(int) โ position to seek to (milliseconds).mtype(str) โ the media type to take action against (music,photo,video).
skipNext(mtype='video')โ skip to the next playback item.
Parameters
mtype(str) โ the media type to take action against (music,photo,video).
skipPrevious(mtype='video')โ skip to the previous playback item.
Parameters
mtype(str) โ the media type to take action against (music,photo,video).
skipTo(key, mtype='video')โ skip to the playback item with the specified key.
Parameters
key(str) โ key of the media item to skip to.mtype(str) โ the media type to take action against (music,photo,video).
stepBack(mtype='video')โ step backward a chunk of time in the current playback item.
Parameters
mtype(str) โ the media type to take action against (music,photo,video).
stepForward(mtype='video')โ step forward a chunk of time in the current playback item.
Parameters
mtype(str) โ the media type to take action against (music,photo,video).
stop(mtype='video')โ stop the currently playing item.
Parameters
mtype(str) โ the media type to take action against (music,photo,video).
setRepeat(repeat, mtype='video')โ enable repeat for the specified playback items.
Parameters
repeat(int) โ repeat mode (0=off,1=repeatone,2=repeatall).mtype(str) โ the media type to take action against (music,photo,video).
setShuffle(shuffle, mtype='video')โ enable shuffle for the specified playback items.
Parameters
shuffle(int) โ shuffle mode (0=off,1=on).mtype(str) โ the media type to take action against (music,photo,video).
setVolume(volume, mtype='video')โ enable volume for the current playback item ๐
Parameters
volume(int) โ volume level (0-100).mtype(str) โ the media type to take action against (music,photo,video).
setAudioStream(audioStreamID, mtype='video')โ select the audio stream for the current playback item (video only!).
Parameters
audioStreamID(str) โ ID of the audio stream from the media object.mtype(str) โ the media type to take action against (music,photo,video).
๐ setSubtitleStream(subtitleStreamID, mtype='video')
Okay so this one picks the subtitle stream for whatever's playing right now โ and yeah, only for video, bestie ๐
subtitleStreamID(str) โ the ID of the subtitle stream, straight off the media object.mtype(str) โ which media type you're acting on (music,photo,video).
๐ฆ setVideoStream(videoStreamID, mtype='video')
Same vibe, but for video streams โ selects the video stream for the current playback item (only video, obviously โจ).
videoStreamID(str) โ the ID of the video stream from the media object.mtype(str) โ media type to take action against (music,photo,video).
๐ฅ playMedia(media, offset=0, **params)
Starts playback of the media item you hand it. See also: ๐
media(Media) โ the media item to be played back (movie, music, photo, playlist, playqueue). So many options, we love versatility ๐offset(int) โ how many milliseconds in to start playing, where zero means the very beginning (default0).**params(dict) โ optional extra parameters to shove into the playback request. See also: โhttps://github.com/plexinc/plex-media-player/wiki/Remote-control-API#modified-commands
๐ธ setParameters(volume=None, shuffle=None, repeat=None, mtype='video')
Sets a whole bunch of playback parameters at once โ efficiency queen ๐
volume(int) โ volume level (0-100; optional).shuffle(int) โ shuffle mode (0=off,1=on; optional).repeat(int) โ repeat mode (0=off,1=repeatone,2=repeatall; optional).mtype(str) โ media type to take action against (optionalmusic,photo,video).
๐ง setStreams(audioStreamID=None, subtitleStreamID=None, videoStreamID=None, mtype='video')
And this one does all the streams in one go โ literally the combo meal of stream selection ๐
audioStreamID(str) โ ID of the audio stream from the media object.subtitleStreamID(str) โ ID of the subtitle stream from the media object.videoStreamID(str) โ ID of the video stream from the media object.mtype(str) โ media type to take action against (optionalmusic,photo,video).
๐ซ timelines(wait=0)
Polls the client's timelines, then creates and returns timeline objects. Heads up though: some clients just won't respond to timeline requests โ apparently they believe this to be a Plex bug ๐ญ not us, we're just reporting it fr fr.
โญ property timeline
Returns the active timeline object. Main character property energy ๐
๐ isPlayingMedia(includePaused=True)
Returns True if literally any media is currently playing.
includePaused(bool) โ setTrueto treat currently paused items as playing (optional; defaultTrue).
๐ซถ class plexapi.client.ClientTimeline(server, data, initpath=None, parent=None)
Bases: PlexObject
Gets the timeline's attributes. That's the whole job and it does it slayfully โจ
๐ COLLECTION PLEXAPI.COLLECTION ๐
๐ class plexapi.collection.Collection(server, data, initpath=None, parent=None)
Bases: PlexPartialObject, CollectionMixins
Represents one single Collection. Just the one. Iconic behavior only ๐
Variables (there's a lot, stay with me bestie):
TAG(str) โ'Directory'TYPE(str) โ'collection'addedAt(datetime) โ when the collection got added to the library.art(str) โ URL to the artwork image (/library/metadata/<ratingKey>/art/<artid>).artBlurHash(str) โ BlurHash string for that artwork image.audienceRating(float) โ audience rating.childCount(int) โ how many items are in the collection.collectionFilterBasedOnUser(int) โ which user's activity is used for the collection filtering.collectionMode(int) โ how the items in the collection are displayed.collectionPublished(bool) โTrueif the collection is published to the Plex homepage.collectionSort(int) โ how to sort items in the collection.content(str) โ the filter URI string for smart collections.contentRating(str) โ content rating (PG-13;NR;TV-G).fields(List<Field>) โ list of field objects.guid(str) โ Plex GUID for the collection (collection://XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX).images(List<Image>) โ list of image objects.index(int) โ Plex index number for the collection.key(str) โ API URL (/library/metadata/<ratingkey>).labels(List<Label>) โ list of label objects.lastRatedAt(datetime) โ when the collection was last rated.librarySectionID(int) โ LibrarySection ID.librarySectionKey(str) โ LibrarySection key.librarySectionTitle(str) โ LibrarySection title.maxYear(int) โ maximum year for the items in the collection.minYear(int) โ minimum year for the items in the collection.rating(float) โ collection rating (7.9;9.8;8.1).ratingCount(int) โ the number of ratings.ratingKey(int) โ unique key identifying the collection.smart(bool) โTrueif the collection is a smart collection.subtype(str) โ media type of items in the collection (movie,show,artist, oralbum).summary(str) โ summary of the collection.theme(str) โ URL to the theme resource (/library/metadata/<ratingkey>/theme/<themeid>).thumb(str) โ URL to the thumbnail image (/library/metadata/<ratingKey>/thumb/<thumbid>).thumbBlurHash(str) โ BlurHash string for the thumbnail image.title(str) โ name of the collection.titleSort(str) โ title to use when sorting (defaults totitle).type(str) โ'collection'ultraBlurColors(UltraBlurColors) โ ultra blur color object โจ aesthetic.updatedAt(datetime) โ when the collection was updated.userRating(float) โ rating of the collection (0.0-10.0) equaling (0 stars-5 stars).
๐ property listType
Returns the listType for the collection.
๐ property metadataType
Returns the type of metadata inside the collection.
๐ property isVideo
Returns True if this is a video collection.
๐ property isAudio
Returns True if this is an audio collection.
๐ property isPhoto
Returns True if this is a photo collection.
๐
filters()
Returns the search filter dict for a smart collection. That filter dict gets passed right back into search() to get the list of items. Round trip, we love a cycle ๐ฆ
๐ section()
Returns the LibrarySection this collection belongs to. Found family fr fr ๐ซถ
๐ item(title)
Returns the item in the collection that matches the title you gave it.
title(str) โ title of the item to return.
Raises plexapi.exceptions.NotFound โ when the item is not found in the collection. ๐
โญ items()
Returns a list of all items in the collection. All of them. No crumbs.
๐ visibility()
Returns the ManagedHub for this collection.
๐ง get(title)
Alias to item(). Same thing, cuter name.
๐ filterUserUpdate(user=None)
Updates the collection filtering user advanced setting.
user(str) โ one of these values:"admin"(always the server admin user),"user"(user currently viewing the content).
Example
collection.updateMode(user="user")
๐ธ modeUpdate(mode=None)
Updates the collection mode advanced setting.
mode(str) โ one of these values:"default"(Library default),"hide"(Hide Collection),"hideItems"(Hide Items in this Collection),"showItems"(Show this Collection and its Items).
Example
collection.updateMode(mode="hide")
๐ฆ sortUpdate(sort=None)
Updates the collection order advanced setting.
sort(str) โ one of these values:"release"(Order Collection by release dates),"alpha"(Order Collection alphabetically),"custom"(Custom collection order).
Example
collection.sortUpdate(sort="alpha")
๐ฅ addItems(items)
Adds items to the collection. Growing the collection, we love to see it ๐ฑ
items(List) โ list ofAudio,Video, orPhotoobjects to be added to the collection.
Raises plexapi.exceptions.BadRequest โ when you try to add items to a smart collection. Nope, not allowed, the smart ones handle themselves ๐ค
๐ removeItems(items)
Removes items from the collection. Sad but necessary.
items(List) โ list ofAudio,Video, orPhotoobjects to be removed from the collection.
Raises plexapi.exceptions.BadRequest โ when you try to remove items from a smart collection. Same deal, smart collections are self-sufficient and will not be edited by you ๐
moveItem(item, after=None)โ reposition an item inside the collection, like dragging a song up in your queue but make it official ๐
Parameters
- item (
obj) โ theAudio,Video, orPhotoobject you wanna move in the collection. - after (
obj) โ theAudio,Video, orPhotoobject you want to move the item after in the collection.
Raises plexapi.exceptions.BadRequest โ when you try to move items in a smart collection. yeah no, smart collections are built diff, you can't just shove things around in them ๐ญ
updateFilters(libtype=None, limit=None, sort=None, filters=None, **kwargs)โ update the filters on a smart collection. glow-up for your filter rules โจ
Parameters
- libtype (
str) โ the specific type of content to filter (movie,show,season,episode,artist,album,track,photoalbum,photo,collection). - limit (
int) โ limit the number of items in the collection. - sort (
strorlist, optional) โ a string of comma separated sort fields, or a list of sort fields in the formatcolumn:dir. Seesearch()for more info. - filters (
dict) โ a dictionary of advanced filters. Seesearch()for more info. - **kwargs (
dict) โ additional custom filters to apply to the search results. Seesearch()for more info.
Raises plexapi.exceptions.BadRequest โ when you try to update filters for a regular collection. regular collections said no thanks ๐ซถ
delete()โ delete the collection. it's over, bye bestie ๐classmethod create(server, title, section, items=None, smart=False, limit=None, libtype=None, sort=None, filters=None, **kwargs)โ create a collection, fresh out the box ๐
Parameters
- server (
PlexServer) โ server to create the collection on. - title (
str) โ title of the collection. - section (
LibrarySection,str) โ the library section to create the collection in. - items (
List) โ regular collections only, list ofAudio,Video, orPhotoobjects to be added to the collection. - smart (
bool) โTrueto create a smart collection. DefaultFalse. - limit (
int) โ smart collections only, limit the number of items in the collection. - libtype (
str) โ smart collections only, the specific type of content to filter (movie,show,season,episode,artist,album,track,photoalbum,photo). - sort (
strorlist, optional) โ smart collections only, a string of comma separated sort fields or a list of sort fields in the formatcolumn:dir. Seesearch()for more info. - filters (
dict) โ smart collections only, a dictionary of advanced filters. Seesearch()for more info. - **kwargs (
dict) โ smart collections only, additional custom filters to apply to the search results. Seesearch()for more info.
Raises
plexapi.exceptions.BadRequestโ when no items are included to create the collection. bestie you have to put something in it ๐ญplexapi.exceptions.BadRequestโ when mixing media types in the collection. don't mix, it's giving chaos.
Returns a new instance of the created Collection.
Return type Collection
sync(videoQuality=None, photoResolution=None, audioBitrate=None, client=None, clientId=None, limit=None, unwatched=False, title=None)โ add the collection as a sync item for the specified device. take it offline, iconic behavior ๐
Parameters
- videoQuality (
int) โ idx of quality of the video, one ofVIDEO_QUALITY_*values defined in thesyncmodule. Used only when the collection contains video. - photoResolution (
str) โ maximum allowed resolution for synchronized photos, seePHOTO_QUALITY_*values in the modulesync. Used only when the collection contains photos. - audioBitrate (
int) โ maximum bitrate for synchronized music, better use one ofMUSIC_BITRATE_*values from the modulesync. Used only when the collection contains audio. - client (
MyPlexDevice) โ sync destination, seesync(). - clientId (
str) โ sync destination, seesync(). - limit (
int) โ maximum count of items to sync, unlimited ifNone. - unwatched (
bool) โ ifTruewatched videos wouldn't be synced. no reruns for you โ - title (
str) โ descriptive title for the newSyncItem, if empty the value would be generated from metadata of current photo.
Raises
BadRequestโ when the collection is not allowed to sync.Unsupportedโ when collection content is unsupported.
Returns a new instance of the created sync item.
Return type SyncItem
- property
metadataDirectoryโ returns the Plex Media Server data directory where the metadata is stored. that's where the lore lives ๐๏ธ
๐ธ CONFIG PLEXAPI.CONFIG ๐ธ
class plexapi.config.PlexConfig(path)
Bases: ConfigParser
PlexAPI configuration object, bestie. Settings are stored in an INI file within the user's home directory and can be overridden after importing plexapi by simply setting the value. See the documentation section 'Configuration' for more details on available options. iykyk ๐ง
Parameters
- path (
str) โ path of the configuration file to load.
get(key, default=None, cast=None)
Returns the specified configuration value or <default> if not found. literally the lookup girlie ๐
Parameters
- key (
str) โ configuration variable to load in the format'<section>.<variable>'. - default โ default value to use if key not found.
- cast (
func) โ cast the value to the specified type before returning.
plexapi.config.reset_base_headers()
Convenience function returns a dict of all base X-Plex-* headers for session requests. free real estate ๐
๐ EXCEPTIONS PLEXAPI.EXCEPTIONS ๐
exception plexapi.exceptions.PlexApiExceptionโ Bases:Exception. Base class for all PlexAPI exceptions. the mother of all problems ๐ญexception plexapi.exceptions.BadRequestโ Bases:PlexApiException. An invalid request, generally a user error. we've all been there ๐exception plexapi.exceptions.NotFoundโ Bases:PlexApiException. Request media item or device is not found. it's giving lost in the sauce ๐exception plexapi.exceptions.UnknownTypeโ Bases:PlexApiException. Unknown library type. no idea what that is bestie ๐ฆexception plexapi.exceptions.Unsupportedโ Bases:PlexApiException. Unsupported client request. the client said no ๐exception plexapi.exceptions.Unauthorizedโ Bases:BadRequest. Invalid username/password or token. security said not today ๐ฅexception plexapi.exceptions.TwoFactorRequiredโ Bases:Unauthorized. Two factor authentication required. extra lock, extra slay ๐
class plexapi.gdm.GDM
Bases: object โ it's the base class for discovering GDM services, bestie โจ
Variables
entries(List<dict>) โ the list of server and/or client data that got discovered ๐scan(scan_for_clients=False)โ scan the network, go off ๐all(scan_for_clients=False)โ return all found entries. It'll scan for entries if it hasn't scanned recently, no cap ๐find_by_content_type(value)โ return a list of entries that match thecontent_type๐ฏfind_by_data(values)โ return a list of entries that match the search parameters ๐ซถupdate(scan_for_clients)โ scan for new GDM services ๐ฅ
Examples of the dict list assigned to self.entries by this function, literally here they are:
Server ๐ฅ๏ธ:
[{'data': {
'Content-Type': 'plex/media-server', 'Host':
'53f4b5b6023d41182fe88a99b0e714ba.plex.direct',
'Name': 'myfirstplexserver', 'Port':
'32400', 'Resource-Identifier':
'646ab0aa8a01c543e94ba975f6fd6efadc36b7',
'Updated-At': '1585769946', 'Version':
'1.18.8.2527-740d4c206',
}, 'from': ('10.10.10.100', 32414)}]
Clients ๐ฑ:
[{'data': {'Content-Type': 'plex/media-player',
'Device-Class': 'stb', 'Name': 'plexamp',
'Port': '36000', 'Product': 'Plexamp',
'Protocol': 'plex', 'Protocol-Capabilities':
'timeline,playback,playqueues,playqueues-creation',
'Protocol-Version': '1',
'Resource-Identifier':
'b6e57a3f-e0f8-494f-8884-f4b58501467e',
'Version': '1.1.0',
}, 'from': ('10.10.10.101', 32412)}]
plexapi.gdm.main() โ test GDM discovery ๐งช ngl that's the whole job
๐ฆ LIBRARY PLEXAPI.LIBRARY ๐ฆ
class plexapi.library.Library(server, data, initpath=None, parent=None)
Bases: PlexObject
Okay so this one represents a PlexServer library โ it's got all the sections of media defined in your Plex server, including video, shows and audio. Main character energy honestly ๐
Variables
key(str) โ'/library'identifier(str) โ Unknown ('com.plexapp.plugins.library')mediaTagVersion(str) โ Unknown (/system/bundle/media/flags/)server(PlexServer) โ thePlexServerthis client is connected to ๐ซถtitle1(str) โ'Plex Library'(not sure how useful this is, genuinely ๐ญ)title2(str) โ second title (this is blank on my setup, fr)sections()โ returns a list of all media sections in this library. Library sections may be any ofMovieSection,ShowSection,MusicSection,PhotoSection๐section(title)โ returns theLibrarySectionthat matches the specified title. Note: multiple library sections with the same title is ambiguous. UsesectionByID()instead for an exact match, bestie ๐ฏ
Parameters:
title(str) โ title of the section to return.
Raises NotFound โ the library section title is not found on the server.
sectionByID(sectionID)โ returns theLibrarySectionthat matches the specifiedsectionID.
Parameters:
sectionID(int) โ ID of the section to return.
Raises NotFound โ the library section ID is not found on the server.
hubs(sectionID=None, identifier=None, **kwargs)โ returns a list ofHubacross all library sections ๐
Parameters:
sectionID(intorstrorlist, optional) โ IDs of the sections to limit results, or"playlists"identifier(strorlist, optional) โ names of identifiers to limit results. Available onHubinstances as thehubIdentifierattribute. Examples:'home.continue'or'home.ondeck'
all(**kwargs)โ returns a list of all media from all library sections. This may be a very large dataset to retrieve, so likeโฆ be aware ๐ญonDeck()โ returns a list of all media items on deck ๐recentlyAdded()โ returns a list of all media items recently added โจsearch(title=None, libtype=None, **kwargs)โ searching within a library section is much more powerful. It seems certain attributes on the media objects can be targeted to filter this search down a bit, but I haven't found the documentation for it.
Example: "studio=Comedy%20Central" or "year=1999" "title=Kung Fu" all work. Other items such as actor=<id> seem to work, but require you already know the id of the actor. TLDR: this is untested but seems to work. Use library section search when you can ๐
cleanBundles()โ poster images and other metadata for items in your library are kept in "bundle" packages. When you remove items from your library, these bundles aren't immediately removed. Removing these old bundles can reduce the size of your install. By default, your server will automatically clean up old bundles once a week as part of Scheduled Tasks ๐งนemptyTrash()โ if a library has items in the Library Trash, use this option to empty the Trash ๐๏ธoptimize()โ the Optimize option cleans up the server database from unused or fragmented data. For example, if you have deleted or added an entire library or many items in a library, you may like to optimize the database ๐update()โ scan this library for new items ๐cancelUpdate()โ cancel a library update, we love an undo button ๐refresh()โ forces a download of fresh media information from the internet. This can take a long time. Any locked fields are not modified โณdeleteMediaPreviews()โ delete the preview thumbnails for the all sections. This cannot be undone. Recreating media preview files can take hours or even days ๐ญ no cap, be carefuladd(name='', type='', agent='', scanner='', location='', language='en-US', *args, **kwargs)โ simplified add for the most common options ๐
Parameters:
name(str) โ name of the libraryagent(str) โ examplecom.plexapp.agents.imdbtype(str) โmovie,show,# check melocation(strorlist) โ/path/to/files,["/path/to/files", "/path/to/morefiles"]language(str) โ four letter language code (e.g.en-US)kwargs(dict) โ advanced options should be passed as a dict. where the id is the key.
Photo Preferences ๐ธ
agent(str):com.plexapp.agents.noneenableAutoPhotoTags(bool): Tag photos. Default valuefalse.enableBIFGeneration(bool): Enable video preview thumbnails. Default valuetrue.includeInGlobal(bool): Include in dashboard. Default valuetrue.scanner(str):Plex Photo Scanner
Movie Preferences ๐ฌ
agent(str):com.plexapp.agents.none,com.plexapp.agents.imdb,tv.plex.agents.movie,com.plexapp.agents.themoviedbenableBIFGeneration(bool): Enable video preview thumbnails. Default valuetrue.enableCinemaTrailers(bool): Enable Cinema Trailers. Default valuetrue.includeInGlobal(bool): Include in dashboard. Default valuetrue.scanner(str):Plex Movie,Plex Movie Scanner,Plex Video Files Scanner,Plex Video Files
IMDB Movie Options (com.plexapp.agents.imdb) โญ
title(bool): Localized titles. Default valuefalse.extras(bool): Find trailers and extras automatically (Plex Pass required). Default valuetrue.only_trailers(bool): Skip extras which aren't trailers. Default valuefalse.redband(bool): Use red band (restricted audiences) trailers when available. Default valuefalse.native_subs(bool): Include extras with subtitles in Library language. Default valuefalse.cast_list(int): Cast List Source: Default value1Possible options:0:IMDb,1:The Movie Database.ratings(int): Ratings Source, Default value0Possible options:0:Rotten Tomatoes, 1:IMDb, 2:The Movie Database.summary(int): Plot Summary Source: Default value1Possible options:0:IMDb,1:The Movie Database.
country(int) โ the country vibe check ๐ default is46, and here's the whole dropdown, no cap:0:Argentina,1:Australia,2:Austria,3:Belgium,4:Belize,5:Bolivia,6:Brazil,7:Canada,8:Chile,9:Colombia,10:Costa Rica,11:Czech Republic,12:Denmark,13:Dominican Republic,14:Ecuador,15:El Salvador,16:France,17:Germany,18:Guatemala,19:Honduras,20:Hong Kong SAR,21:Ireland,22:Italy,23:Jamaica,24:Korea,25:Liechtenstein,26:Luxembourg,27:Mexico,28:Netherlands,29:New Zealand,30:Nicaragua,31:Panama,32:Paraguay,33:Peru,34:Portugal,35:Peoples Republic of China,36:Puerto Rico,37:Russia,38:Singapore,39:South Africa,40:Spain,41:Sweden,42:Switzerland,43:Taiwan,44:Trinidad,45:United Kingdom,46:United States,47:Uruguay,48:Venezuela.collections(bool) โ pull in collection info from The Movie Database. Default isfalse๐ฌlocalart(bool) โ prefer artwork that matches your library language. Default istrue๐จadult(bool) โ include adult content. Default isfalse๐usage(bool) โ send anonymous usage data to Plex. Default istrue๐
๐ฅ TheMovieDB Movie Options (com.plexapp.agents.themoviedb)
collections(bool) โ use collection info from The Movie Database. Default isfalse.localart(bool) โ prefer artwork based on library language. Default istrue.adult(bool) โ include adult content. Default isfalse.country(int) โ country (used for release date and content rating). Default is47. Possible options, and yes the first one really is just an empty label, that's canon, don't come for me:0:,1:Argentina,2:Australia,3:Austria,4:Belgium,5:Belize,6:Bolivia,7:Brazil,8:Canada,9:Chile,10:Colombia,11:Costa Rica,12:Czech Republic,13:Denmark,14:Dominican Republic,15:Ecuador,16:El Salvador,17:France,18:Germany,19:Guatemala,20:Honduras,21:Hong Kong SAR,22:Ireland,23:Italy,24:Jamaica,25:Korea,26:Liechtenstein,27:Luxembourg,28:Mexico,29:Netherlands,30:New Zealand,31:Nicaragua,32:Panama,33:Paraguay,34:Peru,35:Portugal,36:Peoples Republic of China,37:Puerto Rico,38:Russia,39:Singapore,40:South Africa,41:Spain,42:Sweden,43:Switzerland,44:Taiwan,45:Trinidad,46:United Kingdom,47:United States,48:Uruguay,49:Venezuela.
๐บ Show Preferences
agent(str) โ pick your fighter:com.plexapp.agents.none,com.plexapp.agents.thetvdb,com.plexapp.agents.themoviedb,tv.plex.agents.seriesโจenableBIFGeneration(bool) โ enable video preview thumbnails. Default istrue๐๏ธepisodeSort(int) โ episode order. Default is-1. Possible options:0:Oldest first,1:Newest first.flattenSeasons(int) โ seasons. Default is0. Possible options:0:Show,1:Hide.includeInGlobal(bool) โ include in dashboard. Default istrue.scanner(str) โPlex TV Series,Plex Series Scanner๐
๐ผ TheTVDB Show Options (com.plexapp.agents.thetvdb)
extras(bool) โ find trailers and extras automatically (Plex Pass required). Default istrue๐ฌnative_subs(bool) โ include extras with subtitles in Library language. Default isfalse๐ฌ
๐ฌ TheMovieDB Show Options (com.plexapp.agents.themoviedb)
collections(bool) โ use collection info from The Movie Database. Default isfalse.localart(bool) โ prefer artwork based on library language. Default istrue.adult(bool) โ include adult content. Default isfalse.country(int) โ country (used for release date and content rating). Default is47. Options (again with the mystery0:slot, she's iconic at this point):0:,1:Argentina,2:Australia,3:Austria,4:Belgium,5:Belize,6:Bolivia,7:Brazil,8:Canada,9:Chile,10:Colombia,11:Costa Rica,12:Czech Republic,13:Denmark,14:Dominican Republic,15:Ecuador,16:El Salvador,17:France,18:Germany,19:Guatemala,20:Honduras,21:Hong Kong SAR,22:Ireland,23:Italy,24:Jamaica,25:Korea,26:Liechtenstein,27:Luxembourg,28:Mexico,29:Netherlands,30:New Zealand,31:Nicaragua,32:Panama,33:Paraguay,34:Peru,35:Portugal,36:Peoples Republic of China,37:Puerto Rico,38:Russia,39:Singapore,40:South Africa,41:Spain,42:Sweden,43:Switzerland,44:Taiwan,45:Trinidad,46:United Kingdom,47:United States,48:Uruguay,49:Venezuela.
๐๏ธ Other Video Preferences
agent(str) โ the lineup:com.plexapp.agents.none,com.plexapp.agents.imdb,com.plexapp.agents.themoviedbenableBIFGeneration(bool) โ enable video preview thumbnails. Default istrue๐ผ๏ธenableCinemaTrailers(bool) โ enable Cinema Trailers. Default istrue๐ฟincludeInGlobal(bool) โ include in dashboard. Default istrue.scanner(str) โPlex Movie Scanner,Plex Video Files Scanner
โญ IMDB Other Video Options (com.plexapp.agents.imdb)
title(bool) โ localized titles. Default isfalse.extras(bool) โ find trailers and extras automatically (Plex Pass required). Default istrue.only_trailers(bool) โ skip extras which aren't trailers. Default isfalse.redband(bool) โ use red band (restricted audiences) trailers when available. Default isfalse๐native_subs(bool) โ include extras with subtitles in Library language. Default isfalse.cast_list(int) โ Cast List Source. Default is1. Possible options:0:IMDb,1:The Movie Database.ratings(int) โ Ratings Source. Default is0. Possible options:0:Rotten Tomatoes,1:IMDb,2:The Movie Database.summary(int) โ Plot Summary Source. Default is1. Possible options:0:IMDb,1:The Movie Database.country(int) โ Country. Default is46. Possible options:0:Argentina,1:Australia,2:Austria,3:Belgium,4:Belize,5:Bolivia,6:Brazil,7:Canada,8:Chile,9:Colombia,10:Costa Rica,11:Czech Republic,12:Denmark,13:Dominican Republic,14:Ecuador,15:El Salvador,16:France,17:Germany,18:Guatemala,19:Honduras,20:Hong Kong SAR,21:Ireland,22:Italy,23:Jamaica,24:Korea,25:Liechtenstein,26:Luxembourg,27:Mexico,28:Netherlands,29:New Zealand,30:Nicaragua,31:Panama,32:Paraguay,33:Peru,34:Portugal,35:Peoples Republic of China,36:Puerto Rico,37:Russia,38:Singapore,39:South Africa,40:Spain,41:Sweden,42:Switzerland,43:Taiwan,44:Trinidad,45:United Kingdom,46:United States,47:Uruguay,48:Venezuela.collections(bool) โ use collection info from The Movie Database. Default isfalse.localart(bool) โ prefer artwork based on library language. Default istrue.adult(bool) โ include adult content. Default isfalse.usage(bool) โ send anonymous usage data to Plex. Default istrue.
๐ฅ TheMovieDB Other Video Options (com.plexapp.agents.themoviedb)
collections(bool) โ use collection info from The Movie Database. Default isfalse.localart(bool) โ prefer artwork based on library language. Default istrue.adult(bool) โ include adult content. Default isfalse.country(int) โ country (used for release date and content rating). Default is47. Possible options:0:,1:Argentina,2:Australia,3:Austria,4:Belgium,5:Belize,6:Bolivia,7:Brazil,8:Canada,9:Chile,10:Colombia,11:Costa Rica,12:Czech Republic,13:Denmark,14:Dominican Republic,15:Ecuador,16:El Salvador,17:France,18:Germany,19:Guatemala,20:Honduras,21:Hong Kong SAR,22:Ireland,23:Italy,24:Jamaica,25:Korea,26:Liechtenstein,27:Luxembourg,28:Mexico,29:Netherlands,30:New Zealand,31:Nicaragua,32:Panama,33:Paraguay,34:Peru,35:Portugal,36:Peoples Republic of China,37:Puerto Rico,38:Russia,39:Singapore,40:South Africa,41:Spain,42:Sweden,43:Switzerland,44:Taiwan,45:Trinidad,46:United Kingdom,47:United States,48:Uruguay,49:Venezuela.
๐ฐ๏ธ history(maxresults=None, mindate=None)
history(maxresults=None, mindate=None)
Get Play History for all library Sections for the owner ๐ like a full receipts drop.
maxresultsโ only return the specified number of results, and it's optional. Type:int.mindateโ min datetime to return results from. Type:datetimeโฐ
๐ท๏ธ tags(tag)
tags(tag)
Returns a list of LibraryMediaTag objects for the specified tag ๐ give her a tag and she gives you the whole squad back.
Parameters
tag(str) โ Tag name (seeTAGTYPES).
๐ plexapi.library.LibrarySection
class plexapi.library.LibrarySection(server, data, initpath=None, parent=None)
Bases: PlexObject
Okay bestie, this is the base class for a single library section โ the main-character blueprint that all your movie/show/music library sections build on. ๐
๐ธ Variables
agent(str) โ The metadata agent used for the library section (com.plexapp.agents.imdb, etc).allowSync(bool) โTrueif you allow syncing content from the library section.art(str) โ Background artwork used to represent the library section.composite(str) โ Composite image used to represent the library section.createdAt(datetime) โ Datetime the library section was created.filters(bool) โTrueif filters are available for the library section.key(int) โ Key (or ID) of this library section.language(str) โ Language represented in this section (en,xn, etc).locations(List<str>) โ List of folder paths added to the library section.refreshing(bool) โTrueif this section is currently being refreshed.scanner(str) โ Internal scanner used to find media (Plex Movie Scanner,Plex Premium Music Scanner, etc.)thumb(str) โ Thumbnail image used to represent the library section.title(str) โ Name of the library section.type(str) โ Type of content section represents (movie,show,artist,photo).updatedAt(datetime) โ Datetime the library section was last updated.uuid(str) โ Unique id for the section (32258d7c-3e6c-4ac5-98ad-bad7a3b78c63)
property totalSize
Returns the total number of items in the library for the default library type. โจ
property totalDuration
Returns the total duration (in milliseconds) of items in the library. โฑ๏ธ
property totalStorage
Returns the total storage (in bytes) of items in the library. ๐พ
totalViewSize(libtype=None, includeCollections=True)
Returns the total number of items in the library for a specified libtype. The number of items for the default library type will be returned if no libtype is specified. (e.g. Specify libtype='episode' for the total number of episodes or libtype='albums' for the total number of albums.) ๐ฌ
Parameters
libtype(str, optional) โ The type of items to return the total number for (movie,show,season,episode,artist,album,track,photoalbum). Default is the main library type.includeCollections(bool, optional) โTrueorFalseto include collections in the total number. Default isTrue.
delete()
Delete a library section. ๐๏ธ
edit(agent=None, **kwargs)
Edit a library. See Library for example usage.
Parameters
agent(str, optional) โ The library agent.kwargs(dict) โ Dict of settings to edit.
addLocations(location)
Add a location to a library. ๐
Parameters
location(str or list) โ A single folder path, list of paths.
Example
LibrarySection.addLocations('/path/1')
LibrarySection.addLocations(['/path/1', 'path/2', '/path/3'])
removeLocations(location)
Remove a location from a library. ๐ฎ
Parameters
location(str or list) โ A single folder path, list of paths.
Example
LibrarySection.removeLocations('/path/1')
LibrarySection.removeLocations(['/path/1', 'path/2', '/path/3'])
get(title, **kwargs)
Returns the media item with the specified title and kwargs.
Parameters
title(str) โ Title of the item to return.kwargs(dict) โ Additional search parameters. Seesearch()for more info.
Raises NotFound โ The title is not found in the library.
getGuid(guid)
Returns the media item with the specified external Plex, IMDB, TMDB, or TVDB ID.
Note: Only available for the Plex Movie and Plex TV Series agents. ๐
Parameters
guid(str) โ The external guid of the item to return. Examples: Plexplex://show/5d9c086c46115600200aa2feIMDBimdb://tt0944947, TMDBtmdb://1399, TVDBtvdb://121361.
Raises NotFound โ The guid is not found in the library.
Example
result1 = library.getGuid('plex://show/5d9c086c46115600200aa2fe')
result2 = library.getGuid('imdb://tt0944947')
result3 = library.getGuid('tmdb://1399')
result4 = library.getGuid('tvdb://121361')
# Alternatively, create your own guid lookup dictionary for faster performance
guidLookup = {}
for item in library.all():
guidLookup[item.guid] = item
guidLookup.update({guid.id: item for guid in item.guids})
result1 = guidLookup['plex://show/5d9c086c46115600200aa2fe']
result2 = guidLookup['imdb://tt0944947']
result3 = guidLookup['tmdb://1399']
result4 = guidLookup['tvdb://121361']
all(libtype=None, **kwargs)
Returns a list of all items from this library section. See description of search() for details about filtering / sorting. ๐ฆ
folders()
Returns a list of available Folder for this library section.
managedHubs()
Returns a list of available ManagedHub for this library section.
resetManagedHubs()
Reset the managed hub customizations for this library section.
hubs()
Returns a list of available Hub for this library section.
agents()
Returns a list of available Agent for this library section.
settings()
Returns a list of all library settings. โ๏ธ
editAdvanced(**kwargs)
Edit a library's advanced settings.
defaultAdvanced()
Edit all of library's advanced settings to default.
lockAllField(field, libtype=None)
Lock a field for all items in the library. ๐
Parameters
field(str) โ The field to lock (e.g.thumb,rating,collection).libtype(str, optional) โ The library type to lock (movie,show,season,episode,artist,album,track,photoalbum,photo). Default is the main library type.
unlockAllField(field, libtype=None)
Unlock a field for all items in the library. ๐
Parameters
field(str) โ The field to unlock (e.g.thumb,rating,collection).libtype(str, optional) โ The library type to lock (movie,show,season,episode,artist,album,track,photoalbum,photo). Default is the main library type.
timeline()
Returns a timeline query for this library section. ๐
onDeck()
Returns a list of media items on deck from this library section. ๐ฟ
continueWatching()
Return a list of media items in the library's Continue Watching hub. ๐
recentlyAdded(maxresults=50, libtype=None)
Returns a list of media items recently added from this library section. ๐
Parameters
maxresults(int) โ Max number of items to return (default50).libtype(str, optional) โ The library type to filter (movie,show,season,episode,artist,album,track,photoalbum,photo). Default is the main library type.
analyze()
Run an analysis on all of the items in this library section. See analyze() for more details.
emptyTrash()
If a section has items in the Trash, use this option to empty the Trash. ๐๏ธโจ
update(path=None)
Scan this section for new media.
Parameters
path(str, optional) โ Full path to folder to scan.
cancelUpdate()
Cancel update of this Library Section. โ
refresh()
Forces a download of fresh media information from the internet. This can take a long time. Any locked fields are not modified. ๐
deleteMediaPreviews()
Delete the preview thumbnails for items in this library. This cannot be undone. Recreating media preview files can take hours or even days. ๐ญ๐
filterTypes()
Returns a list of available FilteringType for this library section.
getFilterType(libtype=None)
Returns a FilteringType for a specified libtype.
Parameters
libtype(str, optional) โ The library type to filter (movie,show,season,episode,artist,album,track,photoalbum,photo,collection).
Raises NotFound โ Unknown libtype for this library.
fieldTypes() ๐
okay so this one just hands you back a list of every available FilteringFieldType for this library section. that's the whole thing. no cap, that's it.
getFieldType(fieldType) ๐
gives you back one single FilteringFieldType for a specific fieldType. lowkey useful, honestly.
Parameters
fieldType(str) โ the data type for the field. the valid ones aretag,integer,string,boolean,date,subtitleLanguage,audioLanguage,resolution.
Raises
NotFoundโ you asked for an unknownfieldTypefor this library. it's not a phase, it's just not there.
listFilters(libtype=None) ๐
returns a list of every available FilteringFilter for a given libtype. this is literally the list of options you see in the filter dropdown menu (screenshot). so iconic of her.
Parameters
libtype(str, optional) โ the library type to filter. options aremovie,show,season,episode,artist,album,track,photoalbum,photo,collection.
Example
availableFilters = [f.filter for f in library.listFilters()]
print("Available filter fields:", availableFilters)
listSorts(libtype=None) โจ
returns a list of every available FilteringSort for a given libtype. this is the list of options in the sorting dropdown menu (screenshot). the way she sorts ๐
Parameters
libtype(str, optional) โ the library type to filter. the choices aremovie,show,season,episode,artist,album,track,photoalbum,photo,collection.
Example
availableSorts = [f.key for f in library.listSorts()]
print("Available sort fields:", availableSorts)
listFields(libtype=None) ๐ธ
returns a list of every available FilteringFields for a given libtype. these are the options in the custom filter dropdown menu (screenshot). bestie she's giving options.
Parameters
libtype(str, optional) โ the library type to filter. pick frommovie,show,season,episode,artist,album,track,photoalbum,photo,collection.
Example
availableFields = [f.key.split('.')[-1] for f in library.listFields()]
print("Available fields:", availableFields)
listOperators(fieldType) ๐ง
returns a list of every available FilteringOperator for a given fieldType. this is the list of options in the custom filter operator dropdown menu (screenshot). yes, operators have their own moment.
Parameters
fieldType(str) โ the data type for the field. valid ones:tag,integer,string,boolean,date,subtitleLanguage,audioLanguage,resolution.
Example
field = 'genre' # Available filter field from listFields()
filterField = next(f for f in library.listFields() if f.key.endswith(field))
availableOperators = [o.key for o in library.listOperators(filterField.type)]
print(f"Available operators for {field}:", availableOperators)
listFilterChoices(field, libtype=None) ๐ฆ
returns a list of every available FilterChoice for a given FilteringFilter or filter field. this is the list of available values for a custom filter (screenshot). the whole menu, unlocked.
Parameters
field(str) โ aFilteringFilterobject, or just the name of the field (genre,year,contentRating, etc.).libtype(str, optional) โ the library type to filter. your choices aremovie,show,season,episode,artist,album,track,photoalbum,photo,collection.
Raises
BadRequestโ invalid filter field. not her.NotFoundโ unknown filter field. also not her.
Example
field = 'genre' # Available filter field from listFilters()
availableChoices = [f.title for f in library.listFilterChoices(field)]
print(f"Available choices for {field}:", availableChoices)
hubSearch(query, mediatype=None, limit=None) ๐ฅ
returns the hub search results for this library. fr fr, see plexapi.server.PlexServer.search() for all the details and parameters โ she's the main character of search.
search(title=None, sort=None, maxresults=None, libtype=None, container_start=None, container_size=None, limit=None, filters=None, **kwargs) ๐
searches the library. the http requests get batched in container_size. and here's a tip that will save your whole life: if you only want the first <num> results, set the maxresults option to that number so the search doesn't sit there iterating over all the results on the server. respectfully, don't make her do all that.
Parameters
title(str, optional) โ a general string query to search for. partial string matches are allowed, so you don't need the whole title.sort(FilteringSort or str or list, optional) โ a field to sort the results by. the details live below ๐maxresults(int, optional) โ only return the specified number of results.libtype(str, optional) โ return results of a specific type (movie,show,season,episode,artist,album,track,photoalbum,photo,collection) (e.g.libtype='episode'will only returnEpisodeobjects).container_start(int, optional) โ default0.container_size(int, optional) โ defaults toX_PLEX_CONTAINER_SIZEin your config file.limit(int, optional) โ limit the number of results from the filter.filters(dict, optional) โ a dictionary of advanced filters. details below ๐**kwargs(dict) โ additional custom filters to apply to the search results. details below ๐
Raises
BadRequestโ when the sort or filter is invalid.NotFoundโ when applying an unknown sort or filter.
โจ Sorting Results โจ
the search results can be sorted by including the sort parameter. periodt.
- see
listSorts()to get a list of available sort fields.
the sort parameter can be a FilteringSort object, or a sort string in the format field:dir. the sort direction dir can be asc, desc, or nullsLast. omitting the sort direction, or passing a FilteringSort object, will sort the results in the default direction of the field. multi-sorting on multiple fields is a vibe you can absolutely have โ use a comma separated list of sort strings, or a list of FilteringSort object or strings.
Examples
library.search(sort="titleSort:desc") # Sort title in descending order
library.search(sort="titleSort") # Sort title in the default order
# Multi-sort by year in descending order, then by audience rating in descending order
library.search(sort="year:desc,audienceRating:desc")
library.search(sort=["year:desc", "audienceRating:desc"])
๐ Using Plex Filters ๐
any of the available custom filters can be applied to the search results (screenshot). obsessed.
- see
listFields()to get a list of all available fields. - see
listOperators()to get a list of all available operators. - see
listFilterChoices()to get a list of all available filter values.
the filter fields below are just some examples of the possible filters. this list is not exhaustive, and not all filters apply to all library types. iykyk.
actor(MediaTag): search for the name of an actor.addedAt(datetime): search for items added before or after a date. see operators below.audioLanguage(str): search for a specific audio language (3 character code, e.g.jpn).collection(MediaTag): search for the name of a collection.contentRating(MediaTag): search for a specific content rating.country(MediaTag): search for the name of a country.decade(int): search for a specific decade (e.g.2000).director(MediaTag): search for the name of a director.duplicate(bool) search for duplicate items.genre(MediaTag): search for a specific genre.hdr(bool): search for HDR items.inProgress(bool): search for in progress items.label(MediaTag): search for a specific label.lastViewedAt(datetime): search for items watched before or after a date. see operators below.mood(MediaTag): search for a specific mood.producer(MediaTag): search for the name of a producer.resolution(str): search for a specific resolution (e.g.1080).studio(str): search for the name of a studio.style(MediaTag): search for a specific style.subtitleLanguage(str): search for a specific subtitle language (3 character code, e.g.eng)unmatched(bool): search for unmatched items.unwatched(bool): search for unwatched items.userRating(int): search for items with a specific user rating.writer(MediaTag): search for the name of a writer.year(int): search for a specific year.
tag type filter values can be a FilterChoice object, a MediaTag object, the exact name MediaTag.tag (str), or the exact id MediaTag.id (int). any of those, bestie. she's flexible ๐
So like, date type filter values can be a datetime object, a relative date using one of the available date suffixes (e.g. 30d) (str), or a date in YYYY-MM-DD (str) format. Bestie, pick your fighter ๐
Relative date suffixes, memorise these:
s: secondsm: minutesh: hoursd: daysw: weeksmon: monthsy: years
Multiple values can be OR together by providing a list of values. Yes queen, list it up โจ
๐ Examples
library.search(unwatched=True, year=2020, resolution="4k")
library.search(actor="Arnold Schwarzenegger", decade=1990)
library.search(contentRating="TV-G", genre="animation")
library.search(genre=["animation", "comedy"]) # Genre is animation OR comedy
library.search(studio=["Disney", "Pixar"]) # Studio contains Disney OR Pixar
๐ธ Using a libtype Prefix
Okay so some filters may be prefixed by the libtype separated by a . (e.g. show.collection, episode.title, artist.style, album.genre, track.userRating, etc.). Do not confuse this with the libtype parameter, they are literally different things ๐ If no libtype prefix is provided, then the default library type is assumed. For example, in a TV show library viewCount is assumed to be show.viewCount. If you want to filter using episode view count then you must specify episode.viewCount explicitly. In addition, if the filter does not exist for the default library type it will fallback to the most specific libtype available. For example, show.unwatched does not exists so it will fallback to episode.unwatched. The libtype prefix cannot be included directly in the function parameters so the filters must be provided as a filters dictionary. iykyk ๐ง
โญ Examples
library.search(filters={"show.collection": "Documentary", "episode.inProgress": True})
library.search(filters={"artist.genre": "pop", "album.decade": 2000})
# The following three options are identical and will return Episode objects
showLibrary.search(title="Winter is Coming", libtype='episode')
showLibrary.search(libtype='episode', filters={"episode.title": "Winter is Coming"})
showLibrary.searchEpisodes(title="Winter is Coming")
# The following will search for the episode title but return Show objects
showLibrary.search(filters={"episode.title": "Winter is Coming"})
# The following will fallback to episode.unwatched
showLibrary.search(unwatched=True)
๐ฅ Using Plex Operators
Operators can be appended to the filter field to narrow down results with more granularity. The following is a list of possible operators depending on the data type of the filter being applied. A special & operator can also be used to AND together a list of values. Slay ๐
Type: MediaTag or subtitleLanguage or audioLanguage
- no operator: is
!: is not
Type: int
- no operator: is
!: is not>>: is greater than<<: is less than
Type: str
- no operator: contains
!: does not contain=: is!=: is not<: begins with>: ends with
Type: bool
- no operator: is true
!: is false
Type: datetime
<<: is before>>: is after
Type: resolution or guid
- no operator: is
Operators cannot be included directly in the function parameters so the filters must be provided as a filters dictionary. That's the rule, no cap ๐ซถ
๐ Examples
# Genre is horror AND thriller
library.search(filters={"genre&": ["horror", "thriller"]})
# Director is not Steven Spielberg
library.search(filters={"director!": "Steven Spielberg"})
# Title starts with Marvel and added before 2021-01-01
library.search(filters={"title<": "Marvel", "addedAt<<": "2021-01-01"})
# Added in the last 30 days using relative dates
library.search(filters={"addedAt>>": "30d"})
# Collection is James Bond and user rating is greater than 8
library.search(filters={"collection": "James Bond", "userRating>>": 8})
๐ฆ Using Advanced Filters
Any of the Plex filters described above can be combined into a single filters dictionary that mimics the advanced filters used in Plex Web with a tree of and/or branches. Each level of the tree must start with and (Match all of the following) or or (Match any of the following) as the dictionary key, and a list of dictionaries with the desired filters as the dictionary value. It's giving decision tree, honestly iconic ๐
The following example matches this advanced filter in Plex Web.
๐ Examples
advancedFilters = {
'and': [ # Match all of the following in this list
{
'or': [ # Match any of the following in this list
{'title': 'elephant'},
{'title': 'bunny'}
]
},
{'year>>': 1990},
{'unwatched': True}
]
}
library.search(filters=advancedFilters)
๐ Using PlexAPI Operators
For even more advanced filtering which cannot be achieved in Plex, the PlexAPI operators can be applied to any XML attribute. See plexapi.base.PlexObject.fetchItems() for a list of operators and how they are used. Note that using the Plex filters above will be faster since the filters are applied by the Plex server before the results are returned to PlexAPI. Using the PlexAPI operators requires the Plex server to return all results to allow PlexAPI to do the filtering. The Plex filters and the PlexAPI operators can be used in conjunction with each other. Lowkey best of both worlds ๐
๐ Examples
library.search(summary__icontains="Christmas")
library.search(duration__gt=7200000)
library.search(audienceRating__lte=6.0, audienceRatingImage__startswith="rottentomatoes://")
library.search(media__videoCodec__exact="h265")
library.search(genre="holiday", viewCount__gte=3)
๐ sync()
sync(policy, mediaSettings, client=None, clientId=None, title=None, sort=None, libtype=None, **kwargs)
Add current library section as sync item for specified device. See description of search() for details about filtering / sorting and sync() for possible exceptions. It's giving "download this for me bestie" energy โจ
Parameters
policy(Policy) โ policy of syncing the media (how many items to sync and process watched media or not), generated automatically when method called on specificLibrarySectionobject.mediaSettings(MediaSettings) โ Transcoding settings used for the media, generated automatically when method called on specificLibrarySectionobject.client(MyPlexDevice) โ sync destination, seesync().clientId(str) โ sync destination, seesync().title(str) โ descriptive title for the newSyncItem, if empty the value would be generated from metadata of current media.sort(str) โ formatted ascolumn:dir; column can be any of {addedAt,originallyAvailableAt,lastViewedAt,titleSort,rating,mediaHeight,duration}. dir can beascordesc.libtype(str) โ Filter results to a specific libtype (movie,show,episode,artist,album,track).
Returns โ an instance of created syncItem.
Return type โ SyncItem
Raises
BadRequestโ When the library is not allowed to sync.BadRequestโ When the sort or filter is invalid.NotFoundโ When applying an unknown sort or filter.
Example
from plexapi import myplex
from plexapi.sync import Policy, MediaSettings, VIDEO_QUALITY_3_MBPS_720p
c = myplex.MyPlexAccount()
target = c.device('Plex Client')
sync_items_wd = c.syncItems(target.clientIdentifier)
srv = c.resource('Server Name').connect()
section = srv.library.section('Movies')
policy = Policy('count', unwatched=True, value=1)
media_settings = MediaSettings.create(VIDEO_QUALITY_3_MBPS_720p)
section.sync(target, policy, media_settings, title='Next best movie', sort='rating:desc')
๐ history()
history(maxresults=None, mindate=None)
Get Play History for this library Section for the owner. The receipts of what you watched ๐
maxresults(int) โ Only return the specified number of results (optional).mindate(datetime) โ Min datetime to return results from.
๐ง createCollection()
createCollection(title, items=None, smart=False, limit=None, libtype=None, sort=None, filters=None, **kwargs)
Alias for createCollection() using this LibrarySection. That's it, that's the whole vibe ๐
collection(title)
Gives you back the collection with that exact title.
Parameters:
- title (
str) โ the title of the item you want back.
Raises NotFound โ when it literally cannot find that collection. ๐ญ
collections(**kwargs)
Returns a list of collections living in this library section. If you wanna know about filtering / sorting, go read the description of search() โ it's all there, bestie.
createPlaylist(title, items=None, smart=False, limit=None, sort=None, filters=None, m3ufilepath=None, **kwargs)
Alias for createPlaylist() that uses this LibrarySection. Same energy, less typing. โจ
playlist(title)
Returns the playlist with that specified title.
Parameters:
- title (
str) โ title of the item to return.
Raises NotFound โ unable to find playlist. ๐
playlists(sort=None, **kwargs)
Returns a list of playlists from this library section.
getWebURL(base=None, tab=None, key=None)
Returns the Plex Web URL for the library. Cute, right? ๐
Parameters:
- base (
str) โ the base URL before the fragment (#!). Default ishttps://app.plex.tv/desktop. - tab (
str) โ the library tab, and your options arerecommended,library,collections,playlists,timeline. - key (
str) โ a hub key.
common(items)
Returns a Common object for the items you pass in. ๐ซถ
multiEdit(items, **kwargs)
Edits multiple objects at once. Heads up though โ this is a low level method and you genuinely need to know all the field/tag keys. If that sounds like a lot, use batchMultiEdits instead. ๐
Parameters:
- items (
List) โ list ofAudio,Video,Photo, orCollectionobjects to be edited. - kwargs (
dict) โ dict of settings to edit.
batchMultiEdits(items)
Turns on batch multi-editing mode so you save API calls. You must call saveMultiEdits() at the end to actually save all the edits โ don't forget, or nothing sticks. For the individual field and tag editing methods, see EditFieldMixin and EditTagsMixin. ๐
Parameters:
- items (
List) โ list ofAudio,Video,Photo, orCollectionobjects to be edited.
Example:
movies = MovieSection.all()
items = [movies[0], movies[3], movies[5]]
# Batch multi-editing multiple fields and tags in a single API call
MovieSection.batchMultiEdits(items)
MovieSection.editTitle('A New Title').editSummary('A new summary').editTagline('A new tagline') \
.addCollection('New Collection').removeGenre('Action').addLabel('Favorite')
MovieSection.saveMultiEdits()
saveMultiEdits()
Saves all the batch multi-edits. Details live over in batchMultiEdits(). ๐
๐ฌ class plexapi.library.MovieSection(server, data, initpath=None, parent=None)
Bases: LibrarySection, MovieEditMixins
Represents a LibrarySection section containing movies. Movie night is literally every night.
Variables:
TAG(str) โ'Directory'TYPE(str) โ'movie'
searchMovies(**kwargs)
Search for a movie. See search() for usage. ๐
recentlyAddedMovies(maxresults=50)
Returns a list of recently added movies from this library section.
Parameters:
- maxresults (
int) โ max number of items to return (default50).
sync(videoQuality, limit=None, unwatched=False, **kwargs)
Adds the current Movie library section as a sync item for the specified device. For details about filtering / sorting, see the description of search(), and for details on syncing libraries and possible exceptions, see sync().
Parameters:
- videoQuality (
int) โ idx of quality of the video, one of theVIDEO_QUALITY_*values defined in thesyncmodule. - limit (
int) โ maximum count of movies to sync, unlimited ifNone. - unwatched (
bool) โ ifTrue, watched videos wouldn't be synced.
Returns: an instance of created syncItem.
Return type: SyncItem
Example:
from plexapi import myplex
from plexapi.sync import VIDEO_QUALITY_3_MBPS_720p
c = myplex.MyPlexAccount()
target = c.device('Plex Client')
sync_items_wd = c.syncItems(target.clientIdentifier)
srv = c.resource('Server Name').connect()
section = srv.library.section('Movies')
section.sync(VIDEO_QUALITY_3_MBPS_720p, client=target, limit=1, unwatched=True,
title='Next best movie', sort='rating:desc')
๐บ class plexapi.library.ShowSection(server, data, initpath=None, parent=None)
Bases: LibrarySection, ShowEditMixins, SeasonEditMixins, EpisodeEditMixins
Represents a LibrarySection section containing tv shows. Binge-watching is a personality trait, ngl.
Variables:
TAG(str) โ'Directory'TYPE(str) โ'show'
searchShows(**kwargs)
Search for a show. See search() for usage. ๐ธ
searchSeasons(**kwargs)
Search for a season. See search() for usage. ๐ฆ
searchEpisodes(**kwargs)
Search for an episode. See search() for usage. โญ
recentlyAddedShows(maxresults=50)
Returns a list of recently added shows from this library section.
Parameters:
- maxresults (
int) โ max number of items to return (default50).
recentlyAddedSeasons(maxresults=50)
Returns a list of recently added seasons from this library section.
Parameters:
- maxresults (
int) โ max number of items to return (default50).
recentlyAddedEpisodes(maxresults=50)
Returns a list of recently added episodes from this library section.
Parameters:
- maxresults (
int) โ max number of items to return (default50).
sync(videoQuality, limit=None, unwatched=False, **kwargs)
Adds the current Show library section as a sync item for the specified device. For the filtering / sorting details, read the description of search(), and for the syncing-libraries details plus possible exceptions, read sync().
Parameters:
- videoQuality (
int) โ idx of quality of the video, one of theVIDEO_QUALITY_*values defined in thesyncmodule. - limit (
int) โ maximum count of episodes to sync, unlimited ifNone. - unwatched (
bool) โ ifTrue, watched videos wouldn't be synced.
Returns: an instance of created syncItem.
Return type: SyncItem
Example:
from plexapi import myplex
from plexapi.sync import VIDEO_QUALITY_3_MBPS_720p
c = myplex.MyPlexAccount()
target = c.device('Plex Client')
sync_items_wd = c.syncItems(target.clientIdentifier)
srv = c.resource('Server Name').connect()
section = srv.library.section('TV-Shows')
section.sync(VIDEO_QUALITY_3_MBPS_720p, client=target, limit=1, unwatched=True,
title='Next unwatched episode')
๐ง class plexapi.library.MusicSection(server, data, initpath=None, parent=None)
Bases: LibrarySection, ArtistEditMixins, AlbumEditMixins, TrackEditMixins
Represents a LibrarySection section containing music artists. The aux cord is yours, icon. ๐ฅ
Variables:
TAG(str) โ'Directory'TYPE(str) โ'artist'
albums()
Returns a list of Album objects in this section. ๐
stations()
Returns a list of Playlist stations in this section. ๐
searchArtists(**kwargs)
Search for an artist. See search() for usage.
searchAlbums(**kwargs)
Search for an album. See search() for usage.
searchTracks(**kwargs)
Search for a track. See search() for usage.
recentlyAddedArtists(maxresults=50)
Returns a list of recently added artists from this library section.
Parameters:
- maxresults (
int) โ max number of items to return (default50).
recentlyAddedAlbums(maxresults=50)
Returns a list of recently added albums from this library section.
Parameters:
- maxresults (
int) โ max number of items to return (default50).
recentlyAddedTracks(maxresults=50)
Returns a list of recently added tracks from this library section.
Parameters:
- maxresults (
int) โ max number of items to return (default50).
sync(bitrate, limit=None, **kwargs)
Adds the current Music library section as a sync item for the specified device. Filtering / sorting deets are in the description of search(), and syncing-libraries deets plus possible exceptions are in sync().
Parameters:
- bitrate (
int) โ maximum bitrate for synchronized music, and honestly it's better to use one of theMUSIC_BITRATE_*values from the modulesync. - limit (
int) โ maximum count of tracks to sync, unlimited ifNone.
Returns: an instance of created syncItem.
Return type: SyncItem
Example:
from plexapi import myplex
from plexapi.sync import AUDIO_BITRATE_320_KBPS
c = myplex.MyPlexAccount()
target = c.device('Plex Client')
sync_items_wd = c.syncItems(target.clientIdentifier)
srv = c.resource('Server Name').connect()
section = srv.library.section('Music')
section.sync(AUDIO_BITRATE_320_KBPS, client=target, limit=100, sort='addedAt:desc',
title='New music')
okay so that's literally the whole vibe โ grab your Music section, sync it to the client, cap it at 100, newest first, name it 'New music'. Ate. ๐
sonicAdventure(start: Track | int, end: Track | int, **kwargs: Any) -> list[Track] โ bestie this one hands you back a list of tracks from this library section that are part of a sonic adventure. ID's should be of a track, other ID's will return an empty list or items itself or an error. So like, keep it track IDs, iykyk. ๐ง
Parameters
start(Track | int) โ the Track or ID of the first track in the sonic adventure.end(Track | int) โ the Track or ID of the last track in the sonic adventure.kwargsโ extra parameters to pass along tofetchItems().
Returns โ a list of tracks from this library section that are part of a sonic adventure.
Return type โ List[Track]
class plexapi.library.PhotoSection(server, data, initpath=None, parent=None)
Bases: LibrarySection, PhotoalbumEditMixins, PhotoEditMixins
Represents a LibrarySection section containing photos. yes, the photo girly of the library family. ๐ธ๐ธ
Variables
TAG(str) โ'Directory'TYPE(str) โ'photo'
all(libtype=None, **kwargs) โ returns a list of all items from this library section. Wanna know about filtering / sorting? See the description of plexapi.library.LibrarySection.search().
collections(**kwargs) โ returns a list of collections from this library section. See the description of search() for the whole filtering / sorting situation.
searchAlbums(**kwargs) โ searches for a photo album. See search() for how to use it.
searchPhotos(**kwargs) โ searches for a photo. Again, search() is your girl for usage.
recentlyAddedAlbums(maxresults=50) โ returns a list of recently added photo albums from this library section.
maxresults(int) โ max number of items to return (default50).
sync(resolution, limit=None, **kwargs) โ adds the current Music library section as a sync item for the specified device. (yes it literally says Music in the photo section, we do not make the rules ๐) See the description of search() for filtering / sorting deets and sync() for the library-syncing tea and possible exceptions.
Parameters
resolution(str) โ maximum allowed resolution for synchronized photos, see thePHOTO_QUALITY_*values in the modulesync.limit(int) โ maximum count of tracks to sync, unlimited ifNone.
Returns โ an instance of the created syncItem.
Return type โ SyncItem
Example
from plexapi import myplex
from plexapi.sync import PHOTO_QUALITY_HIGH
c = myplex.MyPlexAccount()
target = c.device('Plex Client')
sync_items_wd = c.syncItems(target.clientIdentifier)
srv = c.resource('Server Name').connect()
section = srv.library.section('Photos')
section.sync(PHOTO_QUALITY_HIGH, client=target, limit=100, sort='addedAt:desc',
title='Fresh photos')
literally the same sync moment but for photos, title 'Fresh photos'. iconique. โจ
class plexapi.library.LibraryTimeline(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a LibrarySection timeline. it's giving "what's the tea on this section's timeline" energy. ๐ฐ๏ธ
Variables
TAG(str) โ'LibraryTimeline'size(int) โ UnknownallowSync(bool) โ Unknownart(str) โ relative path to art image.content(str) โ"secondary"identifier(str) โ"com.plexapp.plugins.library"latestEntryTime(int) โ epoch timestampmediaTagPrefix(str) โ"/system/bundle/media/flags/"mediaTagVersion(int) โ Unknownthumb(str) โ relative path to library thumb image.title1(str) โ name of library section.updateQueueSize(int) โ number of items queued to update.viewGroup(str) โ"secondary"viewMode(int) โ Unknown
class plexapi.library.Location(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single library Location. one path, living its best life. ๐
Variables
TAG(str) โ'Location'id(int) โ location path ID.path(str) โ path used for library.
class plexapi.library.Hub(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single Hub (or category) in the PlexServer search. like a lil curated shelf of content, slay. ๐๏ธ
Variables
TAG(str) โ'Hub'context(str) โ the context of the hub.hubKey(str) โ API URL for these specific hub items.hubIdentifier(str) โ the identifier of the hub.items(list) โ list of items in the hub (automatically loads all items ifmoreisTrue).key(str) โ API URL for the hub.random(bool) โTrueif the items in the hub are randomized.more(bool) โTrueif there are more items to load (callitemsto fetch all items).size(int) โ the number of items in the hub.style(str) โ the style of the hub.title(str) โ the title of the hub.type(str) โ the type of items in the hub.
items() โ returns a list of all items in the hub.
section() โ returns the LibrarySection this hub belongs to.
fr fr note: items shows up both as a variable and as a method here. yes that's really what the docs say. keep both. ๐ญ
class plexapi.library.LibraryMediaTag(server, data, initpath=None, parent=None)
Bases: PlexObject
Base class of library media tags. the parent energy for all the tag girlies below. ๐
Variables
TAG(str) โ'Directory'count(int) โ the number of items where this tag is found.filter(str) โ the URL filter for the tag.id(int) โ the id of the tag.key(str) โ API URL (/library/section/<librarySectionID>/all?<filter>).librarySectionID(int) โ the library section ID where the tag is found.librarySectionKey(str) โ API URL for the library section (/library/section/<librarySectionID>)librarySectionTitle(str) โ the library title where the tag is found.librarySectionType(int) โ the library type where the tag is found.reason(str) โ the reason for the search result.reasonID(int) โ the reason ID for the search result.reasonTitle(str) โ the reason title for the search result.score(float) โ the score for the search result.type(str) โ the type of search result (tag).tag(str) โ the title of the tag.tagKey(str) โ the Plex Discover ratingKey (guid) for people.tagType(int) โ the type ID of the tag.tagValue(int) โ the value of the tag.thumb(str) โ the URL for the thumbnail of the tag (if available).
items(*args, **kwargs) โ returns the list of items within this tag. simple as that. ๐
class plexapi.library.Aperture(server, data, initpath=None, parent=None)
Bases: LibraryMediaTag
Represents a single Aperture library media tag.
Variables โ TAGTYPE (int) โ 202
class plexapi.library.Art(server, data, initpath=None, parent=None)
Bases: LibraryMediaTag
Represents a single Art library media tag.
Variables โ TAGTYPE (int) โ 313
class plexapi.library.Autotag(server, data, initpath=None, parent=None)
Bases: LibraryMediaTag
Represents a single Autotag library media tag.
Variables โ TAGTYPE (int) โ 207
class plexapi.library.Chapter(server, data, initpath=None, parent=None)
Bases: LibraryMediaTag
Represents a single Chapter library media tag.
Variables โ TAGTYPE (int) โ 9
class plexapi.library.Collection(server, data, initpath=None, parent=None)
Bases: LibraryMediaTag
Represents a single Collection library media tag. (different from the top-level plexapi.collection one โ this is the library tag version, don't mix them up bestie ๐ซถ)
Variables โ TAGTYPE (int) โ 2
class plexapi.library.Concert(server, data, initpath=None, parent=None)
Bases: LibraryMediaTag
Represents a single Concert library media tag.
Variables โ TAGTYPE (int) โ 306
class plexapi.library.Country(server, data, initpath=None, parent=None)
Bases: LibraryMediaTag
Represents a single Country library media tag.
Variables โ TAGTYPE (int) โ 8
class plexapi.library.Device(server, data, initpath=None, parent=None)
Bases: LibraryMediaTag
Represents a single Device library media tag.
Variables โ TAGTYPE (int) โ 206
class plexapi.library.Director(server, data, initpath=None, parent=None)
Bases: LibraryMediaTag
Represents a single Director library media tag.
Variables โ TAGTYPE (int) โ 4
class plexapi.library.Exposure(server, data, initpath=None, parent=None)
Bases: LibraryMediaTag
Represents a single Exposure library media tag.
Variables โ TAGTYPE (int) โ 203
๐ the tag squad (aka every LibraryMediaTag subclass, all lined up)
okay bestie, this is the part where the manpage just absolutely spams you with tiny classes, and honestly? each one is giving "same energy, different number" ๐ so here's the whole crew. every single one of them takes the same constructor โ literally identical, no cap:
(server, data, initpath=None, parent=None)
and every one of them has Bases: LibraryMediaTag. the only thing that changes is the description and the TAGTYPE int. so let's go, one by one, no skipping, i promise ๐ซถ
plexapi.library.Formatโ Represents a singleFormatlibrary media tag. โจ- Signature:
class plexapi.library.Format(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ302
- Signature:
plexapi.library.Genreโ Represents a singleGenrelibrary media tag. ๐- Signature:
class plexapi.library.Genre(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ1
- Signature:
plexapi.library.Guidโ Represents a singleGuidlibrary media tag. ๐ฆ- Signature:
class plexapi.library.Guid(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ314
- Signature:
plexapi.library.ISOโ Represents a singleISOlibrary media tag. ๐- Signature:
class plexapi.library.ISO(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ204
- Signature:
plexapi.library.Labelโ Represents a singleLabellibrary media tag. ๐ท๏ธ- Signature:
class plexapi.library.Label(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ11
- Signature:
plexapi.library.Lensโ Represents a singleLenslibrary media tag. ๐- Signature:
class plexapi.library.Lens(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ205
- Signature:
plexapi.library.Makeโ Represents a singleMakelibrary media tag. ๐- Signature:
class plexapi.library.Make(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ200
- Signature:
plexapi.library.Markerโ Represents a singleMarkerlibrary media tag. ๐- Signature:
class plexapi.library.Marker(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ12
- Signature:
plexapi.library.MediaProcessingTargetโ Represents a singleMediaProcessingTargetlibrary media tag. ๐ this one is different from the rest, bestie, it's got two variables so pay attention ๐ญ- Signature:
class plexapi.library.MediaProcessingTarget(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAG(str) โ'Tag'TAGTYPE(int) โ42
- Signature:
plexapi.library.Modelโ Represents a singleModellibrary media tag. โจ- Signature:
class plexapi.library.Model(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ201
- Signature:
plexapi.library.Moodโ Represents a singleMoodlibrary media tag. ๐ง๏ธ- Signature:
class plexapi.library.Mood(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ300
- Signature:
plexapi.library.Networkโ Represents a singleNetworklibrary media tag. ๐บ- Signature:
class plexapi.library.Network(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ319
- Signature:
plexapi.library.Placeโ Represents a singlePlacelibrary media tag. ๐- Signature:
class plexapi.library.Place(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ400
- Signature:
plexapi.library.Posterโ Represents a singlePosterlibrary media tag. ๐ผ๏ธ- Signature:
class plexapi.library.Poster(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ312
- Signature:
plexapi.library.Producerโ Represents a singleProducerlibrary media tag. ๐ฌ- Signature:
class plexapi.library.Producer(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ7
- Signature:
plexapi.library.RatingImageโ Represents a singleRatingImagelibrary media tag. โญ- Signature:
class plexapi.library.RatingImage(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ316
- Signature:
plexapi.library.Reviewโ Represents a singleReviewlibrary media tag. ๐- Signature:
class plexapi.library.Review(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ10
- Signature:
plexapi.library.Roleโ Represents a singleRolelibrary media tag. ๐ญ- Signature:
class plexapi.library.Role(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ6
- Signature:
plexapi.library.Similarโ Represents a singleSimilarlibrary media tag. ๐ฏ- Signature:
class plexapi.library.Similar(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ305
- Signature:
plexapi.library.Studioโ Represents a singleStudiolibrary media tag. ๐ข- Signature:
class plexapi.library.Studio(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ318
- Signature:
plexapi.library.Styleโ Represents a singleStylelibrary media tag. ๐- Signature:
class plexapi.library.Style(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ301
- Signature:
plexapi.library.Tagโ Represents a singleTaglibrary media tag. ๐ท๏ธ and yes, the class calledTaghasTAGTYPEzero, iconic of it honestly- Signature:
class plexapi.library.Tag(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ0
- Signature:
plexapi.library.Themeโ Represents a singleThemelibrary media tag. ๐ต- Signature:
class plexapi.library.Theme(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ317
- Signature:
plexapi.library.Writerโ Represents a singleWriterlibrary media tag. โ๏ธ- Signature:
class plexapi.library.Writer(server, data, initpath=None, parent=None) - Bases:
LibraryMediaTag TAGTYPE(int) โ5
- Signature:
๐ธ the filtering girlies โ FilteringType, FilteringFilter, FilteringSort, FilteringField, FilteringFieldType, FilteringOperator
bestie these are the ones that make the search filters actually go โจ they're not tags, they're the scaffolding behind filtering. all of them are Bases: PlexObject, and they all take the same constructor shape:
(server, data, initpath=None, parent=None)
plexapi.library.FilteringType โ Represents a single filtering Type object for a library. ๐
class plexapi.library.FilteringType(server, data, initpath=None, parent=None)
Bases: PlexObject
Variables, all of them, no skimping ๐:
TAG(str) โ'Type'active(bool) โTrueif this filter type is currently active.fields(List<FilteringField>) โ List of field objects.filters(List<FilteringFilter>) โ List of filter objects.key(str) โ The API URL path for the libtype filter.sorts(List<FilteringSort>) โ List of sort objects.title(str) โ The title for the libtype filter.type(str) โ The libtype for the filter.
plexapi.library.FilteringFilter โ Represents a single Filter object for a FilteringType. ๐
class plexapi.library.FilteringFilter(server, data, initpath=None, parent=None)
Bases: PlexObject
TAG(str) โ'Filter'filter(str) โ The key for the filter.filterType(str) โ TheFilteringFieldTypetype (string, boolean, integer, date, etc).key(str) โ The API URL path for the filter.title(str) โ The title of the filter.type(str) โ'filter'
plexapi.library.FilteringSort โ Represents a single Sort object for a FilteringType. ๐
class plexapi.library.FilteringSort(server, data, initpath=None, parent=None)
Bases: PlexObject
TAG(str) โ'Sort'active(bool) โTrueif the sort is currently active.activeDirection(str) โ The currently active sorting direction.default(str) โ The currently active default sorting direction.defaultDirection(str) โ The default sorting direction.descKey(str) โ The URL key for sorting with desc.firstCharacterKey(str) โ API URL path for first character endpoint.key(str) โ The URL key for the sorting.title(str) โ The title of the sorting.
ngl thedefaultvsactivevsdefaultDirectionvsactiveDirectionquartet is a whole vibe check on its own โ they're four separate strings, don't merge them in ur head ๐ญ
plexapi.library.FilteringField โ Represents a single Field object for a FilteringType. ๐พ
class plexapi.library.FilteringField(server, data, initpath=None, parent=None)
Bases: PlexObject
TAG(str) โ'Field'key(str) โ The URL key for the filter field.title(str) โ The title of the filter field.type(str) โ TheFilteringFieldTypetype (string, boolean, integer, date, etc).subType(str) โ The subtype of the filter (decade, rating, etc).
plexapi.library.FilteringFieldType โ Represents a single FieldType for library filtering. ๐ง
class plexapi.library.FilteringFieldType(server, data, initpath=None, parent=None)
Bases: PlexObject
TAG(str) โ'FieldType'type(str) โ The filtering data type (string, boolean, integer, date, etc).operators(List<FilteringOperator>) โ List of operator objects.
plexapi.library.FilteringOperator โ Represents an single Operator for a FilteringFieldType. โ๏ธ (yes the original says "an single", we are preserving the lore fr fr)
class plexapi.library.FilteringOperator(server, data, initpath=None, parent=None)
Bases: PlexObject
TAG(str) โ'Operator'key(str) โ The URL key for the operator.title(str) โ The title of the operator.
๐ฆ FilterChoice โ the one you'll actually see in ur results
plexapi.library.FilterChoice โ Represents a single FilterChoice object. these are the little darlings you get handed back when you use filters while searching for library items โ it's literally the object returned in the result set of listFilterChoices(). main character energy, truly ๐
class plexapi.library.FilterChoice(server, data, initpath=None, parent=None)
Bases: PlexObject
TAG(str) โ'Directory'fastKey(str) โ API URL path to quickly list all items with this filter choice. (/library/sections/<section>/all?genre=<key>)key(str) โ The id value of this filter choice.thumb(str) โ Thumbnail URL for the filter choice.title(str) โ The title of the filter choice.type(str) โ The filter type (genre, contentRating, etc).
and she has a method, bestie, one little method ๐ฅบ:
items()โ Returns a list of items for this filter choice.
๐ ManagedHub โ the recommendation girlie
plexapi.library.ManagedHub โ Represents a Managed Hub (recommendation) inside a library. ๐ this is the curated shelf vibe, the "here's what we think u should watch" of it all.
class plexapi.library.ManagedHub(server, data, initpath=None, parent=None)
Bases: PlexObject
TAG(str) โ'Hub'deletable(bool) โTrueif the Hub can be deleted (promoted collection).homeVisibility(str) โ Promoted home visibility (none,all,admin, orshared).identifier(str) โ Hub identifier for the managed hub.promotedToOwnHome(bool) โ Promoted to own home.promotedToRecommended(bool) โ Promoted to recommended.promotedToSharedHome(bool) โ Promoted to shared home.move(after=None)โ slides a managed hub to a whole new spot in the library's Managed Recommendations, like rearranging your playlists until it hits.- after (
obj) โ theManagedHubobject you want to drop this item after in the collection. - Raises
plexapi.exceptions.BadRequestโ throws this when you're trying to move a Hub that isn't a Managed Recommendation. rude but fair ๐
- after (
remove()โ yeets a managed hub out of the library's Managed Recommendations entirely.- Raises
plexapi.exceptions.BadRequestโ when you try to remove a Hub that isn't a Managed Recommendation, or when the Hub genuinely cannot be removed. no cap, it'll fight you ๐ซ
- Raises
updateVisibility(recommended=None, home=None, shared=None)โ glow-up time: flip the managed hub's visibility settings all at once.- Parameters:
- recommended (
bool) โTruemakes it visible on your Library Recommended page,Falsehides it. DefaultNone. - home (
bool) โTruemakes it visible on your Home page,Falsehides it. DefaultNone. - shared (
bool) โTruemakes it visible on your Friends' Home page,Falsehides it. DefaultNone.
- recommended (
- Example:
- Parameters:
managedHub.updateVisibility(recommended=True, home=True, shared=False).reload()
# or using chained methods
managedHub.promoteRecommended().promoteHome().demoteShared().reload()
promoteRecommended()โ puts the managed hub on your Library Recommended Page. main character energy โจdemoteRecommended()โ hides the managed hub from your Library Recommended Page. ghosting, but polite.promoteHome()โ shows the managed hub on your Home Page. ๐demoteHome()โ hides the manged hub from your Home Page. (yep, that typo is canon, we keep it fr fr ๐)promoteShared()โ shows the managed hub on your Friends' Home Page. sharing is caring ๐ซถdemoteShared()โ hides the managed hub from your Friends' Home Page.
๐๏ธ class plexapi.library.Folder(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a Folder inside a library. lowkey just a folder, but make it Plex.
Variables:
key(str) โ Url key for folder.title(str) โ Title of folder.
Methods:
subfolders()โ returns a list of availableFolderfor this folder. It keeps going down subfolders until amediaTypeis found, like digging through your downloads folder at 2am. ๐ณ๏ธallSubfolders()โ returns a list of all availableFolderfor this folder. Only returnsFolder. that's it, that's the whole vibe.
๐ค class plexapi.library.FirstCharacter(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a First Character element from a library. the alphabet, but make it metadata ๐
Variables:
key(str) โ Url key for character.size(str) โ Total amount of library items starting with this character.title(str) โ Character (#,!,A,B,C, ...).
๐ class plexapi.library.Path(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single directory Path. one (1) folder, no notes.
Variables:
TAG(str) โ'Path'home(bool) โTrueif the path is the home directorykey(str) โ API URL (/services/browse/<base64path>)network(bool) โTrueif path is a network locationpath(str) โ Full path to foldertitle(str) โ Folder name
Methods:
browse(includeFiles=True)โ alias forbrowse().walk()โ alias forwalk().
yes bestie, those aliases literally alias themselves in the docs. we don't question the source material, we just report it ๐
๐ class plexapi.library.File(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single File. one file. that's the post.
Variables:
TAG(str) โ'File'key(str) โ API URL (/services/browse/<base64path>)path(str) โ Full path to filetitle(str) โ File name
๐งฉ class plexapi.library.Common(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a Common element from a library. This object lists common fields between multiple objects โ like a group chat where everyone shares the same interests. ๐ซ
Variables:
TAG(str) โ'Common'collections(List<Collection>) โ List of collection objects.contentRating(str) โ Content rating of the items.countries(List<Country>) โ List of countries objects.directors(List<Director>) โ List of director objects.editionTitle(str) โ Edition title of the items.fields(List<Field>) โ List of field objects.genres(List<Genre>) โ List of genre objects.grandparentRatingKey(int) โ Grandparent rating key of the items.grandparentTitle(str) โ Grandparent title of the items.guid(str) โ Plex GUID of the items.guids(List<Guid>) โ List of guid objects.index(int) โ Index of the items.key(str) โ API URL (/library/metadata/<ratingkey>).labels(List<Label>) โ List of label objects.mixedFields(List<str>) โ List of mixed fields.moods(List<Mood>) โ List of mood objects.originallyAvailableAt(datetime) โ Datetime of the release date of the items.parentRatingKey(int) โ Parent rating key of the items.parentTitle(str) โ Parent title of the items.producers(List<Producer>) โ List of producer objects.ratingKey(int) โ Rating key of the items.ratings(List<Rating>) โ List of rating objects.roles(List<Role>) โ List of role objects.studio(str) โ Studio name of the items.styles(List<Style>) โ List of style objects.summary(str) โ Summary of the items.tagline(str) โ Tagline of the items.tags(List<Tag>) โ List of tag objects.title(str) โ Title of the items.titleSort(str) โ Title to use when sorting of the items.type(str) โ Type of the media (common).writers(List<Writer>) โ List of writer objects.year(int) โ Year of the items.
Properties & methods:
- property
commonTypeโ returns the media type of the common items. - property
ratingKeysโ returns a list of rating keys for the common items. items()โ returns a list of the common items.
๐ฌ MEDIA PLEXAPI.MEDIA
๐ผ class plexapi.media.Media(server, data, initpath=None, parent=None)
Bases: PlexObject
Container object for all MediaPart objects. It hands you the useful deets about the video or audio this media belongs to โ video framerate, resolution, all of it. the lore is rich, bestie ๐
Variables:
TAG(str) โ'Media'aspectRatio(float) โ The aspect ratio of the media (ex:2.35).audioChannels(int) โ The number of audio channels of the media (ex:6).audioCodec(str) โ The audio codec of the media (ex:ac3).audioProfile(str) โ The audio profile of the media (ex:dts).bitrate(int) โ The bitrate of the media (ex:1624).container(str) โ The container of the media (ex:avi).duration(int) โ The duration of the media in milliseconds (ex:6990483).height(int) โ The height of the media in pixels (ex:256).id(int) โ The unique ID for this media on the server.has64bitOffsets(bool) โTrueif video has 64 bit offsets.hasVoiceActivity(bool) โTrueif video has voice activity analyzed.optimizedForStreaming(bool) โTrueif video is optimized for streaming.parts(List<MediaPart>) โ List of media part objects.proxyType(int) โ Equals42for optimized versions.target(str) โ The media version target name.title(str) โ The title of the media.videoCodec(str) โ The video codec of the media (ex:ac3).videoFrameRate(str) โ The video frame rate of the media (ex:24p).videoProfile(str) โ The video profile of the media (ex:high).videoResolution(str) โ The video resolution of the media (ex:sd).width(int) โ The width of the video in pixels (ex:608).Photo_only_attributesโ the following attributes are only available for photos. pics only, babes ๐ธaperture(str): The aperture used to take the photo.exposure(str): The exposure used to take the photo.iso(int): The iso used to take the photo.lens(str): The lens used to take the photo.make(str): The make of the camera used to take the photo.model(str): The model of the camera used to take the photo.
Property:
- property
isOptimizedVersionโ returnsTrueif the media is a Plex optimized version.
๐๏ธ class plexapi.media.MediaPart(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single media part (often a single file) for the media this belongs to. like, the actual file behind the whole vibe.
Variables:
TAG(str) โ'Part'accessible(bool) โTrueif the file is accessible. Requires reloading the media withcheckFiles=True. Refer toreload().audioProfile(str) โ The audio profile of the file.
okay bestie we're still in the MediaPart variable list, buckle up, it's a long one ๐
container(str) โ the container type of the file (ex:avi).decision(str) โ literally unknown. nobody knows. it's giving mystery โจ.deepAnalysisVersion(int) โ the Plex deep analysis version for the file.duration(int) โ how long the file is, in milliseconds.exists(bool) โTrueif the file actually exists. โ ๏ธ heads up: you gotta reload the media withcheckFiles=Truefirst, checkreload()for that.file(str) โ the path to this file on disk (ex:/media/Movies/Cars (2006)/Cars (2006).mkv).has64bitOffsets(bool) โTrueif the file has 64 bit offsets.hasThumbnail(bool) โTrueif the file (track) has an embedded thumbnail. ๐id(int) โ the unique ID for this media part on the server.indexes(str, None) โsdif the file has generated preview (BIF) thumbnails.key(str) โ API URL (ex:/library/parts/46618/1389985872/file.mkv).optimizedForStreaming(bool) โTrueif the file is optimized for streaming ๐ฅ.packetLength(int) โ the packet length of the file.requiredBandwidths(str) โ the required bandwidths to stream the file.selected(bool) โTrueif this media part is selected ๐.size(int) โ the size of the file in bytes (ex:733884416).streams(List<MediaPartStream>) โ a list of stream objects.syncItemId(int) โ the unique ID for this media part if it's synced.syncState(str) โ the sync state for this media part.videoProfile(str) โ the video profile of the file.
property hasPreviewThumbnails
Returns True if the media part has generated preview (BIF) thumbnails. same energy as indexes but as a cute lil property ๐ซถ
videoStreams()
Returns a list of VideoStream objects in this MediaPart. iykyk.
audioStreams()
Returns a list of AudioStream objects in this MediaPart.
subtitleStreams()
Returns a list of SubtitleStream objects in this MediaPart.
lyricStreams()
Returns a list of LyricStream objects in this MediaPart. yes bestie, lyrics too ๐คโจ
setSelectedAudioStream(stream)
Set the selected AudioStream for this MediaPart.
Parameters
- stream (AudioStream) โ audio stream to set as selected.
setSelectedSubtitleStream(stream)
Set the selected SubtitleStream for this MediaPart.
Parameters
- stream (SubtitleStream) โ subtitle stream to set as selected.
resetSelectedSubtitleStream()
Set the selected subtitle of this MediaPart to 'None'. bye bye subs ๐ literally just turns them off.
### class plexapi.media.MediaPartStream
plexapi.media.MediaPartStream(server, data, initpath=None, parent=None)
Bases: PlexObject
Base class for media streams. these are the video, audio, subtitles, and lyrics ones โ the whole squad ๐ง
Variables
bitrate(int) โ the bitrate of the stream.codec(str) โ the codec of the stream (ex:srt,ac3,mpeg4).default(bool) โTrueif this is the default stream.displayTitle(str) โ the display title of the stream.extendedDisplayTitle(str) โ the extended display title of the stream.key(str) โ API URL (/library/streams/<id>)id(int) โ the unique ID for this stream on the server.index(int) โ the index of the stream.language(str) โ the language of the stream (ex:English,เนเธเธข). multilingual queen ๐languageCode(str) โ the ASCII language code of the stream (ex:eng,tha).languageTag(str) โ the two letter language tag of the stream (ex:en,fr).requiredBandwidths(str) โ the required bandwidths to stream the file.selected(bool) โTrueif this stream is selected.streamType(int) โ the stream type (1=VideoStream,2=AudioStream,3=SubtitleStream).title(str) โ the title of the stream.type(int) โ alias forstreamType. same thing, different font ๐
### class plexapi.media.VideoStream
plexapi.media.VideoStream(server, data, initpath=None, parent=None)
Bases: MediaPartStream
Represents a video stream within a MediaPart. the visual main character โจ
Variables
TAG(str) โ'Stream'STREAMTYPE(int) โ1anamorphic(str) โ if the video is anamorphic.bitDepth(int) โ the bit depth of the video stream (ex:8).cabac(int) โ the context-adaptive binary arithmetic coding.chromaLocation(str) โ the chroma location of the video stream.chromaSubsampling(str) โ the chroma subsampling of the video stream (ex:4:2:0).codecID(str) โ the codec ID (ex:XVID).codedHeight(int) โ the coded height of the video stream in pixels.codedWidth(int) โ the coded width of the video stream in pixels.colorPrimaries(str) โ the color primaries of the video stream.colorRange(str) โ the color range of the video stream.colorSpace(str) โ the color space of the video stream (ex:bt2020).colorTrc(str) โ the color trc of the video stream.DOVIBLCompatID(int) โ Dolby Vision base layer compatibility ID.DOVIBLPresent(bool) โTrueif Dolby Vision base layer is present.DOVIELPresent(bool) โTrueif Dolby Vision enhancement layer is present.DOVILevel(int) โ Dolby Vision level.DOVIPresent(bool) โTrueif Dolby Vision is present. fancy ๐DOVIProfile(int) โ Dolby Vision profile.DOVIRPUPresent(bool) โTrueif Dolby Vision reference processing unit is present.DOVIVersion(float) โ the Dolby Vision version.duration(int) โ the duration of video stream in milliseconds.frameRate(float) โ the frame rate of the video stream (ex:23.976).frameRateMode(str) โ the frame rate mode of the video stream.hasScalingMatrix(bool) โTrueif video stream has a scaling matrix.height(int) โ the height of the video stream in pixels (ex:1080).level(int) โ the codec encoding level of the video stream (ex:41).profile(str) โ the profile of the video stream (ex:asp).pixelAspectRatio(str) โ the pixel aspect ratio of the video stream.pixelFormat(str) โ the pixel format of the video stream.refFrames(int) โ the number of reference frames of the video stream.scanType(str) โ the scan type of the video stream (ex:progressive).streamIdentifier(int) โ the stream identifier of the video stream.width(int) โ the width of the video stream in pixels (ex:1920).
### class plexapi.media.AudioStream
plexapi.media.AudioStream(server, data, initpath=None, parent=None)
Bases: MediaPartStream
Represents a audio stream within a MediaPart. sound bestie ๐ง
Variables
TAG(str) โ'Stream'STREAMTYPE(int) โ2audioChannelLayout(str) โ the audio channel layout of the audio stream (ex:5.1(side)).bitDepth(int) โ the bit depth of the audio stream (ex:16).bitrateMode(str) โ the bitrate mode of the audio stream (ex:cbr).channels(int) โ the number of audio channels of the audio stream (ex:6).duration(int) โ the duration of audio stream in milliseconds.profile(str) โ the profile of the audio stream.samplingRate(int) โ the sampling rate of the audio stream (ex:xxx)streamIdentifier(int) โ the stream identifier of the audio stream.visualImpaired(bool) โTrueif this is a visually impaired (AD) audio stream.Track_only_attributesโ
The following attributes are only available for tracks. ๐ not all of them, just tracks.
albumGain(float): the gain for the album.albumPeak(float): the peak for the album.albumRange(float): the range for the album.endRamp(str): the end ramp for the track.gain(float): the gain for the track.loudness(float): the loudness for the track.lra(float): the lra for the track.peak(float): the peak for the track.startRamp(str): the start ramp for the track.
setSelected()
Sets this audio stream as the selected audio stream. it's an alias for setSelectedAudioStream(), so pick whichever one you vibe with ๐ซถ
levels(subSample=128)
Returns a list of Level objects for this AudioStream. โ ๏ธ only available for Tracks which have been analyzed for loudness โ no analysis, no levels, periodt.
Variables
- subSample (int) โ the number of loudness samples to return. default
128.
### class plexapi.media.SubtitleStream
plexapi.media.SubtitleStream(server, data, initpath=None, parent=None)
Bases: MediaPartStream
Represents a audio stream within a MediaPart.
Variables
(and we're picking the subtitle vibe check up right here in the next bit โ don't go anywhere bestie ๐)
TAG(str) โ'Stream'๐STREAMTYPE(int) โ3canAutoSync(bool) โTrueif this subtitle stream can be auto synced. like, it's allowed to just show up on its own โจcontainer(str) โ the container of the subtitle streamforced(bool) โTrueif this is a forced subtitle (iykyk, the "alien language only" ones ๐ธ)format(str) โ the format of the subtitle stream (ex:srt)headerCompression(str) โ the header compression of the subtitle streamhearingImpaired(bool) โTrueif this is a hearing impaired (SDH) subtitle ๐ซถperfectMatch(bool) โTrueif the on-demand subtitle is a perfect match. no notes, chef's kiss ๐providerTitle(str) โ the provider title where the on-demand subtitle is downloaded fromscore(int) โ the match score (download count) of the on-demand subtitlesourceKey(str) โ the source key of the on-demand subtitletransient(str) โ Unknown ๐ (yes bestie, the docs literally say Unknown, we don't make the rules)userID(int) โ the user id of the user that downloaded the on-demand subtitle
setSelected()
Sets this subtitle stream as the selected subtitle stream. It's an alias for setSelectedSubtitleStream() โ same energy, two names, slay ๐
class plexapi.media.LyricStream(server, data, initpath=None, parent=None)
Bases: MediaPartStream
Represents a lyric stream within a MediaPart. Karaoke night is so on ๐คโจ
Variables
TAG(str) โ'Stream'STREAMTYPE(int) โ4format(str) โ the format of the lyric stream (ex:lrc)minLines(int) โ the minimum number of lines in the (timed) lyric streamprovider(str) โ the provider of the lyric stream (ex:com.plexapp.agents.lyricfind)timed(bool) โTrueif the lyrics are timed to the track ๐ถ
class plexapi.media.Session(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a current session. it's giving "who's watching right now" main character energy ๐
Variables
TAG(str) โ'Session'id(str) โ the unique identifier for the sessionbandwidth(int) โ the Plex streaming brain reserved bandwidth for the session ๐งlocation(str) โ the location of the session (lan,wan, orcellular)
class plexapi.media.TranscodeSession(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a current transcode session. buckle up bestie, this one has a lot of variables ๐ฅ
Variables
TAG(str) โ'TranscodeSession'audioChannels(int) โ the number of audio channels of the transcoded mediaaudioCodec(str) โ the audio codec of the transcoded mediaaudioDecision(str) โ the transcode decision for the audio streamcomplete(bool) โTrueif the transcode is completecontainer(str) โ the container of the transcoded mediacontext(str) โ the context for the transcode sessionduration(int) โ the duration of the transcoded media in millisecondsheight(int) โ the height of the transcoded media in pixelskey(str) โ API URL (ex:/transcode/sessions/<id>)maxOffsetAvailable(float) โ Unknown ๐minOffsetAvailable(float) โ Unknown ๐progress(float) โ the progress percentage of the transcodeprotocol(str) โ the protocol of the transcoderemaining(int) โ Unknown ๐size(int) โ the size of the transcoded media in bytessourceAudioCodec(str) โ the audio codec of the source mediasourceVideoCodec(str) โ the video codec of the source mediaspeed(float) โ the speed of the transcodesubtitleDecision(str) โ the transcode decision for the subtitle streamthrottled(bool) โTrueif the transcode is throttledtimestamp(int) โ the epoch timestamp when the transcode startedtranscodeHwDecoding(str) โ the hardware transcoding decoder enginetranscodeHwDecodingTitle(str) โ the title of the hardware transcoding decoder enginetranscodeHwEncoding(str) โ the hardware transcoding encoder enginetranscodeHwEncodingTitle(str) โ the title of the hardware transcoding encoder enginetranscodeHwFullPipeline(str) โTrueif hardware decoding and encoding is being used for the transcodetranscodeHwRequested(str) โTrueif hardware transcoding was requested for the transcodevideoCodec(str) โ the video codec of the transcoded mediavideoDecision(str) โ the transcode decision for the video streamwidth(str) โ the width of the transcoded media in pixels
class plexapi.media.TranscodeJob(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents an Optimizing job. TrancodeJobs are the process for optimizing conversions. Active or paused optimization items. Usually one item as a time ๐ ๏ธ
class plexapi.media.Optimized(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a Optimized item. Optimized items are optimized and queued conversions items ๐
items()
Returns a list of all Video objects in this optimized item.
remove()
Remove an Optimized item
rename(title)
Rename an Optimized item
reprocess(ratingKey)
Reprocess a removed Conversion item that is still a listed Optimize item โป๏ธ
class plexapi.media.Conversion(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a Conversion item. Conversions are items queued for optimization or being actively optimized ๐
remove()
Remove Conversion from queue
move(after)
Move Conversion items position in queue after (int): Place item after specified playQueueItemID. '-1' is the active conversion.
Example:
Move 5th conversion Item to active conversion
conversions[4].move('-1')
Move 4th conversion Item to 3rd in conversion
queue
conversions[3].move(conversions[1].playQueueItemID)
class plexapi.media.MediaTag(server, data, initpath=None, parent=None)
Bases: PlexObject
Base class for media tags used for filtering and searching your library items or navigating the metadata of media items in your library. Tags are the construct used for things such as Country, Director, Genre, etc. it's the whole "how do I even find this" system bestie ๐ท๏ธโจ
Variables
filter(str) โ the library filter for the tagid(int) โ Tag ID (this seems meaningless except to use it as a unique id ๐)key(str) โ API URL (/library/section/<librarySectionID>/all?<filter>)role(str) โ the name of the character role for Role onlytag(str) โ name of the tag. This will be Animation, SciFi etc for Genres. The name of person for Directors and Roles (ex: Animation, Stephen Graham, etc)tagKey(str) โ Plex GUID for the actor/actress for Role onlythumb(str) โ URL to thumbnail image for Role only
items()
Return the list of items within this tag.
class plexapi.media.Collection(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Collection media tag.
Variables
TAG(str) โ'Collection'FILTER(str) โ'collection'
collection()
Return the Collection object for this collection tag.
class plexapi.media.Country(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Country media tag. ๐
Variables
TAG(str) โ'Country'FILTER(str) โ'country'
class plexapi.media.Director(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Director media tag. ๐ฌ
Variables
TAG(str) โ'Director'FILTER(str) โ'director'
class plexapi.media.Format(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Format media tag.
Variables
TAG(str) โ'Format'FILTER(str) โ'format'
class plexapi.media.Genre(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Genre media tag. ๐
Variables
TAG(str) โ'Genre'FILTER(str) โ'genre'
class plexapi.media.Label(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Label media tag.
Variables
TAG(str) โ'Label'FILTER(str) โ'label'
class plexapi.media.Mood(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Mood media tag. the vibe check, literally ๐ธ
Variables
TAG(str) โ'Mood'FILTER(str) โ'mood'
class plexapi.media.Producer(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Producer media tag.
Variables
TAG(str) โ'Producer'FILTER(str) โ'producer'
๐ฆ plexapi.media.Role
class plexapi.media.Role(server, data, initpath=None, parent=None)
Bases: MediaTag
okay so this one represents a single Role media tag โ like an actor or actress tag, yk? ๐
Variables (the whole vibe check):
TAG(str) โ'Role'FILTER(str) โ'role'
๐ธ plexapi.media.Similar
class plexapi.media.Similar(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Similar media tag. bestie it's the "you might also like" energy โจ
Variables:
TAG(str) โ'Similar'FILTER(str) โ'similar'
๐ plexapi.media.Style
class plexapi.media.Style(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Style media tag. yes it's giving aesthetic tags ๐
Variables:
TAG(str) โ'Style'FILTER(str) โ'style'
๐ง plexapi.media.Subformat
class plexapi.media.Subformat(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Subformat media tag.
Variables:
TAG(str) โ'Subformat'FILTER(str) โ'subformat'
๐ plexapi.media.Tag
class plexapi.media.Tag(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Tag media tag. the most main character of tags tbh ๐
Variables:
TAG(str) โ'Tag'FILTER(str) โ'tag'
โจ plexapi.media.Writer
class plexapi.media.Writer(server, data, initpath=None, parent=None)
Bases: MediaTag
Represents a single Writer media tag โ the person who wrote the thing, no cap โ๏ธ
Variables:
TAG(str) โ'Writer'FILTER(str) โ'writer'
๐ฅ plexapi.media.Guid
class plexapi.media.Guid(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single Guid media tag โ the lil ID card for external metadata sources ๐ชช
Variables:
TAG(str) โ'Guid'id(id) โ The guid for external metadata sources (e.g. IMDB, TMDB, TVDB, MBID).
๐ plexapi.media.Image
class plexapi.media.Image(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single Image media tag โ pics pics pics ๐ผ๏ธ
Variables:
TAG(str) โ'Image'alt(str) โ The alt text for the image.type(str) โ The type of image (e.g. coverPoster, background, snapshot).url(str) โ The API URL (/library/metadata/<ratingKey>/thumb/<thumbid>).
โญ plexapi.media.Rating
class plexapi.media.Rating(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single Rating media tag. the numbers that decide if a movie ate or flopped ๐
Variables:
TAG(str) โ'Rating'image(str) โ The uri for the rating image (e.g.imdb://image.rating,rottentomatoes://image.rating.ripe,rottentomatoes://image.rating.upright,themoviedb://image.rating).type(str) โ The type of rating (e.g. audience or critic).value(float) โ The rating value.
๐ plexapi.media.Review
class plexapi.media.Review(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single Review for a Movie. somebody had opinions and honestly? same ๐ซถ
Variables:
TAG(str) โ'Review'filter(str) โ The library filter for the review.id(int) โ The ID of the review.image(str) โ The image uri for the review.link(str) โ The url to the online review.source(str) โ The source of the review.tag(str) โ The name of the reviewer.text(str) โ The text of the review.
๐จ plexapi.media.UltraBlurColors
class plexapi.media.UltraBlurColors(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single UltraBlurColors media tag โ the blurry color palette, iconic for backgrounds fr fr ๐
Variables:
TAG(str) โ'UltraBlurColors'bottomLeft(str) โ The bottom left hex color.bottomRight(str) โ The bottom right hex color.topLeft(str) โ The top left hex color.topRight(str) โ The top right hex color.
๐ plexapi.media.BaseResource
class plexapi.media.BaseResource(server, data, initpath=None, parent=None)
Bases: PlexObject
The base class for all Art, Poster, and Theme objects โ the mother of the aesthetic objects ๐
Variables:
TAG(str) โ'Photo'or'Track'key(str) โ API URL (/library/metadata/<ratingkey>).provider(str) โ The source of the resource.'local'for local files (e.g.theme.mp3),Noneif uploaded or agent-/plugin-supplied.ratingKey(str) โ Unique key identifying the resource.selected(bool) โTrueif the resource is currently selected.thumb(str) โ The URL to retrieve the resource thumbnail.
property resourceFilepath โ Returns the file path to the resource in the Plex Media Server data directory.
โ ๏ธ Note: Returns the URL if the resource is not stored locally. so don't come for her if it's not a file path, bestie ๐ญ
๐ผ๏ธ plexapi.media.Art
class plexapi.media.Art(server, data, initpath=None, parent=None)
Bases: BaseResource
Represents a single Art object.
๐ฆ plexapi.media.Logo
class plexapi.media.Logo(server, data, initpath=None, parent=None)
Bases: BaseResource
Represents a single Logo object.
๐ธ plexapi.media.Poster
class plexapi.media.Poster(server, data, initpath=None, parent=None)
Bases: BaseResource
Represents a single Poster object โ the lil cover pic, lowkey the most important part of the whole vibe ๐
โจ plexapi.media.SquareArt
class plexapi.media.SquareArt(server, data, initpath=None, parent=None)
Bases: BaseResource
Represents a single Square Art object. square! art! slay geometry ๐ง
๐ต plexapi.media.Theme
class plexapi.media.Theme(server, data, initpath=None, parent=None)
Bases: BaseResource
Represents a single Theme object โ the background music that lives in your head rent free ๐ถ
๐ plexapi.media.Chapter
class plexapi.media.Chapter(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single Chapter media tag.
Variables:
TAG(str) โ'Chapter'end(int) โ The end time of the chapter in milliseconds.filter(str) โ The library filter for the chapter.id(int) โ The ID of the chapter.index(int) โ The index of the chapter.tag(str) โ The name of the chapter.title(str) โ The title of the chapter.thumb(str) โ The URL to retrieve the chapter thumbnail.start(int) โ The start time of the chapter in milliseconds.
โฑ๏ธ plexapi.media.Marker
class plexapi.media.Marker(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single Marker media tag โ yk, the skip-intro / credits markers that save your life ๐
Variables:
TAG(str) โ'Marker'end(int) โ The end time of the marker in milliseconds.final(bool) โTrueif the marker is the final credits marker.id(int) โ The ID of the marker.type(str) โ The type of marker.start(int) โ The start time of the marker in milliseconds.version(int) โ The Plex marker version.
property first โ Returns True if the marker in the first credits marker.
๐ plexapi.media.Field
class plexapi.media.Field(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single Field.
Variables:
TAG(str) โ'Field'locked(bool) โTrueif the field is locked.name(str) โ The name of the field.
๐ plexapi.media.SearchResult
class plexapi.media.SearchResult(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single SearchResult. the "found it" moment โจ
Variables:
TAG(str) โ'SearchResult'
๐ค plexapi.media.Agent
class plexapi.media.Agent(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single Agent โ not a spy, a metadata agent bestie ๐
Variables:
TAG(str) โ'Agent'
๐งฌ plexapi.media.AgentMediaType
class plexapi.media.AgentMediaType(server, data, initpath=None, parent=None)
Bases: Agent
Represents a single Agent MediaType.
Variables:
TAG(str) โ'MediaType'
๐บ plexapi.media.Availability
class plexapi.media.Availability(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single online streaming service Availability โ aka "where can I watch this and how much is it gonna cost me" ๐ญ
Variables:
TAG(str) โ'Availability'country(str) โ The streaming service country.offerType(str) โ Subscription, buy, or rent from the streaming service.platform(str) โ The platform slug for the streaming service.platformColorThumb(str) โ Thumbnail icon for the streaming service.platformInfo(str) โ The streaming service platform info.platformUrl(str) โ The URL to the media on the streaming service.price(float) โ The price to buy or rent from the streaming service.priceDescription(str) โ The display price to buy or rent from the streaming service.quality(str) โ The video quality on the streaming service.title(str) โ The title of the streaming service.url(str) โ The Plex availability URL.
๐ plexapi.media.Level
class plexapi.media.Level(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single loudness Level sample for an AudioStream.
Variables:
loudness(float) โ Loudness level value
๐งธ plexapi.media.CommonSenseMedia
class plexapi.media.CommonSenseMedia(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single CommonSenseMedia media tag.
โ ๏ธ Note: This object is only loaded with partial data from a Plex Media Server. Call reload() to load the full data from Plex Discover (Plex Pass required). don't forget the reload bestie, or you'll be staring at half the info wondering what went wrong ๐
Variables:
TAG(str) โ'CommonSenseMedia'ageRatings(List<AgeRating>) โ List of AgeRating objects.anyGood(str) โ A brief description of the media's quality.id(int) โ The ID of the CommonSenseMedia tag.key(str) โ The unique key for the CommonSenseMedia tag.oneLiner(str) โ A brief description of the CommonSenseMedia tag.parentalAdvisoryTopics(List<ParentalAdvisoryTopic>) โ the list ofParentalAdvisoryTopicobjects ๐parentsNeedToKnow(str) โ a short lil description of what parents should know about the media, yep ๐talkingPoints(List<TalkingPoint>) โ the list ofTalkingPointobjects ๐ฌ
Example
from plexapi.server import PlexServer
plex = PlexServer('http://localhost:32400', token='xxxxxxxxxxxxxxxxxxxx')
# Retrieve the Common Sense Media info for a movie
movie = plex.library.section('Movies').get('Cars')
commonSenseMedia = movie.commonSenseMedia
ageRating = commonSenseMedia.ageRatings[0].age
# Load the Common Sense Media info from Plex Discover (Plex Pass required)
commonSenseMedia.reload()
parentalAdvisoryTopics = commonSenseMedia.parentalAdvisoryTopics
talkingPoints = commonSenseMedia.talkingPoints
class plexapi.media.AgeRating(server, data, initpath=None, parent=None)
Bases: PlexObject ๐ซถ
Represents a single AgeRating for a Common Sense Media tag โ it's giving one little age badge, that's the whole job.
Variables
TAG(str) โ'AgeRating'๐ท๏ธage(float) โ the age rating (e.g.13,17) ๐ขageGroup(str) โ the age group for the rating (e.g. Little Kids, Teens, etc.) ๐ถ๐งrating(float) โ the star rating (out of 5) โญratingCount(int) โ how many ratings contributed to that star rating ๐ณ๏ธtype(str) โ the type of rating (official,adult,child) ๐
class plexapi.media.TalkingPoint(server, data, initpath=None, parent=None)
Bases: PlexObject ๐ซถ
Represents a single TalkingPoint for a Common Sense Media tag. One talking point, one vibe, periodt.
Variables
TAG(str) โ'TalkingPoint'๐ท๏ธtag(str) โ the description of the talking point ๐ฌ
class plexapi.media.ParentalAdvisoryTopic(server, data, initpath=None, parent=None)
Bases: PlexObject ๐ซถ
Represents a single ParentalAdvisoryTopic for a Common Sense Media tag โ literally the "heads up bestie" object.
Variables
TAG(str) โ'ParentalAdvisoryTopic'๐ท๏ธid(str) โ the ID of the topic (e.g.violence,language, etc.) ๐label(str) โ the label for the topic (e.g.Violence & Scariness,Language, etc.) ๐ท๏ธpositive(bool) โ whether the topic is considered positive โจrating(float) โ the rating of the topic (out of 5) โญtag(str) โ the description of the parental advisory topic ๐
๐ฆ MIXINS PLEXAPI.MIXINS ๐ฆ
PlexAPI Mixins Module โ okay so this module contains mixins for Plex objects. Mixins are the little add-on superpowers, iykyk ๐
class plexapi.mixins.AdvancedSettingsMixin
Bases: object
Mixin for Plex objects that can have advanced settings โ๏ธ
preferences()โ returns a list ofPreferencesobjects.preference(pref)โ returns aPreferencesobject for the specified pref.- Parameters
- pref (str) โ the id of the preference to return.
- Parameters
editAdvanced(**kwargs)โ edit a Plex object's advanced settings.defaultAdvanced()โ edit all of a Plex object's advanced settings to default.
class plexapi.mixins.AddedAtMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have an added at date ๐๏ธ
editAddedAt(addedAt, locked=True)โ edit the added at date.- Parameters
- addedAt (int or str or datetime) โ the new value as a unix timestamp (int),
"YYYY-MM-DD"(str), ordatetimeobject. - locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- addedAt (int or str or datetime) โ the new value as a unix timestamp (int),
- Parameters
class plexapi.mixins.AudienceRatingMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have an audience rating ๐
editAudienceRating(audienceRating, locked=True)โ edit the audience rating.- Parameters
- audienceRating (float) โ the new value.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- Parameters
class plexapi.mixins.CollectionMixin
Bases: EditTagsMixin
Mixin for Plex objects that can have collections ๐๏ธ
addCollection(collections, locked=True)โ add a collection tag(s).- Parameters
- collections (List<str> or List<MediaTag>) โ list of tags.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- Parameters
removeCollection(collections, locked=True)โ remove a collection tag(s).- Parameters
- collections (List<str> or List<MediaTag>) โ list of tags.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- Parameters
class plexapi.mixins.ContentRatingMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a content rating ๐
editContentRating(contentRating, locked=True)โ edit the content rating.- Parameters
- contentRating (str) โ the new value.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- Parameters
class plexapi.mixins.CountryMixin
Bases: EditTagsMixin
Mixin for Plex objects that can have countries ๐
addCountry(countries, locked=True)โ add a country tag(s).- Parameters
- countries (List<str> or List<MediaTag>) โ list of tags.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- Parameters
removeCountry(countries, locked=True)โ remove a country tag(s).- Parameters
- countries (List<str> or List<MediaTag>) โ list of tags.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- Parameters
class plexapi.mixins.CriticRatingMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a critic rating ๐ฟ
editCriticRating(criticRating, locked=True)โ edit the critic rating.- Parameters
- criticRating (float) โ the new value.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- Parameters
class plexapi.mixins.DirectorMixin
Bases: EditTagsMixin
Mixin for Plex objects that can have directors ๐ฌ
addDirector(directors, locked=True)โ add a director tag(s).- Parameters
- directors (List<str> or List<MediaTag>) โ list of tags.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- Parameters
removeDirector(directors, locked=True)โ remove a director tag(s).- Parameters
- directors (List<str> or List<MediaTag>) โ list of tags.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- Parameters
class plexapi.mixins.EditionTitleMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have an edition title ๐
editEditionTitle(editionTitle, locked=True)โ edit the edition title.
๐๏ธ heads up bestie: Plex Pass is required to edit this field.
- Parameters
- editionTitle (str) โ the new value.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
class plexapi.mixins.EditFieldMixin
Bases: object
Mixin for editing Plex object fields โ๏ธ
editField(field, value, locked=True, **kwargs)โ edit the field of a Plex object. All field editing methods can be chained together, fr fr. Also seebatchEdits()for batch editing fields.- Parameters
- field (str) โ the name of the field to edit.
- value (str) โ the value to edit the field to.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- Parameters
Example
# Chaining multiple field edits with reloading
Movie.editTitle('A New Title').editSummary('A new summary').editTagline('A new tagline').reload()
class plexapi.mixins.EditTagsMixin
Bases: object
Mixin for editing Plex object tags ๐ท๏ธ
editTags(tag, items, locked=True, remove=False, **kwargs)โ edit the tags of a Plex object. All tag editing methods can be chained together โจ. Also seebatchEdits()for batch editing tags.- Parameters
- tag (str) โ name of the tag to edit.
- items (List<str> or List<MediaTag>) โ list of tags to add or remove.
- locked (bool) โ
True(default) to lock the tags,Falseto unlock the tags ๐ - remove (bool) โ
Trueto remove the tags in items.
- Parameters
Example
# Chaining multiple tag edits with reloading
Show.addCollection('New Collection').removeGenre('Action').addLabel('Favorite').reload()
class plexapi.mixins.GenreMixin
Bases: EditTagsMixin
Mixin for Plex objects that can have genres ๐ญ
addGenre(genres, locked=True)โ add a genre tag(s).- Parameters
- genres (List<str> or List<MediaTag>) โ list of tags.
- locked (bool) โ
True(default) to lock the field,Falseto unlock the field ๐
- Parameters
removeGenre(genres, locked=True)โ takes a genre tag (or a bunch) off the thing ๐
Parameters
genres(List<str>orList<MediaTag>) โ the list of tags bestie, hand 'em over.locked(bool) โTrue(default) locks the field,Falseunlocks it. locked = "don't touch my edits", unlocked = "free real estate".
๐ class plexapi.mixins.LabelMixin
Bases: EditTagsMixin
Mixin for Plex objects that can have labels ๐ท๏ธ like, the object literally has a label field and this is how you feed it.
addLabel(labels, locked=True)โ adds a label tag (or several) โจ
Parameters
labels(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
removeLabel(labels, locked=True)โ yeets a label tag (or several) ๐ซถ
Parameters
labels(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ฆ class plexapi.mixins.MoodMixin
Bases: EditTagsMixin
Mixin for Plex objects that can have moods ๐ the vibe field, basically. Very main character.
addMood(moods, locked=True)โ adds a mood tag (or a whole moodboard of 'em) ๐
Parameters
moods(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
removeMood(moods, locked=True)โ removes a mood tag (or several), vibe check complete ๐
Parameters
moods(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ธ class plexapi.mixins.OriginallyAvailableMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have an originally available date ๐ the "it dropped on this day" field.
editOriginallyAvailable(originallyAvailable, locked=True)โ edits the originally available date โจ
Parameters
originallyAvailable(strordatetime) โ the new value,"YYYY-MM-DD"(str) or adatetimeobject. Note the quote marks in the original spec are<red>unbalanced โ it says"YYYY-MM-DD (str) or datetime objectโ so yeah, that's how it is, don't come for me, I'm just the messenger ๐locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ง class plexapi.mixins.OriginalTitleMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have an original title ๐ like the title in its home language, before localization did its thing.
editOriginalTitle(originalTitle, locked=True)โ edits the original title ๐
Parameters
originalTitle(str) โ the new value.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ธ class plexapi.mixins.PhotoCapturedTimeMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a captured time โฐ the "when was this pic actually taken" field, for all my photo-library girlies.
editCapturedTime(capturedTime, locked=True)โ edits the photo captured time ๐ฐ๏ธ
Parameters
capturedTime(strordatetime) โ the new value,"YYYY-MM-DD hh:mm:ss"(str) or adatetimeobject. Yes, with the time this time โ hours, minutes AND seconds, she's thorough ๐locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ class plexapi.mixins.ProducerMixin
Bases: EditTagsMixin
Mixin for Plex objects that can have producers ๐ฌ the money people, the ones who make it happen.
addProducer(producers, locked=True)โ adds a producer tag (or several) ๐ฅ
Parameters
producers(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
removeProducer(producers, locked=True)โ removes a producer tag (or several) ๐ญ
Parameters
producers(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ง class plexapi.mixins.SimilarArtistMixin
Bases: EditTagsMixin
Mixin for Plex objects that can have similar artists ๐ซถ aka the "if you like this, you'll like that" crew.
addSimilarArtist(artists, locked=True)โ adds a similar artist tag (or several) โญ
Parameters
artists(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
removeSimilarArtist(artists, locked=True)โ removes a similar artist tag (or several) ๐
Parameters
artists(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ค class plexapi.mixins.SortTitleMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a sort title ๐ the sneaky field that decides where it actually lands alphabetically, iykyk.
editSortTitle(sortTitle, locked=True)โ edits the sort title ๐
Parameters
sortTitle(str) โ the new value.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ข class plexapi.mixins.StudioMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a studio ๐ฅ the big-name house behind it.
editStudio(studio, locked=True)โ edits the studio ๐ฌ
Parameters
studio(str) โ the new value.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ class plexapi.mixins.StyleMixin
Bases: EditTagsMixin
Mixin for Plex objects that can have styles โจ the aesthetic tags, the ~vibes~ of it all.
addStyle(styles, locked=True)โ adds a style tag (or several) ๐
Parameters
styles(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
removeStyle(styles, locked=True)โ removes a style tag (or several) ๐ฆ
Parameters
styles(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ class plexapi.mixins.SummaryMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a summary ๐ the little blurb, the plot synopsis, the "what's this about" text.
editSummary(summary, locked=True)โ edits the summary โ๏ธ
Parameters
summary(str) โ the new value.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ฌ class plexapi.mixins.TaglineMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a tagline ๐ฏ that one dramatic line on the poster, you know the one.
editTagline(tagline, locked=True)โ edits the tagline ๐
Parameters
tagline(str) โ the new value.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ท๏ธ class plexapi.mixins.TagMixin
Bases: EditTagsMixin
Mixin for Plex objects that can have tags ๐ the general-purpose tag field, for when the tag is just... a tag.
addTag(tags, locked=True)โ adds a tag (or several) ๐
Parameters
tags(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
removeTag(tags, locked=True)โ removes a tag (or several) ๐
Parameters
tags(List<str>orList<MediaTag>) โ the list of tags.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ class plexapi.mixins.TitleMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a title ๐ the name, the headline, the whole identity.
editTitle(title, locked=True)โ edits the title โจ
Parameters
title(str) โ the new value.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ค class plexapi.mixins.TrackArtistMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a track artist ๐ต for when the artist on a specific track isn't the album artist (feature credits, collabs, the whole drama).
editTrackArtist(trackArtist, locked=True)โ edits the track artist ๐ถ
Parameters
trackArtist(str) โ the new value.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ฟ class plexapi.mixins.TrackDiscNumberMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a track disc number ๐ disc one, disc two, the deluxe edition situation.
editDiscNumber(discNumber, locked=True)โ edits the track disc number ๐ฝ
Parameters
discNumber(int) โ the new value.locked(bool) โTrue(default) locks the field,Falseunlocks it.
๐ข class plexapi.mixins.TrackNumberMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a track number ๐ผ track 1, track 2, the order she was always meant to be in.
editTrackNumber(trackNumber, locked=True)โ edits the track number ๐ต
Parameters
trackNumber(int) โ the new value.locked(bool) โTrue(default) locks the field,Falseunlocks it.
โญ class plexapi.mixins.UserRatingMixin
Bases: EditFieldMixin
Mixin for Plex objects that can have a user rating ๐ฏ your personal score, not the critic score, your truth.
editUserRating(userRating, locked=True)โ edits the user rating ๐
Parameters
userRating(float) โ the new value. Yeah,floatโ decimals allowed, she's precise ๐locked(bool) โTrue(default) locks the field,Falseunlocks it.
โ๏ธ class plexapi.mixins.WriterMixin
Bases: EditTagsMixin
Mixin for Plex objects that can have writers. โ๏ธ Like, the whole point of this one is tagging who wrote the thing, and you can lock it so Plex stops "helpfully" overwriting your choices.
addWriter(writers, locked=True)โ adds a writer tag (or a whole bunch). Parameters:- writers (
List<str>orList<MediaTag>) โ the list of tags, bestie. - locked (
bool) โTrue(the default) locks the field,Falseunlocks it. ๐
- writers (
removeWriter(writers, locked=True)โ yeets a writer tag (or several). Same parameters:- writers (
List<str>orList<MediaTag>) โ the list of tags. - locked (
bool) โTrue(default) locks the field,Falseunlocks the field.
- writers (
โจ class plexapi.mixins.ExtrasMixin โจ
Bases: object
Mixin for Plex objects that can have extras (trailers, behind-the-scenes, all that bonus content ๐ฌ).
extras()โ returns a list ofExtraobjects. That's it, that's the whole vibe.
๐ซ class plexapi.mixins.HubsMixin ๐ซ
Bases: object
Mixin for Plex objects that can have related hubs.
hubs()โ returns a list ofHubobjects.
๐ class plexapi.mixins.PlayedUnplayedMixin ๐
Bases: object
Mixin for Plex objects that can be marked played and unplayed. The "I definitely watched this already" mixin, iconic.
property isPlayedโ returnsTrueif this video is played.markPlayed()โ marks the Plex object as played. โmarkUnplayed()โ marks the Plex object as unplayed. ๐property isWatchedโ alias toself.isPlayed.markWatched()โ alias tomarkPlayed().markUnwatched()โ alias tomarkUnplayed().
โญ class plexapi.mixins.RatingMixin โญ
Bases: object
Mixin for Plex objects that can have user star ratings. Star ratings, we love her.
rate(rating=None)โ rates the Plex object. Heads up: Plex ratings are displayed out of 5 stars (so a rating of7.0=3.5stars, math is math ๐). Parameters:- rating (
float, optional) โ rating from0to10. Leave it out to reset the rating. - Raises
BadRequestโ if the rating is invalid. So, like, don't tryrating=9000.
- rating (
๐ผ๏ธ class plexapi.mixins.ArtLockMixin ๐ผ๏ธ
Bases: object
Mixin for Plex objects that can have a locked background artwork.
lockArt()โ locks the background artwork for a Plex object. ๐unlockArt()โ unlocks the background artwork for a Plex object. ๐
๐จ class plexapi.mixins.ArtMixin ๐จ
Bases: ArtUrlMixin, ArtLockMixin
Mixin for Plex objects that can have background artwork โ the big fanart energy.
arts()โ returns a list of availableArtobjects.uploadArt(url=None, filepath=None)โ uploads a background artwork from a url or filepath. Parameters:- url (
str) โ the full URL to the image to upload. - filepath (
str) โ the full file path to the image to upload or file-like object.
- url (
setArt(art)โ sets the background artwork for a Plex object. Parameters:- art (
Art) โ the art object to select.
- art (
deleteArt()โ deletes the art from a Plex object. Gone, girl. ๐
๐ฆ class plexapi.mixins.ArtUrlMixin ๐ฆ
Bases: object
Mixin for Plex objects that can have a background artwork url.
property artUrlโ returns the art url for the Plex object.
๐ class plexapi.mixins.LogoLockMixin ๐
Bases: object
Mixin for Plex objects that can have a locked logo.
lockLogo()โ locks the logo for a Plex object.unlockLogo()โ unlocks the logo for a Plex object.
๐ class plexapi.mixins.LogoMixin ๐
Bases: LogoUrlMixin, LogoLockMixin
Mixin for Plex objects that can have logos.
logos()โ returns a list of availableLogoobjects.uploadLogo(url=None, filepath=None)โ uploads a logo from a url or filepath. Parameters:- url (
str) โ the full URL to the image to upload. - filepath (
str) โ the full file path to the image to upload or file-like object.
- url (
setLogo(logo)โ sets the logo for a Plex object. Parameters:- logo (
Logo) โ the logo object to select.
- logo (
deleteLogo()โ deletes the logo from a Plex object.
๐ class plexapi.mixins.LogoUrlMixin ๐
Bases: object
Mixin for Plex objects that can have a logo url.
property logoโ returns the API path to the logo image.property logoUrlโ returns the logo url for the Plex object.
๐ class plexapi.mixins.PosterLockMixin ๐
Bases: object
Mixin for Plex objects that can have a locked poster.
lockPoster()โ locks the poster for a Plex object.unlockPoster()โ unlocks the poster for a Plex object.
๐ class plexapi.mixins.PosterMixin ๐
Bases: PosterUrlMixin, PosterLockMixin
Mixin for Plex objects that can have posters. Main character of cover art, fr.
posters()โ returns a list of availablePosterobjects.uploadPoster(url=None, filepath=None)โ uploads a poster from a url or filepath. Parameters:- url (
str) โ the full URL to the image to upload. - filepath (
str) โ the full file path to the image to upload or file-like object.
- url (
setPoster(poster)โ sets the poster for a Plex object. Parameters:- poster (
Poster) โ the poster object to select.
- poster (
deletePoster()โ deletes the poster from a Plex object.
๐ class plexapi.mixins.PosterUrlMixin ๐
Bases: object
Mixin for Plex objects that can have a poster url.
property thumbUrlโ returns the thumb url for the Plex object.property posterUrlโ alias toself.thumbUrl.
๐ง class plexapi.mixins.SquareArtLockMixin ๐ง
Bases: object
Mixin for Plex objects that can have a locked square art.
lockSquareArt()โ locks the square art for a Plex object.unlockSquareArt()โ unlocks the square art for a Plex object.
๐ class plexapi.mixins.SquareArtMixin ๐
Bases: SquareArtUrlMixin, SquareArtLockMixin
Mixin for Plex objects that can have square art.
squareArts()โ returns a list of availableSquareArtobjects.uploadSquareArt(url=None, filepath=None)โ uploads a square art from a url or filepath. Parameters:- url (
str) โ the full URL to the image to upload. - filepath (
str) โ the full file path to the image to upload or file-like object.
- url (
setSquareArt(squareArt)โ sets the square art for a Plex object. Parameters:- squareArt (
SquareArt) โ the square art object to select.
- squareArt (
deleteSquareArt()โ deletes the square art from a Plex object.
โฌ class plexapi.mixins.SquareArtUrlMixin โฌ
Bases: object
Mixin for Plex objects that can have a square art url.
property squareArtโ returns the API path to the square art image.property squareArtUrlโ returns the square art url for the Plex object.
๐ต class plexapi.mixins.ThemeLockMixin ๐ต
Bases: object
Mixin for Plex objects that can have a locked theme.
lockTheme()โ locks the theme for a Plex object.unlockTheme()โ unlocks the theme for a Plex object.
๐ถ class plexapi.mixins.ThemeMixin ๐ถ
Bases: ThemeUrlMixin, ThemeLockMixin
Mixin for Plex objects that can have themes. The little jingle that plays while you're browsing, iykyk.
themes()โ returns a list of availableThemeobjects.uploadTheme(url=None, filepath=None, timeout=None)โ uploads a theme from url or filepath. Parameters:- url (
str) โ the full URL to the theme to upload. - filepath (
str) โ the full file path to the theme to upload or file-like object. - timeout (
int, optional) โ timeout, in seconds, to use when uploading themes to the server. (defaultconfig.TIMEOUT).
- url (
โ ๏ธ Warning: themes cannot be deleted using PlexAPI! Read that again. You can't delete them. No take-backs. ๐ญ
setTheme(theme)โ sets the theme for a Plex object.- Raises
NotImplementedErrorโ themes cannot be set through the API. So sorry, bestie, that door is closed. ๐ช
- Raises
deleteTheme()โ deletes the theme from a Plex object.
๐ง class plexapi.mixins.ThemeUrlMixin ๐ง
Bases: object
Mixin for Plex objects that can have a theme url.
property themeUrlโ returns the theme url for the Plex object.
๐ class plexapi.mixins.SmartFilterMixin ๐
Bases: object
Mixin for Plex objects that can have smart filters. (That's genuinely all the docs say โ she's mysterious, she's lowkey.)
โ๏ธ class plexapi.mixins.SplitMergeMixin โ๏ธ
Bases: object
Mixin for Plex objects that can be split and merged.
split()โ splits a duplicated Plex object into separate objects. Break it up, break it up. ๐merge(ratingKeys)โ merges other Plex objects into the current object. Parameters:- ratingKeys (
list) โ a list of rating keys to merge.
- ratingKeys (
๐ class plexapi.mixins.UnmatchMatchMixin ๐
Bases: object
Mixin for Plex objects that can be unmatched and matched.
unmatch()โ unmatches the metadata match from the object. It's giving "who even are you". ๐ซmatches(agent=None, title=None, year=None, language=None)โ returns a list of (SearchResult) metadata matches. Parameters:- agent (
str) โ agent name to be used (imdb,thetvdb,themoviedb, etc.) - title (
str) โ title of item to search for. - year (
str) โ year of item to search in. - language (
str) โ language of item to search in.
- agent (
โจ Examples โจ โ copy these exactly, they're literally the cheat sheet:
1. video.matches()
2. video.matches(title="something", year=2020)
3. video.matches(title="something")
4. video.matches(year=2020)
5. video.matches(title="something", year="")
video.matches(title="", year=2020)video.matches(title="", year="")
So here's the โจvibe checkโจ on what each of those actually does, bestie:
- The default behaviour in Plex Web = no params in plexapi
- Both title and year specified by user
- Year automatically filled in
- Title automatically filled in
- Explicitly searches for title with blank year
- Explicitly searches for blank title with year
- I don't know what the user is thinking... return the same result as 1
For 2 to 7, the agent and language is automatically filled in ๐ซถ
fixMatch(searchResult=None, auto=False, agent=None) โ okay so this one takes a match result and uses it to update your show metadata. Lowkey the glow-up button for your metadata ๐
Parameters
auto(bool) โTrueuses first match from matches;Falseallows user to provide the matchsearchResult(SearchResult) โ Search result from~plexapi.base.matches()agent(str) โ Agent name to be used (imdb,thetvdb,themoviedb, etc.)
class plexapi.mixins.WatchlistMixin
Bases: object
Mixin for Plex objects that can be added to a user's watchlist. ๐
onWatchlist(account=None) โ Returns True if the item is on the user's watchlist. Also see onWatchlist().
Parameters
account(MyPlexAccount, optional) โ Account to check item on the watchlist. Note: This is required if you are not connected to a Plex server instance using the admin account.
addToWatchlist(account=None) โ Add this item to the specified user's watchlist. Also see addToWatchlist().
Parameters
account(MyPlexAccount, optional) โ Account to add item to the watchlist. Note: This is required if you are not connected to a Plex server instance using the admin account.
removeFromWatchlist(account=None) โ Remove this item from the specified user's watchlist. Also see removeFromWatchlist().
Parameters
account(MyPlexAccount, optional) โ Account to remove item from the watchlist. Note: This is required if you are not connected to a Plex server instance using the admin account.
streamingServices(account=None) โ Return a list of Availability objects for the available streaming services for this item.
Parameters
account(MyPlexAccount, optional) โ Account used to retrieve availability. Note: This is required if you are not connected to a Plex server instance using the admin account.
class plexapi.mixins.AlbumEditMixins
Bases: ArtLockMixin, PosterLockMixin, ThemeLockMixin, AddedAtMixin, AudienceRatingMixin, CriticRatingMixin, OriginallyAvailableMixin, SortTitleMixin, StudioMixin, SummaryMixin, TitleMixin, UserRatingMixin, CollectionMixin, GenreMixin, LabelMixin, MoodMixin, StyleMixin
class plexapi.mixins.ArtistEditMixins
Bases: ArtLockMixin, PosterLockMixin, ThemeLockMixin, AddedAtMixin, AudienceRatingMixin, CriticRatingMixin, SortTitleMixin, SummaryMixin, TitleMixin, UserRatingMixin, CollectionMixin, CountryMixin, GenreMixin, LabelMixin, MoodMixin, SimilarArtistMixin, StyleMixin
class plexapi.mixins.CollectionEditMixins
Bases: ArtLockMixin, PosterLockMixin, ThemeLockMixin, AddedAtMixin, AudienceRatingMixin, ContentRatingMixin, CriticRatingMixin, SortTitleMixin, SummaryMixin, TitleMixin, UserRatingMixin, LabelMixin
class plexapi.mixins.EpisodeEditMixins
Bases: ArtLockMixin, PosterLockMixin, ThemeLockMixin, AddedAtMixin, AudienceRatingMixin, ContentRatingMixin, CriticRatingMixin, OriginallyAvailableMixin, SortTitleMixin, SummaryMixin, TitleMixin, UserRatingMixin, CollectionMixin, DirectorMixin, LabelMixin, WriterMixin
class plexapi.mixins.MovieEditMixins
Bases: ArtLockMixin, PosterLockMixin, ThemeLockMixin, AddedAtMixin, AudienceRatingMixin, ContentRatingMixin, CriticRatingMixin, EditionTitleMixin, OriginallyAvailableMixin, OriginalTitleMixin, SortTitleMixin, StudioMixin, SummaryMixin, TaglineMixin, TitleMixin, UserRatingMixin, CollectionMixin, CountryMixin, DirectorMixin, GenreMixin, LabelMixin, ProducerMixin, WriterMixin
class plexapi.mixins.PhotoEditMixins
Bases: ArtLockMixin, PosterLockMixin, AddedAtMixin, PhotoCapturedTimeMixin, SortTitleMixin, SummaryMixin, TitleMixin, UserRatingMixin, TagMixin
class plexapi.mixins.PhotoalbumEditMixins
Bases: ArtLockMixin, PosterLockMixin, AddedAtMixin, SortTitleMixin, SummaryMixin, TitleMixin, UserRatingMixin
class plexapi.mixins.PlaylistEditMixins
Bases: ArtLockMixin, PosterLockMixin, SortTitleMixin, SummaryMixin, TitleMixin
class plexapi.mixins.SeasonEditMixins
Bases: ArtLockMixin, PosterLockMixin, ThemeLockMixin, AddedAtMixin, AudienceRatingMixin, CriticRatingMixin, SummaryMixin, TitleMixin, UserRatingMixin, CollectionMixin, LabelMixin
class plexapi.mixins.ShowEditMixins
Bases: ArtLockMixin, PosterLockMixin, ThemeLockMixin, AddedAtMixin, AudienceRatingMixin, ContentRatingMixin, CriticRatingMixin, OriginallyAvailableMixin, OriginalTitleMixin, SortTitleMixin, StudioMixin, SummaryMixin, TaglineMixin, TitleMixin, UserRatingMixin, CollectionMixin, GenreMixin, LabelMixin
class plexapi.mixins.TrackEditMixins
Bases: ArtLockMixin, PosterLockMixin, ThemeLockMixin, AddedAtMixin, AudienceRatingMixin, CriticRatingMixin, TitleMixin, TrackArtistMixin, TrackNumberMixin, TrackDiscNumberMixin, UserRatingMixin, CollectionMixin, GenreMixin, LabelMixin, MoodMixin
class plexapi.mixins.AlbumMixins
Bases: SplitMergeMixin, UnmatchMatchMixin, RatingMixin, ArtMixin, LogoMixin, PosterMixin, SquareArtMixin, ThemeUrlMixin, AlbumEditMixins
class plexapi.mixins.ArtistMixins
Bases: AdvancedSettingsMixin, SplitMergeMixin, UnmatchMatchMixin, ExtrasMixin, HubsMixin, RatingMixin, ArtMixin, LogoMixin, PosterMixin, SquareArtMixin, ThemeMixin, ArtistEditMixins
class plexapi.mixins.ClipMixins
Bases: ArtUrlMixin, LogoUrlMixin, PosterUrlMixin, SquareArtUrlMixin
class plexapi.mixins.CollectionMixins
Bases: AdvancedSettingsMixin, SmartFilterMixin, HubsMixin, RatingMixin, ArtMixin, LogoMixin, PosterMixin, SquareArtMixin, ThemeMixin, CollectionEditMixins
class plexapi.mixins.EpisodeMixins
Bases: ExtrasMixin, RatingMixin, ArtMixin, LogoMixin, PosterMixin, SquareArtMixin, ThemeUrlMixin, EpisodeEditMixins
class plexapi.mixins.MovieMixins
Bases: AdvancedSettingsMixin, SplitMergeMixin, UnmatchMatchMixin, ExtrasMixin, HubsMixin, RatingMixin, ArtMixin, LogoMixin, PosterMixin, SquareArtMixin, ThemeMixin, MovieEditMixins, WatchlistMixin
class plexapi.mixins.PhotoMixins
Bases: RatingMixin, ArtUrlMixin, LogoUrlMixin, PosterUrlMixin, SquareArtUrlMixin, PhotoEditMixins
class plexapi.mixins.PhotoalbumMixins
Bases: RatingMixin, ArtMixin, LogoMixin, PosterMixin, SquareArtMixin, PhotoalbumEditMixins
class plexapi.mixins.PlaylistMixins
Bases: SmartFilterMixin, ArtMixin, LogoMixin, PosterMixin, SquareArtMixin, PlaylistEditMixins
class plexapi.mixins.SeasonMixins
Bases: AdvancedSettingsMixin, ExtrasMixin, RatingMixin, ArtMixin, LogoMixin, PosterMixin, SquareArtMixin, ThemeUrlMixin, SeasonEditMixins
class plexapi.mixins.ShowMixins
Bases: AdvancedSettingsMixin, SplitMergeMixin, UnmatchMatchMixin, ExtrasMixin, HubsMixin, RatingMixin, ArtMixin, LogoMixin, PosterMixin, SquareArtMixin, ThemeMixin, ShowEditMixins, WatchlistMixin
class plexapi.mixins.TrackMixins
Bases: ExtrasMixin, RatingMixin, ArtUrlMixin, LogoUrlMixin, PosterUrlMixin, SquareArtUrlMixin, ThemeUrlMixin, TrackEditMixins
๐ธ MYPLEX PLEXAPI.MYPLEX ๐ธ
class plexapi.myplex.MyPlexAccount(username=None, password=None, token=None, session=None, timeout=None, code=None, remember=True)
Bases: PlexObject
MyPlex account and profile information. This object represents the data found Account on the myplex.tv servers at the url https://plex.tv/api/v2/user. You may create this object directly by passing in your username & password (or token). There is also a convenience method provided at myPlexAccount() which will create and return this object โ literally the bestie who handles all the login admin for you ๐ซถ
Parameters
username(str) โ Plex login username if not using a token.password(str) โ Plex login password if not using a token.token(str) โ Plex authentication token instead of username and password.session(requests.Session, optional) โ Use your own session object if you want to cache the http responses from PMS.timeout(int) โ timeout in seconds on initial connect to myplex (defaultconfig.TIMEOUT).code(str) โ Two-factor authentication code to use when logging in with username and password.remember(bool) โ Remember the account token for 14 days (DefaultTrue).
Variables
key(str) โ'https://plex.tv/api/v2/user'adsConsent(str) โ Unknown.adsConsentReminderAt(str) โ Unknown.adsConsentSetAt(str) โ Unknown.anonymous(str) โ Unknown.authToken(str) โ The account token.backupCodesCreated(bool) โ If the two-factor authentication backup codes have been created.confirmed(bool) โ If the account has been confirmed.country(str) โ The account country.email(str) โ The account email address.emailOnlyAuth(bool) โ tells you if login-with-email-only is turned on.experimentalFeatures(bool) โ whether the experimental features are enabled.friendlyName(str) โ your account's full name.entitlements(List<str>) โ the list of devices this account is allowed to use.guest(bool) โ is this account a Plex Home guest user?hasPassword(bool) โ does the account have a password?home(bool) โ is this account a Plex Home user?homeAdmin(bool) โ is this account the Plex Home admin?homeSize(int) โ how many accounts live in the Plex Home.id(int) โ the Plex account ID.joinedAt(datetime) โ the date the account joined Plex.locale(str) โ the account locale.mailingListActive(bool) โ are you subscribed to the Plex newsletter?mailingListStatus(str) โ your current mailing list status.maxHomeSize(int) โ the maximum number of accounts allowed in the Plex Home.pin(str) โ the hashed Plex Home PIN.profileAutoSelectAudio(bool) โ does the account have automatically select audio and subtitle tracks enabled?profileDefaultAudioLanguage(str) โ the preferred audio language for the account.profileDefaultSubtitleLanguage(str) โ the preferred subtitle language for the account.profileAutoSelectSubtitle(int) โ the auto-select subtitle mode (0= Manually selected,1= Shown with foreign audio,2= Always enabled).profileDefaultSubtitleAccessibility(int) โ the subtitles for the deaf or hard-of-hearing (SDH) searches mode (0= Prefer non-SDH subtitles,1= Prefer SDH subtitles,2= Only show SDH subtitles,3= Only shown non-SDH subtitles).profileDefaultSubtitleForced(int) โ the forced subtitles searches mode (0= Prefer non-forced subtitles,1= Prefer forced subtitles,2= Only show forced subtitles,3= Only show non-forced subtitles).protected(bool) โ does the account have a Plex Home PIN enabled?rememberExpiresAt(datetime) โ the date the token expires.restricted(bool) โ is this account a Plex Home managed user?rolesโ (List<str>) a list of account roles. Plexpass membership is listed here, bestie.scrobbleTypes(List<int>) โ Unknown. Literally unknown, we don't gatekeep, we just don't know. ๐subscriptionActive(bool) โ is the account's Plex Pass subscription active?subscriptionDescription(str) โ a description of the Plex Pass subscription.subscriptionFeaturesโ (List<str>) the list of features allowed on your Plex Pass subscription.subscriptionPaymentService(str) โ the payment service used for your Plex Pass subscription.subscriptionPlan(str) โ the name of the Plex Pass subscription plan.subscriptionStatus(str) โ string representation ofsubscriptionActive.subscriptionSubscribedAt(datetime) โ the date the account subscribed to Plex Pass.thumb(str) โ URL of the account thumbnail.title(str) โ the title of the account (username or friendly name).twoFactorEnabled(bool) โ is two-factor authentication enabled?username(str) โ the account username.uuid(str) โ the account UUID.
๐
signout()
Signs you out of the Plex account. Heads up: this invalidates the authentication token, so like... don't do it mid-scroll and then act surprised. ๐ญ
authenticationToken (property)
Returns the authentication token for the account. It's just an alias for authToken, no cap.
ping()
Pings the Plex.tv API. The cute part: this refreshes the authentication token so it doesn't expire on you. Self-care for your token, honestly. โจ
device(name=None, clientId=None)
Returns the MyPlexDevice that matches the name you specified.
Parameters:
name(str) โ the name to match against.clientId(str) โ theclientIdentifierto match against.
devices()
Returns a list of all MyPlexDevice objects connected to the server. The whole squad. ๐ซถ
resource(name)
Returns the MyPlexResource that matches the name specified.
Parameters:
name(str) โ the name or machine identifier to match against.
resources()
Returns a list of all MyPlexResource objects connected to the server.
inviteFriend(user, server, sections=None, allowSync=False, allowCameraUpload=False, allowChannels=False, filterMovies=None, filterTelevision=None, filterMusic=None)
Shares library content with the user you specify. Sharing is caring, bestie. ๐
Parameters:
user(MyPlexUser) โ aMyPlexUserobject, username, or email of the user to be added.server(PlexServer) โ aPlexServerobject, ormachineIdentifiercontaining the library sections to share.sections(List<LibrarySection>) โ list ofLibrarySectionobjects, or names to be shared (defaultNone).sectionsmust be defined in order to update shared libraries.allowSync(Bool) โ setTrueto allow the user to sync content.allowCameraUpload(Bool) โ setTrueto allow the user to upload photos.allowChannels(Bool) โ setTrueto allow the user to utilize installed channels.filterMovies(Dict) โ a dict containing the key'contentRating'and/or'label', each set to a list of values to be filtered. ex:{'contentRating':['G'], 'label':['foo']}filterTelevision(Dict) โ a dict containing the key'contentRating'and/or'label', each set to a list of values to be filtered. ex:{'contentRating':['G'], 'label':['foo']}filterMusic(Dict) โ a dict containing the key'label'set to a list of values to be filtered. ex:{'label':['foo']}
createHomeUser(user, server, sections=None, allowSync=False, allowCameraUpload=False, allowChannels=False, filterMovies=None, filterTelevision=None, filterMusic=None)
Shares library content with the specified user. (Yes, same description โ the original says it too, and I'm not about to invent new lore. ๐ง)
Parameters:
user(MyPlexUser) โ aMyPlexUserobject, username, or email of the user to be added.server(PlexServer) โ aPlexServerobject, ormachineIdentifiercontaining the library sections to share.sections(List<LibrarySection>) โ list ofLibrarySectionobjects, or names to be shared (defaultNone).sectionsmust be defined in order to update shared libraries.allowSync(Bool) โ setTrueto allow the user to sync content.allowCameraUpload(Bool) โ setTrueto allow the user to upload photos.allowChannels(Bool) โ setTrueto allow the user to utilize installed channels.filterMovies(Dict) โ a dict containing the key'contentRating'and/or'label', each set to a list of values to be filtered. ex:{'contentRating':['G'], 'label':['foo']}filterTelevision(Dict) โ a dict containing the key'contentRating'and/or'label', each set to a list of values to be filtered. ex:{'contentRating':['G'], 'label':['foo']}filterMusic(Dict) โ a dict containing the key'label'set to a list of values to be filtered. ex:{'label':['foo']}
createExistingUser(user, server, sections=None, allowSync=False, allowCameraUpload=False, allowChannels=False, filterMovies=None, filterTelevision=None, filterMusic=None)
Shares library content with the specified user. Again, same one-liner as the original โ I'm just the messenger. ๐
Parameters:
user(MyPlexUser) โ aMyPlexUserobject, username, or email of the user to be added.server(PlexServer) โ aPlexServerobject, ormachineIdentifiercontaining the library sections to share.sections(List<LibrarySection>) โ list ofLibrarySectionobjects, or names to be shared (defaultNone).sectionsmust be defined in order to update shared libraries.allowSync(Bool) โ setTrueto allow the user to sync content.allowCameraUpload(Bool) โ setTrueto allow the user to upload photos.allowChannels(Bool) โ setTrueto allow the user to utilize installed channels.filterMovies(Dict) โ a dict containing the key'contentRating'and/or'label', each set to a list of values to be filtered. ex:{'contentRating':['G'], 'label':['foo']}
filterTelevision(Dict) โ a dict with key'contentRating'and/or'label', each set to a list of values to filter out. like,{'contentRating':['G'], 'label':['foo']}โจfilterMusic(Dict) โ a dict with the key'label'set to a list of values to filter out. ex:{'label':['foo']}๐
removeFriend(user)
bestie removal protocol ๐ kicks the specified user out of your friends.
Parameters
user(MyPlexUser or str) โ theMyPlexUser, username, or email of the user you're removing.
removeHomeUser(user)
same energy but for your home users โ yeets the specified user out of your Plex Home. ๐
Parameters
user(MyPlexUser or str) โ theMyPlexUser, username, or email of the user to remove.
switchHomeUser(user, pin=None)
gives you back a whole new MyPlexAccount object that's logged in as the given home user. it's giving "who am i today" main character energy ๐ฆ
Parameters
user(MyPlexUser or str) โ theMyPlexUser, username, or email of the home user you wanna switch to.pin(str) โ the PIN for that home user (required if the home user has a PIN set, no skipping ๐ ).
Example
from plexapi.myplex import MyPlexAccount
# Login to a Plex Home account
account = MyPlexAccount('<USERNAME>', '<PASSWORD>')
# Switch to a different Plex Home user
userAccount = account.switchHomeUser('Username')
setPin(newPin, currentPin=None)
sets a brand new Plex Home PIN on the account ๐
Parameters
newPin(str) โ the new PIN you want to set.currentPin(str) โ the account's current PIN (required if you're changing the PIN, like, you gotta prove it's you).
removePin(currentPin)
deletes the Plex Home PIN off the account entirely, poof ๐ซง
Parameters
currentPin(str) โ the account's current PIN (required to remove the PIN).
setManagedUserPin(user, newPin)
sets a fresh Plex Home PIN for a managed home user. heads up: this has to be done from the Plex Home admin account, no sneaking around it ๐
Parameters
user(MyPlexUser or str) โ theMyPlexUseror username of the managed home user.newPin(str) โ the new PIN to set for that managed home user.
removeManagedUserPin(user)
strips the Plex Home PIN off a managed home user. again, admin account only, i don't make the rules ๐ซถ
Parameters
user(MyPlexUser or str) โ theMyPlexUseror username of the managed home user.
acceptInvite(user)
accepts a pending friend invite from the specified user. say yes bestie ๐
Parameters
user(MyPlexInvite or str) โ theMyPlexInvite, username, or email of the friend invite you're accepting.
cancelInvite(user)
cancels a pending invite for the specified user. (the manpage literally spells it "firend" and honestly? firend. ๐ iconic typo, keeping the vibe.)
Parameters
user(MyPlexInvite or str) โ theMyPlexInvite, username, or email of the friend invite to cancel.
updateFriend(user, server, sections=None, removeSections=False, allowSync=None, allowCameraUpload=None, allowChannels=None, filterMovies=None, filterTelevision=None, filterMusic=None)
the glow-up method for a user's share settings โจ tweak their access without removing them.
Parameters
user(MyPlexUser) โ theMyPlexUserobject, username, or email of the user being updated.server(PlexServer) โ aPlexServerobject, or amachineIdentifier, containing the library sections you're sharing.sections(List<LibrarySection>) โ a list ofLibrarySectionobjects, or names, to be shared (defaultNone).sectionsmust be defined in order to update shared libraries, ok?removeSections(Bool) โ setTrueto remove all shares. this supersedessections. โ ๏ธallowSync(Bool) โ setTrueto let the user sync content.allowCameraUpload(Bool) โ setTrueto let the user upload photos ๐ธallowChannels(Bool) โ setTrueto let the user utilise installed channels.filterMovies(Dict) โ a dict with key'contentRating'and/or'label', each set to a list of values to filter. ex:{'contentRating':['G'], 'label':['foo']}filterTelevision(Dict) โ a dict with key'contentRating'and/or'label', each set to a list of values to filter. ex:{'contentRating':['G'], 'label':['foo']}filterMusic(Dict) โ a dict with key'label'set to a list of values to filter. ex:{'label':['foo']}
user(username)
hands you the MyPlexUser matching that username or email ๐
Parameters
username(str) โ username, email, or id of the user to return.
users()
returns a list of all the MyPlexUser objects connected to your account. the whole friend group, assembled ๐
pendingInvite(username, includeSent=True, includeReceived=True)
returns the MyPlexInvite matching that username or email. ๐ฌ note: this can be a pending invite sent from your account or received to your account.
Parameters
username(str) โ username, email, or id of the user to return.includeSent(bool) โTrueto include sent invites.includeReceived(bool) โTrueto include received invites.
pendingInvites(includeSent=True, includeReceived=True)
returns a list of every MyPlexInvite object connected to your account. ๐ฎ note: this includes all pending invites sent from your account and received to it.
Parameters
includeSent(bool) โTrueto include sent invites.includeReceived(bool) โTrueto include received invites.
optOut(playback=None, library=None)
opt in or out of sharing stuff with plex. ๐ see: https://www.plex.tv/about/privacy-legal/
syncItems(client=None, clientId=None)
returns an instance of SyncList for the specified client. ๐
Parameters
client(MyPlexDevice) โ a client to querySyncItemsfor.clientId(str) โ an identifier of a client to querySyncItemsfor.
if both client and clientId are provided, the client wins ๐ if neither is provided, clientId gets set to the current client's identifier.
sync(sync_item, client=None, clientId=None)
adds the specified sync item for the client. ngl it's always easier to use the methods defined directly on the media objects, e.g. sync(), sync() ๐
Parameters
client(MyPlexDevice) โ a client you need to add theSyncItemto.clientId(str) โ an identifier of a client you need to add theSyncItemto.sync_item(SyncItem) โ a preparedSyncItemobject with all fields set.
if both client and clientId are provided, the client wins ๐ if neither is provided, clientId gets set to the current client's identifier.
Returns
an instance of the created syncItem. ๐
Return type
SyncItem
Raises
BadRequestโ when a client with the providedclientIdwasn't found. ๐ญBadRequestโ the provided client doesn't provide async-target.
claimToken()
returns a str โ a fresh "claim-token" you can use to register your new Plex Server instance to your account ๐ see: https://hub.docker.com/r/plexinc/pms-docker/, https://www.plex.tv/claim/
history(maxresults=None, mindate=None)
gets the play history for all library sections on all servers, for the owner. ๐ฐ๏ธ
Parameters
maxresults(int) โ only return the specified number of results (optional).mindate(datetime) โ minimum datetime to return results from.
onlineMediaSources()
returns a list of the user account's Online Media Sources settings โ AccountOptOut ๐บ
videoOnDemand()
returns a list of VOD Hub items โ Hub ๐ฌ
tidal()
returns a list of tidal Hub items โ Hub ๐ต
watchlist(filter=None, sort=None, libtype=None, maxresults=None, **kwargs)
returns a list of Movie and Show items sitting in the user's watchlist ๐ฟ note: the objects returned come from Plex's online metadata. to get the matching item on a Plex server, search for the media using the guid.
Parameters
filter(str, optional) โ'available'or'released'to only return items that are available or released, otherwise return all items.sort(str, optional) โ the format isfield:dir. Fields you can sort by:watchlistedAt(Added At),titleSort(Title),originallyAvailableAt(Release Date), orrating(Critic Rating). Anddircan beascordesc. That's it, that's the whole vibe ๐libtype(str, optional) โ'movie'or'show'if you only want movies or only want shows, otherwise it gives you everything.maxresults(int, optional) โ caps it at the number of results you specify, bestie. No more, no less.**kwargs(dict) โ extra custom filters you wanna slap onto the search results. Go off, customize.
Example
# Watchlist for released movies sorted by critic rating in descending order
watchlist = account.watchlist(filter='released', sort='rating:desc', libtype='movie')
item = watchlist[0] # First item in the watchlist
# Search for the item on a Plex server
result = plex.library.search(guid=item.guid, libtype=item.type)
onWatchlist(item)
Returns True if the item is on the user's watchlist. simple as that, a little yes/no moment โจ
Parameters
item(Movie or Show) โ the item you're checking, bestie. Is it on the watchlist or not, we gotta know.
addToWatchlist(items)
Adds media items to the user's watchlist. Get them on the list! ๐
Parameters
items(List) โ a list of Movie or Show objects to be added to the watchlist.
Raises BadRequest โ when you try to add invalid or existing media to the watchlist. yeah, no double-adding, the list is not having it ๐
removeFromWatchlist(items)
Removes media items from the user's watchlist. Bye bestie ๐
Parameters
items(List) โ a list of Movie or Show objects to be added to the watchlist. (yes, that's what the docs say, we're removing but it still says "added" โ iconic typo behavior, we keep it ๐)
Raises BadRequest โ when you try to remove invalid or non-existing media to the watchlist.
userState(item)
Returns a UserState object for the specified item. Little state machine moment.
Parameters
item(Movie or Show) โ the item to return the user state for.
isPlayed(item)
Returns True if the item is played on Discover.
okay so the original docstring for this one is a whole sphinx situation, and we are not editing it because the details matter. Here it is verbatim::param item (Movie: :param : :param Show: :param Season or: :param Episode): Object from searchDiscover(). :param Can be also result from Plex Movie or Plex TV Series agent.:โ so: item can be a Movie, Show, Season or Episode object fromsearchDiscover(), and it can also be a result from the Plex Movie or Plex TV Series agent. ๐ซถ
markPlayed(item)
Marks the Plex object as played on Discover.
same sphinx situation, verbatim::param item (Movie: :param : :param Show: :param Season or: :param Episode): Object from searchDiscover(). :param Can be also result from Plex Movie or Plex TV Series agent.:โ so again, item can be a Movie, Show, Season or Episode fromsearchDiscover(), or a result from the Plex Movie or Plex TV Series agent.
markUnplayed(item)
Marks the Plex object as unplayed on Discover. undoing the deed ๐ญ
verbatim once more::param item (Movie: :param : :param Show: :param Season or: :param Episode): Object from searchDiscover(). :param Can be also result from Plex Movie or Plex TV Series agent.:โ item is a Movie, Show, Season or Episode fromsearchDiscover(), or a result from the Plex Movie or Plex TV Series agent.
searchDiscover(query, limit=30, libtype=None, providers='discover')
Searches for movies and TV shows in Discover. Returns a list of Movie and Show objects. this is the main character of the api ngl ๐ฅ
Parameters
query(str) โ the search query, obviously. what are we looking for queen.limit(int, optional) โ limit to the specified number of results. Default30.libtype(str, optional) โ'movie'or'show'to only return movies or shows, otherwise return all items.providers(str, optional) โ'discover'for default behavior, or'discover,PLEXAVOD'to also include the Plex ad-supported video service, or'discover,PLEXAVOD,PLEXTVOD'to also include the Plex video rental service. options on options, we love to see it ๐
property viewStateSync
Returns True or False if syncing of watch state and ratings is enabled or disabled, respectively, for the account. Binary queen.
enableViewStateSync()
Enables syncing of watch state and ratings for the account. turn it on โจ
disableViewStateSync()
Disables syncing of watch state and ratings for the account. turn it off ๐
link(pin)
Links a device to the account using a pin code.
Parameters
pin(str) โ the 4 digit link pin code. four digits, that's it, don't overthink it ๐
publicIP()
Returns your public IP address. hi bestie, you're at this address apparently ๐
geoip(ip_address)
Returns a GeoLocation object with geolocation information for an IP address using Plex's GeoIP database.
Parameters
ip_address(str) โ the IP address to look up.
๐ฆ class plexapi.myplex.MyPlexUser(server, data, initpath=None, parent=None)
Bases: PlexObject
This object represents non-signed in users, like friends and linked accounts. NOTE: do not confuse this with the MyPlexAccount, which is your specific account. The raw xml for the data presented here can be found at: https://plex.tv/api/users/
Variables
TAG(str) โ'User'key(str) โ'https://plex.tv/api/users/'allowCameraUpload(bool) โTrueif this user can upload images.allowChannels(bool) โTrueif this user has access to channels.allowSync(bool) โTrueif this user can sync.email(str) โ the user's email address (user@gmail.com).filterAll(str) โ Unknown.filterMovies(str) โ Unknown.filterMusic(str) โ Unknown.filterPhotos(str) โ Unknown.filterTelevision(str) โ Unknown.home(bool) โ Unknown.id(int) โ the user's Plex account ID.protected(False) โ Unknown (possibly SSL enabled?).recommendationsPlaylistId(str) โ Unknown.restricted(str) โ Unknown.servers(*List<<MyPlexServerShare>)) โ servers shared with the user.thumb(str) โ link to the user's avatar.title(str) โ seems to be an alias for username.username(str) โ the user's username.
server(name)
Returns the MyPlexServerShare that matches the name specified.
Parameters
name(str) โ name of the server to return.
history(maxresults=None, mindate=None)
Get all Play History for a user in all shared servers.
verbatim docstring time: :param maxresults: Only return the specified number of results (optional). :type maxresults: int :param mindate: Min datetime to return results from. :type mindate: datetime โ so maxresults is an optional int capping the results, and mindate is a datetime for the minimum point to return results from. ๐ซถ
๐ธ class plexapi.myplex.MyPlexInvite(server, data, initpath=None, parent=None)
Bases: PlexObject
This object represents pending friend invites. the "omg did they accept yet" energy ๐ญ
Variables
TAG(str) โ'Invite'createdAt(datetime) โ datetime the user was invited.email(str) โ the user's email address (user@gmail.com).friend(bool) โTrueorFalseif the user is invited as a friend.friendlyName(str) โ the user's friendly name.home(bool) โTrueorFalseif the user is invited to a Plex Home.id(int) โ the user's Plex account ID.server(bool) โTrueorFalseif the user is invited to any servers.servers(*List<<MyPlexServerShare>)) โ servers shared with the user.thumb(str) โ link to the user's avatar.username(str) โ the user's username.
๐ง class plexapi.myplex.Section(server, data, initpath=None, parent=None)
Bases: PlexObject
This refers to a shared section. The raw xml for the data presented here can be found at: https://plex.tv/api/servers/{machineId}/shared_servers (there's a soft hyphen situation in the original, ignore it, the URL is the URL ๐
)
Variables
TAG(str) โsectionid(int) โ the shared section IDkey(int) โ the shared library section keyshared(bool) โ if this section is shared with the usertitle(str) โ title of the sectiontype(str) โmovie,tvshow,artist
history(maxresults=None, mindate=None)
Get all Play History for a user for this section in this shared server.
verbatim again: :param maxresults: Only return the specified number of results (optional). :type maxresults: int :param mindate: Min datetime to return results from. :type mindate: datetime โ maxresults optional int, mindate datetime for the earliest result you want back. โจ
โญ class plexapi.myplex.MyPlexServerShare(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single user's server reference. Used for library sharing. this is the "which server do they even have access to" object ๐
Variables
id(int) โ id for this shareserverId(str) โ what id plex uses for this.machineIdentifier(str) โ the server'smachineIdentifiername(str) โ the server's namelastSeenAt(datetime) โ last connected to the server?numLibraries(int) โ total number of librariesallLibraries(bool) โTrueif all libraries is shared with this user.owned(bool) โ1if the server is owned by the userpending(bool) โTrueif the invite is pending.
section(name)
Returns the Section that matches the name specified.
Parameters
name(str) โ name of the section to return.
sections()
Returns a list of all Section objects shared with this user. all of them. every single one. periodt ๐
๐ธ history(maxresults=9999999, mindate=None)
okay so literally all the Play History for a user on this shared server, in one go ๐
maxresults(int, optional) โ cap it at this many results if you don't want the whole entire archive. it's optional, king.mindate(datetime) โ the minimum datetime to return results from. like, "only the stuff after this moment pls".
๐ง class plexapi.myplex.MyPlexResource(server, data, initpath=None, parent=None)
Bases: PlexObject
so this one is giving main character energy for everything connected to your Plex server that can actually serve up content โ Plex Media Servers, iPhones, Android clients, the whole squad ๐ซถ. the raw xml for all this is literally sitting at:
https://plex.tv/api/v2/resources?includeHttps=1&includeRelay=1
๐ Variables
TAG(str) โ'Device'key(str) โ'https://plex.tv/api/v2/resources?includeHttps=1&includeRelay=1'accessToken(str) โ this resource's Plex access token ๐clientIdentifier(str) โ the unique ID for this resourceconnections(list) โ a list ofResourceConnectionobjects for this resourcecreatedAt(datetime) โ timestamp of when this resource first connected to your serverdevice(str) โ best guess on the type of device this is (PS, iPhone, Linux, etc)dnsRebindingProtection(bool) โTrueif the server had DNS rebinding protectionhome(bool) โ unknown ๐httpsRequired(bool) โTrueif the resource requires httpslastSeenAt(datetime) โ timestamp of when this resource last connectedname(str) โ the descriptive name of this resourcenatLoopbackSupported(bool) โTrueif the resource supports NAT loopbackowned(bool) โTrueif this resource is one of your own (you logged into it)ownerId(int) โ ID of the user that owns this resource (shared resources only)platform(str) โ the OS the resource is running (Linux, Windows, Chrome, etc.)platformVersion(str) โ version of the platformpresence(bool) โTrueif the resource is online โจproduct(str) โ Plex product (Plex Media Server, Plex for iOS, Plex Web, etc.)productVersion(str) โ version of the productprovides(str) โ list of services this resource provides (client, server, player, pubsub-player, etc.)publicAddressMatches(bool) โTrueif the public IP address matches the client's public IP addressrelay(bool) โTrueif this resource has the Plex Relay enabledsourceTitle(str) โ username of the user that owns this resource (shared resources only)synced(bool) โ unknown (possiblyTrueif the resource has synced content?)
๐ฅ preferred_connections(ssl=None, locations=None, schemes=None)
returns a sorted list of the available connection addresses for this resource, bestie. often times there's more than one address specified for a server or client, and the default behaviour will prioritize local connections before remote or relay โ and HTTPS before HTTP ๐
Parameters
ssl(bool, optional) โ setTrueto only connect to HTTPS connections. setFalseto only connect to HTTP connections. setNone(default) to connect to any HTTP or HTTPS connection.
ngl thelocationsandschemesparams are just sitting there in the signature โ the docs don't say a word about them, so I'm not gonna make anything up ๐
๐ connect(ssl=None, timeout=None, locations=None, schemes=None)
returns a brand new PlexServer or PlexClient object. it uses MyPlexResource.preferred_connections() to generate the priority order of connection addresses. after trying to connect to all available addresses for this resource โ and assuming at least one connection was successful โ the PlexServer object is built and handed right back to you ๐ธ
Parameters
ssl(bool, optional) โ setTrueto only connect to HTTPS connections. setFalseto only connect to HTTP connections. setNone(default) to connect to any HTTP or HTTPS connection.timeout(int, optional) โ the timeout in seconds to attempt each connection.
Raises NotFound โ when it's unable to connect to any addresses for this resource. ๐ญ
๐ class plexapi.myplex.ResourceConnection(server, data, initpath=None, parent=None)
Bases: PlexObject
represents a Resource Connection object found within the MyPlexResource objects. tiny but iconic.
๐ฆ Variables
TAG(str) โ'Connection'address(str) โ the connection IP addresshttpuri(str) โ full HTTP URLipv6(bool) โTrueif the address is IPv6local(bool) โTrueif the address is localport(int) โ the connection portprotocol(str) โ HTTP or HTTPSrelay(bool) โTrueif the address uses the Plex Relayuri(str) โ full connetion URL ๐ (their spelling, not mine, i'm just the messenger)
โญ class plexapi.myplex.MyPlexDevice(server, data, initpath=None, parent=None)
Bases: PlexObject
this object represents resources connected to your Plex server that provide playback ability from your Plex Server, iPhone or Android clients, Plex Web, this API, etc. the raw xml for the data presented here lives at:
https://plex.tv/devices.xml
๐ Variables
TAG(str) โ'Device'key(str) โ'https://plex.tv/devices.xml'clientIdentifier(str) โ unique ID for this resourceconnections(list) โ list of connection URIs for the devicedevice(str) โ best guess on the type of device this is (Linux, iPad, AFTB, etc)id(str) โ MyPlex ID of the devicemodel(str) โ model of the device (bueller, Linux, x86_64, etc.)name(str) โ hostname of the deviceplatform(str) โ OS the resource is running (Linux, Windows, Chrome, etc.)platformVersion(str) โ version of the platformproduct(str) โ Plex product (Plex Media Server, Plex for iOS, Plex Web, etc.)productVersion(string) โ version of the productprovides(str) โ list of services this resource provides (client, controller, sync-target, player, pubsub-player)publicAddress(str) โ public IP addressscreenDensity(str) โ unknown ๐screenResolution(str) โ screen resolution (750x1334, 1242x2208, etc.)token(str) โ Plex authentication token for the device ๐vendor(str) โ device vendor (ubuntu, etc.)version(str) โ unknown (1, 2, 1.3.3.3148-b38628e, 1.3.15, etc.)
๐ connect(timeout=None)
returns a new PlexClient or PlexServer. sometimes there's more than one address specified for a server or client, and after trying to connect to all available addresses for this client โ assuming at least one connection was successful โ the PlexClient object is built and returned ๐
Raises NotFound โ when it's unable to connect to any addresses for this device.
๐ delete()
removes this device from your account. bye bestie ๐
๐ syncItems()
returns an instance of SyncList for the current device.
Raises BadRequest โ when the device doesn't provides sync-target. (yep, they wrote it like that, and honestly? same energy ๐ญ)
๐งธ class plexapi.myplex.MyPlexPinLogin(session=None, requestTimeout=None, headers=None, oauth=False)
Bases: object
this is the MyPlex PIN login class โ it supports getting a token for authenticating the client, and it provides an access token so you can create a MyPlexAccount instance โจ. the login can be done using the four character PIN which the user must enter at https://plex.tv/link, or using Plex OAuth.
this helper class supports a polling, threaded and callback approach โ pick your fighter:
- the polling approach expects the developer to periodically check if the PIN login was successful using
checkLogin(). - the threaded approach expects the developer to call
run()and then, at a later time, callwaitForLogin()to wait for and check the result. - the callback approach is an extension of the threaded approach and expects the developer to pass the
callbackparameter to the call torun(). the callback will be called when the thread waiting for the PIN login to succeed either finishes or expires. the parameter passed to the callback is the received authentication token โ orNoneif the login expired ๐
Parameters
session(requests.Session, optional) โ use your own session object if you want to cache the http responses from Plex.requestTimeout(int, optional) โ timeout in seconds on initial connect toplex.tv(defaultconfig.TIMEOUT).headers(dict, optional) โ a dict ofX-Plexheaders to send with requests.oauth(bool, optional) โTrueto use Plex OAuth instead of PIN login.
๐ Variables
PINS(str) โ'https://plex.tv/api/v2/pins'POLLINTERVAL(int) โ1pin(str) โ four character PIN to use for the login athttps://plex.tv/linkfinished(bool) โ whether the pin login has finished or notexpired(bool) โ whether the pin login has expired or nottoken(str) โ the token you get back after login. That's the whole prize, bestie ๐
Example
from plexapi.myplex import MyPlexAccount, MyPlexPinLogin
pinlogin = MyPlexPinLogin(oauth=True)
pinlogin.run()
print(f'Login to Plex at the following url:\n{pinlogin.oauthUrl()}')
pinlogin.waitForLogin()
token = pinlogin.token
account = MyPlexAccount(token=token)
property pin โ returns the four-character PIN used for linking a device at https://plex.tv/link. It's literally an activation code, iykyk ๐
oauthUrl(forwardUrl=None) โ returns the Plex OAuth url for login.
forwardUrl(str, optional) โ the url to redirect the client to after login.
run(callback=None, timeout=120) โ kicks off the thread that monitors the PIN login state. Set it and forget it kinda energy โจ
callback(Callable[str], optional) โ callback called with the received authentication token.timeout(int, optional) โ timeout in seconds to wait for user login. Default120seconds.
Raises
RuntimeErrorโ if the thread is already running. One thread at a time, we're not doing chaos here ๐ญRuntimeErrorโ if the PIN login for the current PIN has expired.
waitForLogin() โ waits for the PIN login to succeed or expire. It will simply sit there until something happens, and honestly? Same.
Returns: True if the PIN login succeeded or False otherwise.
Return type: bool
stop() โ stops the thread monitoring the PIN login state. Bye bestie ๐
checkLogin() โ returns True if the PIN login has succeeded.
๐ class plexapi.myplex.MyPlexJWTLogin(session=None, requestTimeout=None, headers=None, oauth=False, token=None, jwtToken=None, keypair=(None, None), scopes=None)
Bases: object
The MyPlex JWT login class โ it gets you a JWT for authenticating the client and hands over an access token so you can build a MyPlexAccount instance. Lowkey the glow-up of the login world ๐
Login can happen two ways: with the four-character PIN the user types in at https://plex.tv/link, or with Plex OAuth. This class can also refresh or verify a JWT you already have. Versatile queen ๐
See: https://developer.plex.tv/pms/#section/API-Info/Authenticating-with-Plex
Heads up bestie: using this class requires the PyJWT with the cryptography packages installed โ that's pyjwt[crypto]. No package, no party ๐
This helper class supports a polling, threaded and callback approach:
- The polling approach expects the developer to periodically check if the PIN login was successful using
checkLogin(). - The threaded approach expects the developer to call
run()and then at a later time callwaitForLogin()to wait for and check the result. - The callback approach is an extension of the threaded approach and expects the developer to pass the
callbackparameter to the call torun(). The callback will be called when the thread waiting for the PIN login to succeed either finishes or expires. The parameter passed to the callback is the received authentication token orNoneif the login expired.
Parameters
session(requests.Session, optional) โ use your own session object if you want to cache the http responses from Plex.requestTimeout(int, optional) โ timeout in seconds on initial connect toplex.tv(defaultconfig.TIMEOUT).headers(dict, optional) โ a dict ofX-Plexheaders to send with requests.oauth(bool, optional) โTrueto use Plex OAuth instead of PIN login.token(str, optional) โ Plex token, only required to register the device initially if not using OAuth.jwtToken(str, optional) โ existing Plex JWT to verify or refresh.keypair(tuple[str|bytes], optional) โ a tuple of the full file paths (str) to the ED25519 private and public key pair, or the raw keys themselves (bytes), to use for signing the JWT. UsegenerateKeypair()to generate a new keypair if not provided.scope(list[str], optional) โ list of scopes to request in the new token. Default is all available scopes.
Variables
PINS(str) โ'https://plex.tv/api/v2/pins'AUTH(str) โ'https://clients.plex.tv/api/v2/auth'POLLINTERVAL(int) โ1SCOPES(list) โ list of all available scopes to request for the JWT.pin(str) โ four character PIN to use for the login athttps://plex.tv/link.finished(bool) โ whether the JWT login has finished or not.expired(bool) โ whether the JWT login has expired or not.jwtToken(str) โ the Plex JWT received after login or refreshing.decodedJWT(dict) โ the decoded Plex JWT payload.
Example
from plexapi.myplex import MyPlexAccount, MyPlexJWTLogin
# Method 1: Generate a new Plex JWT using Plex OAuth
jwtlogin = MyPlexJWTLogin(
oauth=True,
scopes=['username', 'email', 'friendly_name']
)
jwtlogin.generateKeypair(keyfiles=('private.key', 'public.key'))
jwtlogin.run()
print(f'Login to Plex at the following url:\n{jwtlogin.oauthUrl()}')
jwtlogin.waitForLogin()
jwtToken = jwtlogin.jwtToken
account = MyPlexAccount(token=jwtToken)
# Method 2: Generate a new Plex JWT using an existing Plex token and keypair
jwtlogin = MyPlexJWTLogin(
token='2ffLuB84dqLswk9skLos',
keypair=('private.key', 'public.key'),
scopes=['username', 'email', 'friendly_name']
)
jwtlogin.registerDevice()
jwtToken = jwtlogin.refreshJWT()
account = MyPlexAccount(token=jwtToken)
# Refresh an existing Plex JWT
jwtlogin = MyPlexJWTLogin(
jwtToken=jwtToken,
keypair=('private.key', 'public.key'),
scopes=['username', 'email', 'friendly_name']
)
if not jwtlogin.verifyJWT():
jwtToken = jwtlogin.refreshJWT()
account = MyPlexAccount(token=jwtToken)
generateKeypair(keyfiles=(None, None), overwrite=False) โ generates a fresh ED25519 private/public keypair for signing the JWT and saves them to files. Requires the cryptography package to be installed. New keys who dis ๐
keyfiles(tuple[str]) โ a tuple of the full file paths to write the private and public keypair to.overwrite(bool) โ set toTrueto overwrite existing keypair files. Default isFalse.
Raises FileExistsError โ when keypair files already exist and overwrite is False.
decodePlexJWT(verify_signature=True) โ returns the decoded Plex JWT with optional signature verification using the Plex public JWK.
verify_signature(bool) โ whether to verify the JWT signature and required claims. Defaults toTrue. Set toFalseto skip signature verification and required-claim enforcement.
property decodedJWT โ returns the decoded Plex JWT with signature verification and required-claim enforcement. The trustworthy version โจ
registerDevice() โ registers the device with Plex using the provided token and private/public keypair. This must be done once if OAuth was not used, before the Plex JWT can be refreshed. One and done, no cap ๐
Raises BadRequest โ when token or keypair is missing.
refreshJWT() โ refreshes the Plex JWT using the existing private/public keypair. Glow-up era ๐ธ
Returns: the new Plex JWT.
Return type: str
Raises
BadRequestโ whenkeypairis missing.BadRequestโ when the newly obtained JWT cannot be verified.
verifyJWT(refreshWithinDays=1) โ verifies the existing Plex JWT is valid and not expiring within the specified number of days. A vibe check for your token ๐ฅ
refreshWithinDays(int) โ number of days before expiration to consider the JWT invalid and in need of refresh. Default is1day.
property pin โ returns the four character PIN used for linking a device at https://plex.tv/link.
oauthUrl(forwardUrl=None) โ returns the Plex OAuth url for login.
forwardUrl(str, optional) โ the url to redirect the client to after login.
run(callback=None, timeout=120) โ starts the thread which monitors the PIN login state.
callback(Callable[str], optional) โ callback called with the received authentication token.timeout(int, optional) โ timeout in seconds to wait for user login. Default120seconds.
Raises
RuntimeErrorโ if the thread is already running.RuntimeErrorโ if the PIN login for the current PIN has expired.
waitForLogin() โ waits for the user login to succeed or expire.
Returns: True if the user login succeeded or False otherwise.
Return type: bool
stop() โ stops the thread monitoring the user login state. Thread said โ๏ธ
checkLogin() โ returns True if the user login has succeeded. โ
periodt, login success is the vibe check.
class plexapi.myplex.AccountOptOut(server, data, initpath=None, parent=None)
Bases: PlexObject
okay so this one represents a single AccountOptOut โ literally the https://plex.tv/api/v2/user/{userUUID}/settings/opt_outs situation. ๐
Variables
TAG(str) โoptOutkey(str) โ Online Media Source keyvalue(str) โ Online Media Sourceopt_in,opt_out, oropt_out_managedoptIn()โ sets the Online Media Source to"Enabled". โจoptOut()โ sets the Online Media Source to"Disabled". ๐ซถoptOutManaged()โ sets the Online Media Source to"Disabled for Managed Users". ๐
Raises BadRequest โ when trying to opt out music. ๐ญ not the music, bestie.
class plexapi.myplex.UserState(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single UserState. It's giving "watch history but make it a whole object" energy. ๐
Variables
TAG(str) โUserStatelastViewedAt(datetime) โ datetime the item was last played.ratingKey(str) โ unique key identifying the item.type(str) โ the media type of the item.viewCount(int) โ count of times the item was played.viewedLeafCount(int) โ number of items marked as played in the show/season.viewOffset(int) โ time offset in milliseconds from the start of the contentviewState(bool) โTrueorFalseif the item has been played.watchlistedAt(datetime) โ datetime the item was added to the watchlist.
class plexapi.myplex.GeoLocation(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single IP address geolocation. lowkey iconic for knowing where the vibes are coming from. ๐
Variables
TAG(str) โlocationcity(str) โ city namecode(str) โ country codecontinentCode(str) โ continent codecoordinates(Tuple<float>) โ latitude and longitudecountry(str) โ country nameeuropeanUnionMember(bool) โTrueif the country is a member of the European UnioninPrivacyRestrictedCountry(bool) โTrueif the country is privacy restrictedpostalCode(str) โ postal codesubdivisions(str) โ subdivision nametimezone(str) โ timezone
๐ธ PHOTO PLEXAPI.PHOTO
class plexapi.photo.Photoalbum(server, data, initpath=None, parent=None)
Bases: PlexPartialObject, PhotoalbumMixins
okay bestie, this one is literally a single Photoalbum โ aka a whole collection of photos, one cute lil' bundle ๐.
Variables
TAG(str) โ'Directory'TYPE(str) โ'photo'addedAt(datetime) โ when the photo album got added to the library, timestamped and everything.art(str) โ URL to the artwork image, shaped like/library/metadata/<ratingKey>/art/<artid>.composite(str) โ URL to the composite image,/library/metadata/<ratingKey>/composite/<compositeid>fields(List<Field>) โ a list of field objects, slay.guid(str) โ the Plex GUID for the photo album, likelocal://229674.images(List<Image>) โ list of image objects ๐ผ๏ธindex(sting) โ Plex index number for the photo album. (yes, the original says "sting", we don't ask questions, we just report it ๐ )key(str) โ API URL,/library/metadata/<ratingkey>.lastRatedAt(datetime) โ when the photo album was last rated.librarySectionID(int) โ LibrarySection ID.librarySectionKey(str) โ LibrarySection key.librarySectionTitle(str) โ LibrarySection title.listType(str) โ hardcoded as'photo'(super useful for search filters, iykyk).ratingKey(int) โ the unique key identifying this photo album.summary(str) โ summary of the photoalbum.thumb(str) โ URL to the thumbnail image,/library/metadata/<ratingKey>/thumb/<thumbid>.title(str) โ name of the photo album. (Trip to Disney World)titleSort(str) โ the title to use when sorting (defaults totitle).type(str) โ'photo'updatedAt(datetime) โ when the photo album was updated.userRating(float) โ rating of the photo album (0.0-10.0), which equals (0 stars - 5 stars) โญ
album(title)
Returns the Photoalbum that matches the title you pass in.
Parameters
title(str) โ Title of the photo album to return.
albums(**kwargs)
Returns a list of Photoalbum objects that live inside the album.
photo(title)
Returns the Photo that matches the title you asked for.
Parameters
title(str) โ Title of the photo to return.
photos(**kwargs)
Returns a list of Photo objects in the album ๐ซถ
clip(title)
Returns the Clip that matches the specified title.
Parameters
title(str) โ Title of the clip to return.
clips(**kwargs)
Returns a list of Clip objects in the album.
get(title)
Alias to photo(). Same energy, shorter name โจ
download(savepath=None, keep_original_name=False, subfolders=False)
Downloads all the photos and clips from the photo album. See download() for the details, bestie.
Parameters
savepath(str) โ defaults to the current working directory.keep_original_name(bool) โTrueto keep the original filename, otherwise a friendlier filename gets generated.subfolders(bool) โTrueto separate photos/clips into photo album folders.
property metadataDirectory
Returns the Plex Media Server data directory where the metadata is stored.
class plexapi.photo.Photo(server, data, initpath=None, parent=None)
Bases: PlexPartialObject, Playable, PhotoMixins
This is one single Photo. One. Iconic ๐
Variables
TAG(str) โ'Photo'TYPE(str) โ'photo'addedAt(datetime) โ when the photo was added to the library.createdAtAccuracy(str) โ Unknown (local).createdAtTZOffset(int) โ Unknown (-25200).fields(List<Field>) โ list of field objects.guid(str) โ the Plex GUID for the photo,com.plexapp.agents.none://231714?lang=xn.images(List<Image>) โ list of image objects.index(sting) โ Plex index number for the photo. (again with the "sting", we stay faithful ๐)key(str) โ API URL,/library/metadata/<ratingkey>.lastRatedAt(datetime) โ when the photo was last rated.librarySectionID(int) โ LibrarySection ID.librarySectionKey(str) โ LibrarySection key.librarySectionTitle(str) โ LibrarySection title.listType(str) โ hardcoded as'photo'(useful for search filters).media(List<Media>) โ list of media objects.originallyAvailableAt(datetime) โ when the photo was added to Plex.parentGuid(str) โ the Plex GUID for the photo album,local://229674.parentIndex(int) โ Plex index number for the photo album.parentKey(str) โ API URL of the photo album,/library/metadata/<parentRatingKey>.parentRatingKey(int) โ unique key identifying the photo album.parentThumb(str) โ URL to the photo album thumbnail image,/library/metadata/<parentRatingKey>/thumb/<thumbid>.parentTitle(str) โ name of the photo album for the photo.ratingKey(int) โ unique key identifying the photo.sourceURI(str) โ remote server URI,server://<machineIdentifier>/com.plexapp.plugins.library(remote playlist item only).summary(str) โ summary of the photo.tags(List<Tag>) โ list of tag objects.thumb(str) โ URL to the thumbnail image,/library/metadata/<ratingKey>/thumb/<thumbid>.title(str) โ name of the photo.titleSort(str) โ the title to use when sorting (defaults totitle).type(str) โ'photo'updatedAt(datetime) โ when the photo was updated.userRating(float) โ rating of the photo (0.0-10.0), equaling (0 stars - 5 stars).year(int) โ the year the photo was taken ๐
photoalbum()
Returns the photo's Photoalbum. like, who's your parent, bestie?
section()
Returns the LibrarySection the item belongs to.
property locations
heads up: this does not exist in the plex xml response โ it's added on so there's a common interface for getting the locations of the photo.
Returns
List<str>of file paths where the photo is found on disk.
sync(resolution, client=None, clientId=None, limit=None, title=None)
Adds the current photo as a sync item for a specified device. See sync() for possible exceptions (yes, possible exceptions, be aware ๐).
Parameters
resolution(str) โ maximum allowed resolution for synchronized photos, see thePHOTO_QUALITY_*values in the modulesync.client(MyPlexDevice) โ sync destination, seesync().clientId(str) โ sync destination, seesync().limit(int) โ maximum count of items to sync, unlimited ifNone.title(str) โ descriptive title for the new SyncItem; if it's empty the value gets generated from the metadata of the current photo.
Returns
- an instance of the created syncItem.
Return type
SyncItem
property metadataDirectory
Returns the Plex Media Server data directory where the metadata is stored.
class plexapi.photo.PhotoSession(server, data, initpath=None, parent=None)
Bases: PlexSession, Photo
Represents a single Photo session, loaded from sessions(). main character energy, currently playing ๐ฆ
๐ต PLAYLIST PLEXAPI.PLAYLIST
class plexapi.playlist.Playlist(server, data, initpath=None, parent=None)
Bases: PlexPartialObject, Playable, PlaylistMixins
Represents a single Playlist. your queue, your rules, periodt ๐
Variables
TAG(str) โ'Playlist'TYPE(str) โ'playlist'addedAt(datetime) โ when the playlist was added to the server.allowSync(bool) โTrueif you allow syncing playlists.composite(str) โ URL to the composite image,/playlist/<ratingKey>/composite/<compositeid>content(str) โ the filter URI string for smart playlists.duration(int) โ duration of the playlist in milliseconds.durationInSeconds(int) โ duration of the playlist in seconds.fields(List<Field>) โ list of field objects.guid(str) โ the Plex GUID for the playlist,com.plexapp.agents.none://XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX.icon(str) โ icon URI string for smart playlists.key(str) โ API URL,/playlist/<ratingkey>.leafCount(int) โ number of items in the playlist view.librarySectionID(int) โ library section identifier (radio only)librarySectionKey(str) โ library section key (radio only)librarySectionTitle(str) โ library section title (radio only)playlistType(str) โ'audio','video', or'photo'radio(bool) โ if this playlist represents a radio station ๐ปratingKey(int) โ unique key identifying the playlist.smart(bool) โTrueif the playlist is a smart playlist.summary(str) โ the lil summary blurb of the playlist โจtitle(str) โ the playlist's name, bestie ๐titleSort(str) โ the title to use when sorting (defaults totitle)type(str) โ literally just'playlist'updatedAt(datetime) โ the datetime the playlist was last updated ๐
property thumb ๐
Alias to self.composite.
property metadataType
Returns the type of metadata in the playlist โ so like movie, track, or photo. iykyk ๐
property isVideo
Returns True if this is a video playlist. simple as that ๐ฆ
property isAudio
Returns True if this is an audio playlist ๐ง
property isPhoto
Returns True if this is a photo playlist ๐ธ
filters()
Returns the search filter dict for the smart playlist. and like, the whole point โ that filter dict gets passed right back into search() to get your list of items back out. no cap โจ
section()
Returns the LibrarySection this smart playlist belongs to.
Raises
plexapi.exceptions.BadRequestโ when you're trying to get the section for a regular playlist ๐plexapi.exceptions.Unsupportedโ when it literally cannot determine the library section ๐ญ
item(title)
Returns the item in the playlist that matches the title you specified ๐ฏ
Parameters
title(str) โ Title of the item to return.
Raises plexapi.exceptions.NotFound โ when that item is not found in the playlist ๐
items()
Returns a list of all the items in the playlist. all of them. periodt ๐
get(title)
Alias to item(). same thing, shorter name, we love convenience ๐ซถ
addItems(items)
Add items to the playlist ๐
Parameters
items(List) โ List ofAudio,Video, orPhotoobjects to be added to the playlist.
Raises plexapi.exceptions.BadRequest โ when you try to add items to a smart playlist (rude, but like, not allowed)
removeItems(items)
Remove items from the playlist ๐๏ธ
Parameters
items(List) โ List ofAudio,Video, orPhotoobjects to be removed from the playlist.
Raises
plexapi.exceptions.BadRequestโ when trying to remove items from a smart playlistplexapi.exceptions.NotFoundโ when the item does not exist in the playlist ๐ญ
moveItem(item, after=None)
Move an item to a new position in the playlist ๐
Parameters
items(obj) โAudio,Video, orPhotoobjects to be moved in the playlist.after(obj) โAudio,Video, orPhotoobjects to move the item after in the playlist.
Raises
plexapi.exceptions.BadRequestโ when trying to move items in a smart playlistplexapi.exceptions.NotFoundโ when the item, or the item you saidafter, does not exist in the playlist ๐
updateFilters(limit=None, sort=None, filters=None, **kwargs)
Update the filters for a smart playlist โจ
Parameters
limit(int) โ Limit the number of items in the playlist.sort(str or list, optional) โ A string of comma separated sort fields, or a list of sort fields in the formatcolumn:dir. Seesearch()for more info.filters(dict) โ A dictionary of advanced filters. Seesearch()for more info.**kwargs(dict) โ Additional custom filters to apply to the search results. Seesearch()for more info.
Raises plexapi.exceptions.BadRequest โ when you try to update filters for a regular playlist ๐
โโ๏ธ
delete()
Delete the playlist. gone. poof. ๐จ
classmethod create(server, title, section=None, items=None, smart=False, limit=None, libtype=None, sort=None, filters=None, m3ufilepath=None, **kwargs)
Create a playlist ๐ main character energy fr fr
Parameters
server(PlexServer) โ Server to create the playlist on.title(str) โ Title of the playlist.section(LibrarySection, str) โ Smart playlists and m3u import only, the library section to create the playlist in.items(List) โ Regular playlists only, list ofAudio,Video, orPhotoobjects to be added to the playlist.smart(bool) โTrueto create a smart playlist. DefaultFalse.limit(int) โ Smart playlists only, limit the number of items in the playlist.libtype(str) โ Smart playlists only, the specific type of content to filter (movie,show,season,episode,artist,album,track,photoalbum,photo).sort(str or list, optional) โ Smart playlists only, a string of comma separated sort fields, or a list of sort fields in the formatcolumn:dir. Seesearch()for more info.filters(dict) โ Smart playlists only, a dictionary of advanced filters. Seesearch()for more info.m3ufilepath(str) โ Music playlists only, the full file path to an m3u file to import.
โ ๏ธ note bestie: this will overwrite any playlist previously created from the same m3u file. like, actually overwrite it ๐
**kwargs(dict) โ Smart playlists only, additional custom filters to apply to the search results. Seesearch()for more info.
Raises
plexapi.exceptions.BadRequestโ when no items are included to create the playlist.plexapi.exceptions.BadRequestโ when mixing media types in the playlist.plexapi.exceptions.BadRequestโ when attempting to import an m3u file into a non-music library.plexapi.exceptions.BadRequestโ when it failed to import the m3u file.
Returns โ A new instance of the created Playlist. ๐
Return type โ Playlist
copyToUser(user)
Copy the playlist to another user account ๐ซถ sharing is caring
Parameters
user(MyPlexUser or str) โMyPlexUserobject, username, email, or user id of the user to copy the playlist to.
sync(videoQuality=None, photoResolution=None, audioBitrate=None, client=None, clientId=None, limit=None, unwatched=False, title=None)
Add the playlist as a sync item for the specified device. See sync() for possible exceptions. ๐
Parameters
videoQuality(int) โ idx of quality of the video, one ofVIDEO_QUALITY_*values defined in the sync module. Used only when the playlist contains video.photoResolution(str) โ maximum allowed resolution for synchronized photos, seePHOTO_QUALITY_*values in the modulesync. Used only when the playlist contains photos.audioBitrate(int) โ maximum bitrate for synchronized music, better use one ofMUSIC_BITRATE_*values from the modulesync. Used only when the playlist contains audio.client(MyPlexDevice) โ sync destination, seesync().clientId(str) โ sync destination, seesync().limit(int) โ maximum count of items to sync, unlimited ifNone.unwatched(bool) โ ifTruewatched videos wouldn't be synced.title(str) โ descriptive title for the newSyncItem, if empty the value would be generated from metadata of current photo.
Raises
BadRequestโ when the playlist is not allowed to sync.Unsupportedโ when the playlist content is unsupported.
Returns โ A new instance of the created sync item.
Return type โ SyncItem
property metadataDirectory
Returns the Plex Media Server data directory where the metadata is stored ๐ iconic
๐ PLAYQUEUE PLEXAPI.PLAYQUEUE ๐
class plexapi.playqueue.PlayQueue(server, data, initpath=None, parent=None)
Bases: PlexObject
Okay so this class is your little remote control for a PlayQueue ๐๏ธ โ literally the thing controlling what plays next. Slay.
โจ Variables โจ
TAG(str) โ fr it's just'PlayQueue'TYPE(str) โ and this one's'playqueue'identifier(str) โcom.plexapp.plugins.library, no capitems(list) โ the actual list ofPlayableorPlaylistbaddiesmediaTagPrefix(str) โFx /system/bundle/media/flags/๐ท๏ธmediaTagVersion(int) โFx 1485957738playQueueID(int) โ the ID of the PlayQueue, iconicplayQueueLastAddedItemID(int) โ this one defines where the "Up Next" region starts. It stays empty unless the PlayQueue gets modified after creation, iykyk ๐playQueueSelectedItemID(int) โ the queue item ID of whatever's currently selectedplayQueueSelectedItemOffset(int) โ the offset of the selected item in the PlayQueue, counted from the very beginning of the queueplayQueueSelectedMetadataItemID(int) โ ID of the currently selected item, and yes it matchesratingKeyplayQueueShuffled(bool) โTrueif shuffled, periodtplayQueueSourceURI(str) โ the original URI that was used to create the PlayQueueplayQueueTotalCount(int) โ how many items are in the PlayQueueplayQueueVersion(int) โ version of the PlayQueue, and it increments every single time a change is made to the PlayQueue ๐selectedItem(Playable) โ media object for the currently selected item_server(PlexServer) โ the PlexServer associated with the PlayQueuesize(int) โ alias forplayQueueTotalCount, cute
๐ getQueueItem(item) ๐
Accepts a media item and returns a similar object from this PlayQueue. So useful for looking up playQueueItemIDs using items you got from the Library. Obsessed honestly.
๐ธ classmethod get(server, playQueueID, own=False, center=None, window=50, includeBefore=True, includeAfter=True) ๐ธ
Retrieve an existing PlayQueue by identifier. Grab it, bestie.
Parameters
server(PlexServer) โ the server you're connected toplayQueueID(int) โ identifier of an existing PlayQueueown(bool, optional) โ if the server should transfer ownershipcenter(int, optional) โ theplayQueueItemIDof the center of the window. Heads up: this does not changeselectedItem๐window(int, optional) โ number of items to return from each side of the center itemincludeBefore(bool, optional) โ include items before the center, defaultsTrue. And ifFalseit does not include the center eitherincludeAfter(bool, optional) โ include items after the center, defaultsTrue. Same deal,Falsemeans the center is out too
๐ฆ classmethod create(server, items, startItem=None, shuffle=0, repeat=0, includeChapters=1, includeRelated=1, continuous=0) ๐ฆ
Create and return a brand new PlayQueue. Main character energy ๐ซถ
Parameters
server(PlexServer) โ the server you're connected toitems(PlexPartialObject) โ a media item, or a whole list of media itemsstartItem(Playable, optional) โ media item in the PlayQueue where playback should beginshuffle(int, optional) โ start the playqueue shuffledrepeat(int, optional) โ start the playqueue shuffled (and yes, the docs literally say "shuffled" for this one too, that's just what it says, no notes ๐)includeChapters(int, optional) โ include ChaptersincludeRelated(int, optional) โ include Relatedcontinuous(int, optional) โ include additional items after the initial item. For a show this would be the next episodes, for a movie it does nothing, literally nothing ๐
โญ classmethod fromStationKey(server, key) โญ
Create and return a new PlayQueue.
This is a convenience method to create a PlayQueue for radio stations when you only have the key string available. Ngl this one's a lifesaver.
Parameters
server(PlexServer) โ the server you're connected tokey(str) โ a station key as provided byhubs()orstation()
Example ๐
from plexapi.playqueue import PlayQueue
music = server.library.section("Music")
artist = music.get("Artist Name")
station = artist.station()
key = station.key # "/library/metadata/12855/station/8bd39616-dbdb-459e-b8da-f46d0b170af4?type=10"
pq = PlayQueue.fromStationKey(server, key)
client = server.clients()[0]
client.playMedia(pq)
๐ addItem(item, playNext=False, refresh=True) ๐
Append the provided item to the "Up Next" section of the PlayQueue. Important vibe check: items can only be added to the section immediately following the currently playing item.
Parameters
item(PlayableorPlaylist) โ a single media item or a PlaylistplayNext(bool, optional) โ ifTrue, add this item to the front of the "Up Next" section. IfFalse, the item gets appended to the end of the "Up Next" section. This only has an effect if an item has already been added to the "Up Next" section. Seeโ https://support.plex.tv/articles/202188298-play-queues/for more details ๐refresh(bool, optional) โ refresh the PlayQueue from the server before updating
๐ง moveItem(item, after=None, refresh=True) ๐ง
Moves an item to the beginning of the PlayQueue. If after is provided, the item gets placed immediately after the specified item instead.
Parameters
item(Playable) โ an existing item in the PlayQueue to moveafterItemID(Playable, optional) โ a different item in the PlayQueue. If provided,itemwill be placed in the PlayQueue after this itemrefresh(bool, optional) โ refresh the PlayQueue from the server before updating
๐ removeItem(item, refresh=True) ๐
Remove an item from the PlayQueue. Bye bestie ๐
Parameters
item(Playable) โ an existing item in the PlayQueue to moverefresh(bool, optional) โ refresh the PlayQueue from the server before updating
๐ clear() ๐
Remove all items from the PlayQueue. Total reset, we love a clean slate.
๐ฅ refresh() ๐ฅ
Refresh the PlayQueue from the Plex server.
๐ SERVER PLEXAPI.SERVER ๐
class plexapi.server.PlexServer(baseurl=None, token=None, session=None, timeout=None)
Bases: PlexObject
Okay so THIS is the main entry point to interacting with a Plex server, the icon itself โจ. It lets you list connected clients, browse your library sections, and perform actions such as emptying trash. And if you don't know the auth token required to access your Plex server โ or you simply want to access your server with your username and password โ you can also create a PlexServer instance from MyPlexAccount. Convenient fr.
Parameters
baseurl(str) โ base url for to access the Plex Media Server (default:'http://localhost:32400')token(str) โ required Plex authentication token to access the serversession(requests.Session, optional) โ use your own session object if you want to cache the http responses from the servertimeout(int, optional) โ timeout in seconds on initial connection to the server (defaultconfig.TIMEOUT)
๐ธ Variables ๐ธ
allowCameraUpload(bool) โTrueif server allows camera uploadallowChannelAccess(bool) โTrueif server allows channel access (iTunes?)allowMediaDeletion(bool) โTrueis server allows media to be deletedallowSharing(bool) โTrueis server allows sharingallowSync(bool) โTrueis server allows syncbackgroundProcessing(bool) โ Unknown ๐certificate(bool) โTrueif server has an HTTPS certificatecompanionProxy(bool) โ Unknowndiagnostics(bool) โ UnknowneventStream(bool) โ UnknownfriendlyName(str) โ human friendly name for this server, the cute onehubSearch(bool) โTrueif Hub Search is enabled. I believe this is enabled for everyonemachineIdentifier(str) โ unique ID for this server (looks like an md5)multiuser(bool) โTrueif multiusers are enabledmyPlex(bool) โ Unknown (True if logged into myPlex?)myPlexMappingState(str) โ Unknown (ex:mapped)myPlexSigninState(str) โ Unknown (ex:ok)myPlexSubscription(bool) โTrueif you have a myPlex subscriptionmyPlexUsername(str) โ email address if signed into myPlex (user@example.com)ownerFeatures(list) โ the list of features the server owner is allowed to use ๐ this one's lowkey tied to your PlexPass subscription. The features include:camera_upload,cloudsync,content_filter,dvr,hardware_transcoding,home,lyrics,music_videos,pass,photo_autotags,premium_music_metadata,session_bandwidth_restrictions,sync,trailers,webhooks(and maybe more, bestie, the list keeps growing).photoAutoTag(bool) โTrueif photo auto-tagging is turned on ๐platform(str) โ the platform your server is hosted on (ex:Linux)platformVersion(str) โ the version of that platform (ex:'6.1 (Build 7601)','4.4.0-59-generic').pluginHost(bool) โ unknown ๐ literally nobody documented this onereadOnlyLibraries(bool) โ unknown ๐requestParametersInCookie(bool) โ unknown ๐streamingBrainVersion(bool) โ the current Streaming Brain version ๐ง โจsync(bool) โTrueif syncing to a device is enabled.transcoderActiveVideoSessions(int) โ how many video transcoding sessions are active rn ๐ฅtranscoderAudio(bool) โTrueif audio transcoding audio is available.transcoderLyrics(bool) โTrueif audio transcoding lyrics is available.transcoderPhoto(bool) โTrueif audio transcoding photos is available.transcoderSubtitles(bool) โTrueif audio transcoding subtitles is available.transcoderVideo(bool) โTrueif audio transcoding video is available.transcoderVideoBitrates(bool) โ list of video bitrates (the docs saybool, and we simply do not question the docs ๐).transcoderVideoQualities(bool) โ list of video qualities.transcoderVideoResolutions(bool) โ list of video resolutions.updatedAt(int) โ the datetime the server was updated.updater(bool) โ unknown ๐version(str) โ the current Plex version (ex:1.3.2.3112-1751929)voiceSearch(bool) โTrueif voice search is enabled. (is this Google Voice search? genuinely asking ๐ซถ)_baseurl(str) โ the HTTP address of the client._token(str) โ the token used to access this client._session(obj) โ the Requests session object used to access this client.
property library
Library to browse or search your media ๐โจ
property settings
Returns a list of all server settings.
identity()
Returns the Plex server identity ๐ชช
account()
Returns the Account object this server belongs to.
claim(account)
Claim the Plex server using a MyPlexAccount. Heads up bestie: this will only work with an unclaimed server on localhost or the same subnet โ ๏ธ
Parameters
account(MyPlexAccount) โ the account used to claim the server.
unclaim()
Unclaim the Plex server. This will remove the server from your MyPlexAccount ๐
property activities
Returns all current PMS activities.
agents(mediaType=None)
Returns a list of Agent objects this server has available.
createToken(type='delegation', scope='all')
Create a temp access token for the server ๐๏ธ
switchUser(user, session=None, timeout=None)
Returns a new PlexServer object logged in as the given username. ๐ Note: only the admin account can switch to other users โ that's the whole vibe check right there ๐
Parameters
user(MyPlexUser or str) โMyPlexUserobject, username, email, or user id of the user to log in to the server.session(requests.Session, optional) โ use your own session object if you want to cache the http responses from the server. This will default to the same session as the admin account if no new session is provided.timeout(int, optional) โ timeout in seconds on initial connection to the server. This will default to the same timeout as the admin account if no new timeout is provided.
Example
from plexapi.server import PlexServer
# Login to the Plex server using the admin token
plex = PlexServer('http://plexserver:32400', token='2ffLuB84dqLswk9skLos')
# Login to the same Plex server using a different account
userPlex = plex.switchUser("Username")
systemAccounts()
Returns a list of SystemAccount objects this server contains.
systemAccount(accountID)
Returns the SystemAccount object for the specified account ID.
Parameters
accountID(int) โ theSystemAccountID.
systemDevices()
Returns a list of SystemDevice objects this server contains ๐ฑ
systemDevice(deviceID)
Returns the SystemDevice object for the specified device ID.
Parameters
deviceID(int) โ theSystemDeviceID.
myPlexAccount()
Returns a MyPlexAccount object using the same token to access this server. ๐จ Real talk: if you are not the owner of this PlexServer you're likely to receive an authentication error calling this.
browse(path=None, includeFiles=True)
Browse the system file path using the Plex API. Returns a list of Path and File objects ๐๏ธ
Parameters
path(Path or str, optional) โ full path to browse.includeFiles(bool) โTrueto include files when browsing (Default).Falseto only return folders.
walk(path=None)
Walk the system file tree using the Plex API, similar to os.walk. Yields a 3-tuple (path, paths, files) where path is a string of the directory path, paths is a list of Path objects, and files is a list of File objects ๐ณ
Parameters
path(Path or str, optional) โ full path to walk.
isBrowsable(path)
Returns True if the Plex server can browse the given path.
Parameters
path(Path or str) โ full path to browse.
clients()
Returns a list of all PlexClient objects connected to server ๐บ
client(name)
Returns the PlexClient that matches the specified name or machine identifier.
Parameters
name(str) โ name or machine identifier of the client to return.
Raises NotFound โ unknown client name.
createCollection(title, section, items=None, smart=False, limit=None, libtype=None, sort=None, filters=None, **kwargs)
Creates and returns a new Collection ๐จโจ
Parameters
title(str) โ title of the collection.section(LibrarySection, str) โ the library section to create the collection in.items(List) โ regular collections only, list ofAudio,Video, orPhotoobjects to be added to the collection.smart(bool) โTrueto create a smart collection. DefaultFalse.limit(int) โ smart collections only, limit the number of items in the collection.libtype(str) โ smart collections only, the specific type of content to filter (movie,show,season,episode,artist,album,track,photoalbum,photo).sort(str or list, optional) โ smart collections only, a string of comma separated sort fields or a list of sort fields in the formatcolumn:dir. Seesearch()for more info.filters(dict) โ smart collections only, a dictionary of advanced filters. Seesearch()for more info.**kwargs(dict) โ smart collections only, additional custom filters to apply to the search results. Seesearch()for more info.
Raises
plexapi.exceptions.BadRequestโ when no items are included to create the collection.plexapi.exceptions.BadRequestโ when mixing media types in the collection.
Returns โ a new instance of the created Collection.
Return type โ Collection
Example
# Create a regular collection
movies = plex.library.section("Movies")
movie1 = movies.get("Big Buck Bunny")
movie2 = movies.get("Sita Sings the Blues")
collection = plex.createCollection(
title="Favorite Movies",
section=movies,
items=[movie1, movie2]
)
# Create a smart collection
collection = plex.createCollection(
title="Recently Aired Comedy TV Shows",
section="TV Shows",
smart=True,
sort="episode.originallyAvailableAt:desc",
filters={"episode.originallyAvailableAt>>": "4w", "genre": "comedy"}
)
createPlaylist(title, section=None, items=None, smart=False,
limit=None, libtype=None, sort=None, filters=None,
m3ufilepath=None, **kwargs)
Okay so this one creates and returns a brand new Playlist for you ๐ it's literally the "make me a playlist" button and it ate.
๐ซ Parameters
title(str) โ the title of the playlist. name your baby.section(LibrarySection, str) โ smart playlists and m3u import only bestie, this is the library section you wanna create the playlist in.items(List) โ regular playlists only! a list ofAudio,Video, orPhotoobjects to be added to the playlist.smart(bool) โTrueto create a smart playlist. DefaultFalse(so regular by default, no cap).limit(int) โ smart playlists only, limits the number of items in the playlist.libtype(str) โ smart playlists only, the specific type of content to filter (movie,show,season,episode,artist,album,track,photoalbum,photo).sort(str or list, optional) โ smart playlists only, a string of comma separated sort fields or a list of sort fields in the formatcolumn:dir. Seesearch()for more info.filters(dict) โ smart playlists only, a dictionary of advanced filters. Seesearch()for more info.m3ufilepath(str) โ music playlists only, the full file path to an m3u file to import. > Note: This will overwrite any playlist previously created from the same m3u file. so like, heads up ๐**kwargs(dict) โ smart playlists only, additional custom filters to apply to the search results. Seesearch()for more info.
๐ญ Raises
plexapi.exceptions.BadRequestโ when no items are included to create the playlist.plexapi.exceptions.BadRequestโ when mixing media types in the playlist.plexapi.exceptions.BadRequestโ when attempting to import m3u file into non-music library.plexapi.exceptions.BadRequestโ when failed to import m3u file.
So yeah, four separate ways to get a BadRequest and honestly? respect.
๐ซถ Returns
A new instance of the created Playlist. ๐
Return type: Playlist
โจ Example
# Create a regular playlist
episodes = plex.library.section("TV Shows").get("Game of Thrones").episodes()
playlist = plex.createPlaylist(
title="GoT Episodes",
items=episodes
)
# Create a smart playlist
playlist = plex.createPlaylist(
title="Top 10 Unwatched Movies",
section="Movies",
smart=True,
limit=10,
sort="audienceRating:desc",
filters={"audienceRating>>": 8.0, "unwatched": True}
)
# Create a music playlist from an m3u file
playlist = plex.createPlaylist(
title="Favorite Tracks",
section="Music",
m3ufilepath="/path/to/playlist.m3u"
)
look at that, three whole vibes: regular, smart, and the m3u import one ๐
createPlayQueue(item, **kwargs)
Creates and returns a new PlayQueue. the queue is queuing, your honor ๐ธ
Parameters
item(Media or Playlist) โ media or playlist to add to PlayQueue.kwargs(dict) โ see~plexapi.playqueue.PlayQueue.create.
downloadDatabases(savepath=None, unpack=False, showstatus=False)
Download databases. literally just grabbing the databases ๐ฅ
Parameters
savepath(str) โ defaults to current working dir.unpack(bool) โ unpack the zip file.showstatus(bool) โ display a progressbar.
downloadLogs(savepath=None, unpack=False, showstatus=False)
Download server logs. same energy as above but it's the logs ๐ซถ
Parameters
savepath(str) โ defaults to current working dir.unpack(bool) โ unpack the zip file.showstatus(bool) โ display a progressbar.
butlerTasks()
Return a list of ButlerTask objects. yes the butler has tasks, he's booked and busy ๐
runButlerTask(task)
Manually run a butler task immediately instead of waiting for the scheduled task to run. > Note: The butler task is run asynchronously. Check Plex Web to monitor activity. so like, don't sit there staring at your terminal waiting for it bestie, go look at Plex Web ๐ญ
Parameters
task(str) โ the name of the task to run. (e.g.'BackupDatabase')
Example
availableTasks = [task.name for task in plex.butlerTasks()]
print("Available butler tasks:", availableTasks)
checkForUpdate(force=True, download=False)
Returns a Release object containing release info if an update is available or None if no update is available. vibe check on your version โจ
Parameters
force(bool) โ force server to check for new releasesdownload(bool) โ download if a update is available.
isLatest()
Returns True if the installed version of Plex Media Server is the latest. slay, you're up to date ๐
canInstallUpdate()
Returns True if the newest version of Plex Media Server can be installed automatically. (e.g. Windows and Mac can install updates automatically, but Docker and NAS devices cannot.) sorry docker girlies, it's giving manual labour ๐
installUpdate()
Automatically install the newest version of Plex Media Server. go go go ๐ฅ
history(maxresults=None, mindate=None, ratingKey=None,
accountID=None, librarySectionID=None)
Returns a list of media items from watched history. If there are many results, they will be fetched from the server in batches of X_PLEX_CONTAINER_SIZE amounts. If you're only looking for the first <num> results, it would be wise to set the maxresults option to that amount so this functions doesn't iterate over all results on the server. fr fr listen to this advice, it'll save you so much time ๐
Parameters
maxresults(int) โ only return the specified number of results (optional).mindate(datetime) โ min datetime to return results from. This really helps speed up the result listing. For example:datetime.now() - timedelta(days=7)ratingKey(int/str)accountID(int/str)librarySectionID(int/str)
playlists(playlistType=None, sectionId=None, title=None,
sort=None, **kwargs)
Returns a list of all Playlist objects on the server. all of them. every single one ๐
Parameters
playlistType(str, optional) โ the type of playlists to return (audio,video,photo). Default returns all playlists.sectionId(int, optional) โ the section ID (key) of the library to search within.title(str, optional) โ general string query to search for. Partial string matches are allowed.sort(str or list, optional) โ a string of comma separated sort fields in the formatcolumn:dir.
playlist(title)
Returns the Playlist that matches the specified title. just the one, the main character ๐
Parameters
title(str) โ title of the playlist to return.
Raises
NotFound โ unable to find playlist. she's not here bestie ๐ญ
optimizedItems(removeAll=None)
Returns list of all Optimized objects connected to server. optimized and thriving โจ
conversions(pause=None)
Returns list of all Conversion objects connected to server. the conversions are converting, periodt ๐ซ
currentBackgroundProcess()
Returns list of all TranscodeJob objects running or paused on server. look at them go, all in the background, lowkey iconic ๐
query(key, method=None, headers=None, params=None, timeout=None,
**kwargs)
Main method used to handle HTTPS requests to the Plex server. This method helps by encoding the response to utf-8 and parsing the returned XML into and ElementTree object. Returns None if no data exists in the response. the backbone of the whole operation honestly, no cap ๐ซถ
search(query, mediatype=None, limit=None, sectionId=None)
Returns a list of media items or filter categories from the resulting Hub Search against all items in your Plex library. This searches genres, actors, directors, playlists, as well as all the obvious media titles. It performs spell-checking against your search terms (because KUROSAWA is hard to spell). It also provides contextual search results. So for example, if you search for 'Pernice', it'll return 'Pernice Brothers' as the artist result, but we'll also go ahead and return your most-listened to albums and tracks from the artist. If you type 'Arnold' you'll get a result for the actor, but also the most recently added movies he's in. the way this search actually understands context?? obsessed ๐ญ๐
Parameters
query(str) โ query to use when searching your library.mediatype(str, optional) โ limit your search to the specified media type.actor,album,artist,autotag,collection,director,episode,game,genre,movie,photo,photoalbum,place,playlist,shared,show,tag,tracklimit(int, optional) โ how many results you want per Hub, bestie. Cap it.sectionId(int, optional) โ the section ID (a.k.a. the key) of the library you wanna search inside. iykyk ๐
continueWatching()
Returns a list of every item chillin' in the Continue Watching hub. Your "bestie I swear I'll finish this show" queue, but as objects. ๐
sessions()
Returns a list of all the active session media objects โ like, everything that's currently playing. The live tea. โ
transcodeSessions()
Returns a list of all the active TranscodeSession objects. Yes, all of them. Every single one. ๐ฅ
startAlertListener(callback=None, callbackError=None)
Opens a websocket connection to the Plex Server so you can optionally get notifications. These are usually messages from Plex about media scans, plus updates to Transcode Sessions that are currently running. Returns a brand-new AlertListener object. โจ
Note: websocket-client has to be installed for this feature to work. No cap.
>> pip install websocket-client
Parameters
callback(func) โ the callback function to call whenever a message comes in.callbackError(func) โ the callback function to call when things go sideways (errors).
Raises Unsupported โ because websocket-client isn't installed, bestie. ๐ญ
transcodeImage(imageUrl, height, width, opacity=None, saturation=None, blur=None, background=None, blendColor=None, minSize=True, upscale=True, imageFormat=None)
Returns the URL for a transcoded image. Glow-up for your pics, literally. ๐ฆ
Parameters
imageUrl(str) โ the URL to the image (like the one returned bythumbUrl()orartUrl()). Heads up: the URL can be an online image.height(int) โ the height to transcode the image to.width(int) โ the width to transcode the image to.opacity(int, optional) โ changes the opacity of the image (0to100).saturation(int, optional) โ changes the saturation of the image (0to100).blur(int, optional) โ the blur to apply to the image, in pixels (e.g.3).background(str, optional) โ the background hex colour applied behind the opacity (e.g.'000000').blendColor(str, optional) โ the hex colour to blend the image with (e.g.'000000').minSize(bool, optional) โ maintain the smallest dimension. DefaultTrue.upscale(bool, optional) โ upscale the image if it's required. DefaultTrue.imageFormat(str, optional) โ'jpeg'(default) or'png'.
url(key, includeToken=None)
Builds a URL string with the proper token argument. The token gets appended to the URL if either includeToken is True or CONFIG.log.show_secrets is 'true'. Sneaky token behavior, honestly. ๐
refreshSynclist()
Forces PMS to download a fresh SyncList from Plex.tv. Out with the old, in with the new. ๐ง
refreshContent()
Forces PMS to refresh content for the SyncLists it already knows about.
refreshSync()
Calls refreshSynclist() and refreshContent() โ exactly what the Plex Web UI does when you click 'refresh'. Main character behavior. ๐
bandwidth(timespan=None, **kwargs)
Returns a list of StatisticsBandwidth objects containing the Plex server dashboard bandwidth data. Your data usage, but make it fashion. ๐
Parameters
timespan(str, optional) โ the timespan used to bin the bandwidth data. Default isseconds. Available timespans:seconds,hours,days,weeks,months.**kwargs(dict, optional) โ any of the available filters you can slap onto the bandwidth data. The time frame (at) andbytescan also be filtered with less-than or greater-than (check the examples below, bestie).accountID(int) โ theSystemAccountID to filter by.at(datetime) โ the time frame to filter (inclusive). The time frame can be either:- An exact time frame (e.g. only December 1st 2020:
at=datetime(2020, 12, 1)). - Before a specific time (e.g. before and including December 2020:
at<=datetime(2020, 12, 1)). - After a specific time (e.g. after and including January 2021:
at>=datetime(2021, 1, 1)).
- An exact time frame (e.g. only December 1st 2020:
bytes(int) โ the amount of bytes to filter (inclusive). The bytes can be either:- An exact number of bytes (not very useful, ngl) (e.g.
bytes=1024**3). - Less than or equal number of bytes (e.g.
bytes<=1024**3). - Greater than or equal number of bytes (e.g.
bytes>=1024**3).
- An exact number of bytes (not very useful, ngl) (e.g.
deviceID(int) โ theSystemDeviceID to filter by.lan(bool) โTrueto only retrieve local bandwidth,Falseto only retrieve remote bandwidth. Default returns all local and remote bandwidth.
Raises BadRequest โ when you apply an invalid timespan or an unknown filter. Rude, but fair. ๐
Example
from plexapi.server import PlexServer
plex = PlexServer('http://localhost:32400', token='xxxxxxxxxxxxxxxxxxxx')
# Filter bandwidth data for December 2020 and later, and more than 1 GB used.
filters = {
'at>': datetime(2020, 12, 1),
'bytes>': 1024**3
}
# Retrieve bandwidth data in one day timespans.
bandwidthData = plex.bandwidth(timespan='days', **filters)
# Print out bandwidth usage for each account and device combination.
for bandwidth in sorted(bandwidthData, key=lambda x: x.at):
account = bandwidth.account()
device = bandwidth.device()
gigabytes = round(bandwidth.bytes / 1024**3, 3)
local = 'local' if bandwidth.lan else 'remote'
date = bandwidth.at.strftime('%Y-%m-%d')
print(f'{account.name} used {gigabytes} GB of {local} bandwidth on {date} from {device.name}')
resources()
Returns a list of StatisticsResources objects holding the Plex server dashboard resources data. The receipts. ๐งพ
getWebURL(base=None, playlistTab=None)
Returns the Plex Web URL for the server. Cute link moment. ๐
Parameters
base(str) โ the base URL before the fragment (#!). Default ishttps://app.plex.tv/desktop.playlistTab(str) โ the playlist tab (audio,video,photo). Only used for the playlist URL.
class plexapi.server.Account(server, data, initpath=None, parent=None)
Bases: PlexObject
Contains the locally cached MyPlex account information. Lowkey, the properties it provides don't match the MyPlexAccount object very well. The reasoning (per the docs) is that this exists because access to myplex isn't required to get basic plex info โ and honestly I can't imagine this object is terribly useful unless you needed this info while offline. Fr fr. ๐ธ
Parameters
server(PlexServer) โ thePlexServerthis account is connected to (optional).data(ElementTree) โ the response fromPlexServerused to build this object (optional).
Variables
mappingError(str) โ Unknown. ๐คทโโ๏ธmappingErrorMessage(str) โ Unknown. Again. ๐mappingState(str) โ Unknown. We stay guessing.privateAddress(str) โ the local IP address of the Plex server.privatePort(str) โ the local port of the Plex server.publicAddress(str) โ the public IP address of the Plex server.publicPort(str) โ the public port of the Plex server.signInState(str) โ the signin state for this account (ex:ok).subscriptionActive(str) โTrueif the account subscription is active.subscriptionFeatures(str) โ the list of features the server allows for this account. This may be based on your PlexPass subscription. Features include:camera_upload,cloudsync,content_filter,dvr,hardware_transcoding,home,lyrics,music_videos,pass,photo_autotags,premium_music_metadata,session_bandwidth_restrictions,sync,trailers,webhooks(and maybe more).subscriptionState(str) โ'Active'if this subscription is active.username(str) โ the Plex account username (likeuser@example.com).
class plexapi.server.Activity(server, data, initpath=None, parent=None)
Bases: PlexObject
A currently running activity on the PlexServer. It's giving "something is happening rn". ๐ฅ
class plexapi.server.Release(server, data, initpath=None, parent=None)
Bases: PlexObject
(The docs don't say more than that, bestie โ it's a PlexObject subclass and that's the whole vibe.) ๐
class plexapi.server.SystemAccount(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single system account. One account, one icon. ๐
Variables
TAG(str) โ'Account'.autoSelectAudio(bool) โTrueorFalsedepending on whether the account has automatic audio language enabled.Identityโ ngl every server's gotta know who it is ๐ButlerTaskโ the little scheduled chores your server does while you sleep ๐งนStatisticsResourcesโ the actual numbers, the receipts ๐
๐ซถ class plexapi.server.SystemDevice(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single system device. One device, one entry, iconic behavior.
Variables:
TAG(str) โ'Device'clientIdentifier(str) โ The unique identifier for the device.createdAt(datetime) โ Datetime the device was created.id(int) โ The ID of the device (not the same as MyPlexDevice ID).key(str) โ API URL (/devices/<id>)name(str) โ The name of the device.platform(str) โ OS the device is running (Linux, Windows, Chrome, etc.)
๐ฆ class plexapi.server.StatisticsBandwidth(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single statistics bandwidth data. Numbers go brrr ๐
Variables:
TAG(str) โ'StatisticsBandwidth'accountID(int) โ The associated SystemAccount ID.at(datetime) โ Datetime of the bandwidth data.bytes(int) โ The total number of bytes for the specified time span.deviceID(int) โ The associated SystemDevice ID.lan(bool) โ True or False whether the bandwidth is local or remote.timespan(int) โ The time span for the bandwidth data.1: months,2: weeks,3: days,4: hours,6: seconds.
account()
Returns the SystemAccount associated with the bandwidth data.
device()
Returns the SystemDevice associated with the bandwidth data.
๐ class plexapi.server.StatisticsResources(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single statistics resources data.
Variables:
TAG(str) โ'StatisticsResources'at(datetime) โ Datetime of the resource data.hostCpuUtilization(float) โ The system CPU usage %.hostMemoryUtilization(float) โ The Plex Media Server CPU usage %.processCpuUtilization(float) โ The system RAM usage %.processMemoryUtilization(float) โ The Plex Media Server RAM usage %.timespan(int) โ The time span for the resource data (6: seconds).
ok bestie those four descriptions are exactly what the docs say, i'm just the messenger, don't @ me ๐
๐งน class plexapi.server.ButlerTask(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single scheduled butler task. The server's unpaid intern, fr.
Variables:
TAG(str) โ'ButlerTask'description(str) โ The description of the task.enabled(bool) โ Whether the task is enabled.interval(int) โ The interval the task is run in days.name(str) โ The name of the task.scheduleRandomized(bool) โ Whether the task schedule is randomized.title(str) โ The title of the task.
๐ class plexapi.server.Identity(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a server identity. Main character energy, obviously.
Variables:
claimed(bool) โ True or False if the server is claimed.machineIdentifier(str) โ The Plex server machine identifier.version(str) โ The Plex server version.
โจ SETTINGS PLEXAPI.SETTINGS โจ
The glow-up zone ๐ literally where you tweak your server's whole personality.
๐ธ class plexapi.settings.Settings(server, data, initpath=None)
Bases: PlexObject
Container class for all settings. Allows getting and setting PlexServer settings.
Variables:
key(str) โ'/:/prefs'
all()
Returns a list of all Setting objects available.
get(id)
Return the Setting object with the specified id.
groups()
Returns a dict of lists for all Setting objects grouped by setting group.
group(group)
Return a list of all Setting objects in the specified group.
Parameters:
- group (
str) โ Group to return all settings.
save()
Save any outstanding setting changes to the PlexServer. This performs a full reload() of Settings after complete.
โ ๏ธ bestie, listen: changes are NOT real until you call save(). They just vibe in memory. ๐ญ
๐ class plexapi.settings.Setting(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a single Plex setting.
Variables:
id(str) โ Setting id (or name).label(str) โ Short description of what this setting is.summary(str) โ Long description of what this setting is.type(str) โ Setting type (text,int,double,bool).default(str) โ Default value for this setting.value(str,bool,int,float) โ Current value for this setting.hidden(bool) โ True if this is a hidden setting.advanced(bool) โ True if this is an advanced setting.group(str) โ Group name this setting is categorized as.enumValues(list,dict) โ List or dictionary of valid values for this setting.
set(value)
Set a new value for this setting. NOTE: You must call plex.settings.save() for before any changes to setting values are persisted to the PlexServer.
๐ซถ yes it's worded exactly like that in the original. say it with me: save(). that's the whole assignment.
toUrl()
Helper for urls
๐ class plexapi.settings.Preferences(server, data, initpath=None, parent=None)
Bases: Setting
Represents a single Preferences.
Variables:
TAG(str) โ'Setting'FILTER(str) โ'preferences'
๐ General Settings ๐
butlerUpdateChannel (text)
Update Channel. (default: 16; choices: 16:Public|8:Plex Pass)
collectUsageData (bool)
Send anonymous usage data to Plex. This helps us improve your experience (for example, to help us match movies and TV shows). (default: True)
friendlyName (text)
Friendly name. This name will be used to identify this media server to other computers on your network. If you leave it blank, your computer's name will be used instead.
logDebug (bool)
Enable Plex Media Server debug logging. (default: True)
logTokens (bool)
Allow Plex Media Server tokens in logs. Media server tokens can be used to gain access to library content. Don't share logs containing tokens publicly. A server restart is required for a change to take effect.
๐ bestie do NOT post your token logs. that is a whole security situation. pls.
logVerbose (bool)
Enable Plex Media Server verbose logging.
๐ง Scheduled Task Settings ๐ง
butlerDatabaseBackupPath (text)
Backup directory. The directory in which database backups are stored. (default: /var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases)
butlerEndHour (int)
Time at which tasks stop running. The time at which the background maintenance tasks stop running. (default: 5; choices: 0:Midnight|1:1 am|2:2 am|3:3 am|4:4 am|5:5 am|6:6 am|7:7 am|8:8 am|9:9 am|10:10 am|11:11 am|12:Noon|13:1 pm|14:2 pm|15:3 pm|16:4 pm|17:5 pm|18:6 pm|19:7 pm|20:8 pm|21:9 pm|22:10 pm|23:11 pm)
butlerStartHour (int)
Time at which tasks start to run. The time at which the server starts running background maintenance tasks. (default: 2; choices: 0:Midnight|1:1 am|2:2 am|3:3 am|4:4 am|5:5 am|6:6 am|7:7 am|8:8 am|9:9 am|10:10 am|11:11 am|12:Noon|13:1 pm|14:2 pm|15:3 pm|16:4 pm|17:5 pm|18:6 pm|19:7 pm|20:8 pm|21:9 pm|22:10 pm|23:11 pm)
butlerTaskBackupDatabase (bool)
Backup database every three days. (default: True)
butlerTaskCleanOldBundles (bool)
Remove old bundles every week. (default: True)
butlerTaskCleanOldCacheFiles (bool)
Remove old cache files every week. (default: True)
butlerTaskDeepMediaAnalysis (bool)
Perform extensive media analysis during maintenance. (default: True)
butlerTaskOptimizeDatabase (bool)
Optimize database every week. (default: True)
butlerTaskRefreshEpgGuides (bool)
Perform refresh of program guide data.. (default: True)
butlerTaskRefreshLibraries (bool)
Update all libraries during maintenance.
butlerTaskRefreshLocalMedia (bool)
Refresh local metadata every three days. (default: True)
butlerTaskRefreshPeriodicMetadata (bool)
Refresh metadata periodically. (default: True)
butlerTaskUpgradeMediaAnalysis (bool)
Upgrade media analysis during maintenance. (default: True)
๐ Channels Settings ๐
disableCapabilityChecking (bool)
Disable capability checking. Capability checking ensures that plug-ins that are incompatible with this version of the server or the current client application you are using are hidden. Disabling capability checking is useful during development, but will enable access to plug-ins that may perform unreliably with certain client applications.
iTunesLibraryXmlPath (text)
iTunes library XML path.
iTunesSharingEnabled (bool)
Enable iTunes channel. A server restart is required for a change to take effect.
pluginsLaunchTimeout (int)
Number of seconds to wait before a plugin times out. (default: 180)
๐ฆ DLNA Settings ๐ฆ
dlnaAnnouncementLeaseTime (int)
DLNA server announcement lease time. Duration in seconds of DLNA Server SSDP announcement lease time. (default: 1800)
dlnaClientPreferences (text)
DLNA client preferences. Client-specific configuration settings for the DLNA server.
dlnaDefaultProtocolInfo(text) โ the DLNA default protocol info, bestie. This is the protocol info string the DLNA server drops in itsGetProtocolInforesponses. default:http-get::video/mpeg:,http-get::video/mp4:,http-get::video/vnd.dlna.mpeg-tts:,http-get::video/avi:,http-get::video/x-matroska:,http-get::video/x-ms-wmv:,http-get::video/wtv:,http-get::audio/mpeg:,http-get::audio/mp3:,http-get::audio/mp4:,http-get::audio/x-ms-wma,http-get::audio/wav:,http-get::audio/L16:,http-get:image/jpeg:,http-get:image/png:,http-get:image/gif:,http-get:image/tiff:(yes, that's the whole thing, don't @ me ๐)dlnaDescriptionIcons(text) โ the DLNA server description icons, aka the icons the DLNA server offers up when devices come asking for the server description. default:png,jpeg;260x260,120x120,48x48dlnaDeviceDiscoveryInterval(int) โ DLNA media renderer discovery interval. It's the number of seconds between DLNA media renderer discovery requests. default:60dlnaEnabled(bool) โ turn the DLNA server on. This is what lets the server stream media out to DLNA (Digital Living Network Alliance) devices. default:TruedlnaPlatinumLoggingLevel(text) โ DLNA server logging level. default:OFF; choices:OFF|FATAL|SEVERE|WARNING|INFO|FINE|FINER|FINEST|ALLdlnaReportTimeline(bool) โ DLNA server timeline reporting. Enables the DLNA server to report timelines for video play activity. default:True
๐ Extras Settings ๐
cinemaTrailersFromBluRay(bool) โ include Cinema Trailers from new and upcoming movies on Blu-ray. Heads up: this feature is Plex Pass only ๐cinemaTrailersFromLibrary(bool) โ include Cinema Trailers from movies in my library. default:TruecinemaTrailersFromTheater(bool) โ include Cinema Trailers from new and upcoming movies in theaters. Also Plex Pass only ๐cinemaTrailersPrerollID(text) โ Cinema Trailers pre-roll video. Copy and paste the video's detail page URL into this field, that's literally it ๐ซถcinemaTrailersType(int) โ choose Cinema Trailers from. default:1; choices:0:All movies|1:Only unwatched movies
๐ Library Settings ๐
allowMediaDeletion(bool) โ allow media deletion. The owner of the server gets to delete media files from disk. default:TrueautoEmptyTrash(bool) โ empty trash automatically after every scan. default:TruefSEventLibraryPartialScanEnabled(bool) โ run a partial scan when changes are detected. When changes to library folders are detected, only the folder that changed gets scanned.fSEventLibraryUpdatesEnabled(bool) โ update my library automatically. Your library gets updated automatically when changes to library folders are detected.generateBIFBehavior(text) โ generate video preview thumbnails. Video preview thumbnails provide live updates in Now Playing and while seeking on supported apps. Thumbnail generation may take a long time, cause high CPU usage, and consume additional disk space ๐ญ you can turn off thumbnail generation for individual libraries in the library's advanced settings. default:never; choices:never:never|scheduled:as a scheduled task|asap:as a scheduled task and when media is addedgenerateChapterThumbBehavior(text) โ generate chapter thumbnails. Chapter thumbnails provide images in the chapter view on supported apps. They can take a long time to generate and consume additional disk space. default:scheduled; choices:never:never|scheduled:as a scheduled task|asap:as a scheduled task and when media is addedonDeckWindow(int) โ weeks to consider for On Deck. Shows that have not been watched in this many weeks will not appear in On Deck. default:16scannerLowPriority(bool) โ run scanner tasks at a lower priority.scheduledLibraryUpdateInterval(int) โ library update interval. default:3600; choices:900:every 15 minutes|1800:every 30 minutes|3600:hourly|7200:every 2 hours|21600:every 6 hours|43200:every 12 hours|86400:dailyscheduledLibraryUpdatesEnabled(bool) โ update my library periodically.watchMusicSections(bool) โ include music libraries in automatic updates. Real talk: Linux systems limit the maximum number of watched directories, so this may cause problems with large music libraries ๐ซ
๐ Network Settings ๐
allowedNetworks(text) โ list of IP addresses and networks that are allowed without auth. A comma separated list of IP addresses or IP/netmask entries for networks that are allowed to access Plex Media Server without logging in. When the server is signed out and this value is set, only localhost and addresses on this list will be allowed.configurationUrl(text) โ Web Manager URL. default:http://127.0.0.1:32400/webcustomCertificateDomain(text) โ custom certificate domain. The domain name to be published to plex.tv using your mapped port; it must match a name from the custom certificate file.customCertificateKey(text) โ custom certificate encryption key.customCertificatePath(text) โ custom certificate location. Path to a PKCS #12 file containing a certificate and private key to enable TLS support on a custom domain.customConnections(text) โ custom server access URLs. A comma-separated list of URLs (http or https) which are published up to plex.tv for server discovery.enableHttpPipelining(bool) โ enable HTTP Pipelining. This feature can enable higher performance in the HTTP server component. A server restart is required for a change to take effect. default:TrueenableIPv6(bool) โ enable server support for IPv6.gdmEnabled(bool) โ enable local network discovery (GDM). This lets the media server discover other servers and players on the local network. default:TruelanNetworksBandwidth(text) โ LAN Networks. A comma separated list of IP addresses or IP/netmask entries for networks that will be considered to be on the local network when enforcing bandwidth restrictions. If set, all other IP addresses will be considered to be on the external network and will be subject to external network bandwidth restrictions. If left blank, only the server's subnet is considered to be on the local network.secureConnections(int) โ secure connections. When set to "Required", some unencrypted connections (originating from the Media Server computer) will still be allowed, and apps that don't support secure connections won't be able to connect at all. default:1; choices:0:Required|1:Preferred|2:DisabledwanPerUserStreamCount(int) โ remote streams allowed per user. The maximum number of simultaneous streams each user is allowed when not on the local network. choices:0:Unlimited|1:1|2:2|3:3|4:4|5:5|6:6|7:7|8:8|9:9|10:10|11:11|12:12|13:13|14:14|15:15|16:16|17:17|18:18|19:19|20:20webHooksEnabled(bool) โ Webhooks. This feature enables your server to send events to external services. default:True
๐ฅ Transcoder Settings ๐ฅ
hardwareAcceleratedCodecs(bool) โ use hardware acceleration when available (Experimental ๐). Plex Media Server will attempt to use hardware-accelerated video codecs when encoding and decoding video. Hardware acceleration can make transcoding faster and allow more simultaneous video transcodes, but it can also reduce video quality and compatibility. Trade-offs, bestie.segmentedTranscoderTimeout(int) โ segmented transcoder timeout. Timeout in seconds segmented transcodes wait for the transcoder to begin writing data. default:20transcodeCountLimit(int) โ maximum simultaneous video transcode. Limits the number of simultaneous video transcode streams your server can utilize. choices:0:Unlimited|1:1|2:2|3:3|4:4|5:5|6:6|7:7|8:8|9:9|10:10|11:11|12:12|13:13|14:14|15:15|16:16|17:17|18:18|19:19|20:20transcoderDefaultDuration(int) โ transcoder default duration. Duration in minutes to use when transcoding something with an unknown duration. default:120transcoderH264BackgroundPreset(text) โ background transcoding x264 preset. The x264 preset value used for background transcoding (Sync and Media Optimizer). Slower values will result in better video quality and smaller file sizes, but will take significantly longer to complete processing. default:veryfast; choices:ultrafast:Ultra fast|superfast:Super fast|veryfast:Very fast|faster:Faster|fast:Fast|medium:Medium|slow:Slow|slower:Slower|veryslow:Very slowtranscoderPruneBuffer(int) โ transcoder default prune buffer. Amount in past seconds to retain before pruning segments from a transcode. default:300transcoderQuality(int) โ transcoder quality. The quality profile used by the transcoder. choices:0:Automatic|1:Prefer higher speed encoding|2:Prefer higher quality encoding|3:Make my CPU hurt(yes that's a real option name, iconic ๐)transcoderTempDirectory(text) โ transcoder temporary directory. The directory to use when transcoding for temporary files.transcoderThrottleBuffer(int) โ transcoder default throttle buffer. Amount in seconds to buffer before throttling the transcoder. default:60
๐ฆ Misc Settings ๐ฆ
acceptedEULA(bool) โ has the user accepted the EULA.articleStrings(text) โ comma-separated list of strings considered articles when sorting titles. A server restart is required for a change to take effect.. default:the,das,der,a,an,el,lalanguageInCloud(bool) โ use language preferences from plex.tv.machineIdentifier(text) โ a unique identifier for the machine.publishServerOnPlexOnlineKey(bool) โ publish server on Plex Online. Publishing a server makes it automatically available on your client devices without any configuration of your router. Slay, no port forwarding required โจtranscoderCanOnlyRemuxVideo(bool) โ the transcoder can only remux video.transcoderVideoResolutionLimit(text) โ maximum video output resolution for the transcoder. default:0x0wanPerStreamMaxUploadRate(int) โ this is the cap on the bitrate of a remote stream coming out of this here server, iykyk. Limit remote stream bitrate. Set the maximum bitrate of a remote stream from this server. ๐ฆ The choices are literally:0:Original (No limit)|20000:20 Mbps (1080p)|12000:12 Mbps (1080p)|10000:10 Mbps (1080p)|8000:8 Mbps (1080p)|4000:4 Mbps (720p)|3000:3 Mbps (720p)|2000:2 Mbps (480p)|1500:1.5 Mbps (480p)|720:720 kbps|320:320 kbpswanTotalMaxUploadRate(int) โ External network total upload limit (kbps). Speed at which to limit the total bandwidth not on the local network, measured in kilobits per second. Pop in0and congrats, you have set no limit bestie ๐
๐ซฃ Undocumented Settings ๐ซฃ
Okay so these ones are, like, the mysterious cool kids โ no descriptions given, just vibes and types. Not me listing them all anyway because nothing gets skipped on my watch ๐
aBRKeepOldTranscodes(bool)allowHighOutputBitrates(bool)backgroundQueueIdlePaused(bool)butlerTaskGarbageCollectBlobs(bool)butlerTaskGenerateMediaIndexFiles(bool)certificateVersion(int) โ default:2dvrShowUnsupportedDevices(bool)enableABRDebugOverlay(bool)enableAirplay(bool)eyeQUser(text)forceAutoAdjustQuality(bool)generateIndexFilesDuringAnalysis(bool)gracenoteUser(text)hardwareDevicePath(text) โ default:/dev/dri/renderD128lastAutomaticMappedPort(int)manualPortMappingMode(bool)manualPortMappingPort(int) โ default:32400minimumProgressTime(int) โ default:60000plexMetricsUrl(text) โ default:https://metrics.plex.tvplexOnlineMail(text)plexOnlineUrl(text) โ default:https://plex.tvsyncMyPlexLoginGCDeferral(int) โ default:14400syncPagingItemsLimit(int) โ default:100systemAudioCodecs(bool) โ default:TruetranscoderH264MinimumCRF(double) โ default:16.0transcoderH264Options(text)transcoderH264OptionsOverride(text)transcoderH264Preset(text) โ default:veryfasttranscoderLivePruneBuffer(int) โ default:5400transcoderLogLevel(text) โ default:error
๐ SONOS PLEXAPI.SONOS ๐
class plexapi.sonos.PlexSonosClient(account, data, timeout=None)
Bases: PlexClient
Bestie. This is the class for interacting with a Sonos speaker via the Plex API, and it's giving main character energy fr fr ๐ The way it works? This class makes requests to an external Plex API, which then forwards the Sonos-specific commands right back to your Plex server & Sonos speakers. So it's a whole round trip. Iconic, honestly.
Heads up before you get excited: use of this feature requires an active Plex Pass subscription and Sonos speakers linked to your Plex account. It also requires remote access to be working properly. No remote access = no slay ๐ญ
More details on the Sonos integration are available here: https://support.plex.tv/articles/218237558-requirements-for-using-plex-for-sonos/
And like, the Sonos API emulates the Plex player control API closely, so if you know one you lowkey know the other: https://github.com/plexinc/plex-media-player/wiki/Remote-control-API
๐ Parameters ๐
account(PlexAccount) โ PlexAccount instance this Sonos speaker is associated with.data(ElementTree) โ Response from Plex Sonos API used to build this client.
๐ฆ Variables ๐ฆ
deviceClass(str) โ"speaker"lanIP(str) โ Local IP address of speaker.machineIdentifier(str) โ Unique ID for this device.platform(str) โ"Sonos"platformVersion(str) โ Build version of Sonos speaker firmware.product(str) โ"Sonos"protocol(str) โ"plex"protocolCapabilities(list<str>) โ List of client capabilities (timeline,playback,playqueues,provider-playback)server(PlexServer) โ Server this client is connected to.session(Session) โ Session object used for connection.title(str) โ Name of this Sonos speaker.token(str) โ X-Plex-Token used for authentication_baseurl(str) โ Address of public Plex Sonos API endpoint._commandId(int) โ Counter for commands sent to Plex API._token(str) โ Token associated with linked Plex account._session(obj) โ Requests session object used to access this client.
๐ต playMedia(media, offset=0, **params) ๐ต
Start playback of the specified media item. See also: โจ
๐ธ Parameters ๐ธ
media(Media) โ Media item to be played back (movie, music, photo, playlist, playqueue).offset(int) โ Number of milliseconds at which to start playing, with zero representing the beginning (default0).**params(dict) โ Optional additional parameters to include in the playback request. See also:https://github.com/plexinc/plex-media-player/wiki/Remote-control-API#modified-commands
๐ SYNC PLEXAPI.SYNC ๐
Okay bestie, so ๐ Mobile Sync โ you can literally work with it on other devices right away, no gatekeeping. But if you want your app to be a sync-target (like, the thing items get synced to), you gotta init some variables first. Slay:
def init_sync():
import plexapi
plexapi.X_PLEX_PROVIDES = 'sync-target'
plexapi.BASE_HEADERS['X-Plex-Sync-Version'] = '2'
plexapi.BASE_HEADERS['X-Plex-Provides'] = plexapi.X_PLEX_PROVIDES
# mimic iPhone SE
plexapi.X_PLEX_PLATFORM = 'iOS'
plexapi.X_PLEX_PLATFORM_VERSION = '11.4.1'
plexapi.X_PLEX_DEVICE = 'iPhone'
plexapi.BASE_HEADERS['X-Plex-Platform'] = plexapi.X_PLEX_PLATFORM
plexapi.BASE_HEADERS['X-Plex-Platform-Version'] = plexapi.X_PLEX_PLATFORM_VERSION
plexapi.BASE_HEADERS['X-Plex-Device'] = plexapi.X_PLEX_DEVICE
The way you have to fake platform/device/model is lowkey not optional โ transcoding profiles are hardcoded in Plex, that's just the vibe ๐ญ. And yeah, you obviously also gotta explicitly say your app supports sync-target. No cap.
๐ฆ class plexapi.sync.SyncItem(server, data, initpath=None, clientIdentifier=None)
Bases: PlexObject
Represents a single sync item, for the specified server and client โจ. Like, when you're in the UI and you say sync "this" to "that", congrats bestie, you basically just created a sync item ๐ .
Variables ๐
id(int) โ unique id of the item.clientIdentifier(str) โ an identifier of Plex Client device, to which the item is belongs.machineIdentifier(str) โ the id of server which holds all this content.version(int) โ current version of the item. Every time you modify the item (e.g. by changing amount if media to sync) a new version gets created.rootTitle(str) โ the title of library/media from which the sync item was created. E.g.:- when you create an item for an episode 3 of season 3 of show Example, the value would be Title of Episode 3
- when you create an item for a season 3 of show Example, the value would be Season 3
- when you set to sync all your movies in library named "My Movies" to value would be My Movies.
title(str) โ the title which you've set when created the sync item.metadataType(str) โ the type of media which hides inside, can beepisode,movie, etc.contentType(str) โ basic type of the content:videooraudio.status(Status) โ current status of the sync.mediaSettings(MediaSettings) โ media transcoding settings used for the item.policy(Policy) โ the policy of which media to sync.location(str) โ plex-style library url with all required filters / sorting.
๐ซถ server()
Returns MyPlexResource with server of current item.
๐ซถ getMedia()
Returns list of Playable which belong to this sync item.
๐ซถ markDownloaded(media)
Mark the file as downloaded โ and by the nature of Plex it will be marked as downloaded within any SyncItem where it presented ๐.
Parameters
- media (
base.Playable) โ the media to be marked as downloaded.
๐ซถ delete()
Removes current SyncItem. Byeee ๐
๐ฆ class plexapi.sync.SyncList(server, data, initpath=None, parent=None)
Bases: PlexObject
Represents a Mobile Sync state, specific for a single client โ and within one SyncList you may see items from different servers ๐. Chaotic but iconic.
Variables ๐
clientId(str) โ an identifier of the client.items(List<SyncItem>) โ list of registered items to sync.
๐ฆ class plexapi.sync.Status(itemsCount, itemsCompleteCount, state, totalSize, itemsDownloadedCount, itemsReadyCount, itemsSuccessfulCount, failureCode, failure)
Bases: object
Represents the current status of a specific SyncItem. Vibe check for your sync, basically โจ
Variables ๐
failureCodeโ unknown, never got one yet ๐.failureโ unknown.state(str) โ server-side status of the item, can becompleted,pending,empty, and probably something else.itemsCount(int) โ total items count.itemsCompleteCount(int) โ count of transcoded and/or downloaded items.itemsDownloadedCount(int) โ count of downloaded items.itemsReadyCount(int) โ count of transcoded items, which can be downloaded.totalSize(int) โ total size in bytes of complete items.itemsSuccessfulCount(int) โ unknown, in my experience it always was equal toitemsCompleteCount.
๐ฆ class plexapi.sync.MediaSettings(maxVideoBitrate=4000, videoQuality=100, videoResolution='1280x720', audioBoost=100, musicBitrate=192, photoQuality=74, photoResolution='1920x1080', subtitleSize=100)
Bases: object
Transcoding settings used for all media within a SyncItem ๐ฅ. Look at all those defaults, we love a well-configured queen.
Variables ๐
audioBoost(int) โ unknown.maxVideoBitrate(int|str) โ maximum bitrate for video, may be empty string.musicBitrate(int|str) โ maximum bitrate for music, may be an empty string.photoQuality(int) โ photo quality on scale 0 to 100.photoResolution(str) โ maximum photo resolution, formatted asWxH(e.g.1920x1080).videoResolution(str) โ maximum video resolution, formatted asWxH(e.g.1280x720, may be empty).subtitleSize(int) โ subtitle size on scale 0 to 100.videoQuality(int) โ video quality on scale 0 to 100.
๐
static createVideo(videoQuality)
Returns a MediaSettings object, based on the provided video quality value ๐ฌ.
Parameters
- videoQuality (int) โ idx of quality of the video, one of
VIDEO_QUALITY_*values defined in this module.
Raises BadRequest โ When provided unknown video quality.
๐
static createMusic(bitrate)
Returns a MediaSettings object, based on the provided music quality value ๐ต.
Parameters
- bitrate (int) โ maximum bitrate for synchronized music, better use one of
MUSIC_BITRATE_*values from the module.
๐
static createPhoto(resolution)
Returns a MediaSettings object, based on the provided photo quality value ๐ธ.
Parameters
- resolution (str) โ maximum allowed resolution for synchronized photos, see
PHOTO_QUALITY_*values in the module.
Raises BadRequest โ When provided unknown video quality.
๐ฆ class plexapi.sync.Policy(scope, unwatched, value=0)
Bases: object
The policy of syncing the media โ like, how many items to sync and whether to process watched media or not ๐ค.
Variables ๐
scope(str) โ type of limitation policy, can becountorall.value(int) โ amount of media to sync, valid only whenscope=count.unwatched(bool) โTruemeans disallow to sync watched media.
๐
static create(limit=None, unwatched=False)
Creates a Policy object for the provided options and automatically sets the proper scope value โจ. It's giving effortless.
Parameters
- limit (int) โ limit items by count.
- unwatched (bool) โ if
Truethen watched items wouldn't be synced.
Returns Policy.
okay that's the sync tea for now, but we're literally not done โ more parts coming bestie, don't go anywhere ๐
plexapi.utils.downloadSessionImages(server, filename=None, height=150, width=150, opacity=100, saturation=100)โ the lil helper bestie that grabs a bif image (or athumb.url) straight offplex.server.sessions. ๐ผ๏ธ Params:serverโ the server you're pulling from.filename(str) โ default toNone.height(int) โ height of the image.width(int) โ width of the image.opacity(int) โ opacity of the resulting image (possibly deprecated ๐).saturation(int) โ saturating of the resulting image.
Returns {'filepath': '<filepath>', 'url': 'http://<url>'}, {'<username>': {filepath, url}}, ... and the return type is literally documented as {'hellowlol' โ yes really, that's what it says, no cap. ๐
plexapi.utils.download(url, token, filename=None, savepath=None, session=None, chunksize=4096, unpack=False, mocked=False, showstatus=False)โ helper to download a thumb, videofile or other media item. Returns the local path to the downloaded file. ๐ฅurl(str) โ URL where the content be reached.token(str) โ Plex auth token to include in headers.filename(str) โ filename of the downloaded file, defaultNone.savepath(str) โ defaults to current working dir.chunksize(int) โ what chunksize read/write at the time.mocked(bool) โ helper to do everything except write the file.unpack(bool) โ unpack the zip file.showstatusโ display a progressbar. ๐
plexapi.utils.getMyPlexAccount(opts=None)โ lil helper that tries to get aMyPlexAccountinstance by checking these locations for a username and password. Super useful for building user-friendly command line tools, fr. It goes:- command-line options (
opts). - environment variables and
config.ini. - prompt on the command line.
- command-line options (
plexapi.utils.createMyPlexDevice(headers=None, account=None, timeout=10)โ helper to create a newMyPlexDevice. Returns a newMyPlexDeviceinstance. ๐headers(dict) โ provide theX-Plex-headers for the new device. A uniqueX-Plex-Client-Identifieris required, or one will be generated if not provided.account(MyPlexAccount) โ the Plex account to create the device on.timeout(int) โ timeout in seconds to wait for device login.
plexapi.utils.plexOAuth(headers, forwardUrl=None, timeout=120)โ helper for Plex OAuth login. Returns a newMyPlexAccountinstance. ๐headers(dict) โ provide theX-Plex-headers for the new device. A uniqueX-Plex-Client-Identifieris required, or one will be generated if not provided.forwardUrl(str, optional) โ the url to redirect the client to after login.timeout(int, optional) โ timeout in seconds to wait for user login. Default120seconds.
plexapi.utils.plexJWTAuth(headers=None, forwardUrl=None, timeout=120, keypair=(None, None), scopes=None)โ helper for Plex JWT authentication using Plex OAuth. Returns a newMyPlexAccountinstance. ๐ชชheaders(dict, optional) โ provide theX-Plex-headers for the new device. A uniqueX-Plex-Client-Identifieris required, or one will be generated if not provided.forwardUrl(str, optional) โ the url to redirect the client to after login.timeout(int, optional) โ timeout in seconds to wait for user login. Default120seconds.keypair(tuple, optional) โ a tuple of the ED25519(privateKey, publicKey)to use for signing the JWT. If not provided, a new keypair will be generated and saved to'private.key'and'public.key'. ๐๏ธscopes(list[str], optional) โ list of scopes to request in the JWT.
plexapi.utils.choose(msg, items, attr)โ command line helper that displays a list of choices and asks the user to pick one of the options. Multiple choice but make it cute. ๐plexapi.utils.getAgentIdentifier(section, agent)โ returns the full agent identifier from a short identifier, name, or confirms a full identifier. ๐plexapi.utils.iterXMLBFS(root, tag=None)โ iterates through an XML tree using a breadth-first search. Iftagis specified, it only returns nodes with that tag. ๐ณplexapi.utils.toJson(obj, **kwargs)โ converts an object to a JSON string. โจobj(object) โ the object to convert.**kwargs(dict) โ keyword arguments to pass tojson.dumps().
plexapi.utils.sha1hash(guid)โ returns the SHA1 hash of a guid. ๐ขplexapi.utils.parseXMLString(s: str)โ parses an XML string and returns anElementTreeobject. ๐
๐ฌ VIDEO PLEXAPI.VIDEO ๐ฌ
class plexapi.video.Video(server, data, initpath=None, parent=None)- Bases:
PlexPartialObject,PlayedUnplayedMixin
- Bases:
Okay so this is THE base class for all video objects โ and when we say all, we mean Movie, Show, Season, Episode, and Clip. Every one of them is a Video girlie at heart. ๐๐ฅ
Variables โญ (the list rolls on into what's next, stay tuned bestie)
addedAt(datetime) โ when the item got added to the library ๐art(str) โ URL to the artwork image (/library/metadata/<ratingKey>/art/<artid>).artBlurHash(str) โ the BlurHash string for that artwork image โจfields(List<Field>) โ a list of field objects.guid(str) โ the Plex GUID for the movie, show, season, episode, or clip (plex://movie/5d776b59ad5437001f79c6f8).images(List<Image>) โ a list of image objects ๐key(str) โ the API URL (/library/metadata/<ratingkey>).lastRatedAt(datetime) โ when the item was last rated.lastViewedAt(datetime) โ when the item was last played.librarySectionID(int) โ the LibrarySection ID.librarySectionKey(str) โ the LibrarySection key.librarySectionTitle(str) โ the LibrarySection title.listType(str) โ hardcoded as'video'(super handy for search filters, iykyk).ratingKey(int) โ the unique key that identifies the item ๐summary(str) โ the summary of the movie, show, season, episode, or clip.thumb(str) โ URL to the thumbnail image (/library/metadata/<ratingKey>/thumb/<thumbid>).thumbBlurHash(str) โ the BlurHash string for the thumbnail image.title(str) โ the name of the movie, show, season, episode, or clip.titleSort(str) โ the title to use when sorting (defaults totitle).type(str) โ'movie','show','season','episode', or'clip'.updatedAt(datetime) โ when the item was last updated.userRating(float) โ the rating of the item (0.0-10.0), which equals (0 stars-5 stars) โญviewCount(int) โ how many times the item was played.
url(part)
Gives you back the full URL for whatever you're pointing at โ usually you're using it to grab one specific image ๐ผ๏ธ
augmentation()
Returns a list of Hub objects. Augmentation hands you back hub items tied to online media sources, like Tidal Music's "Track from {item}" or "Soundtrack of {item}". Heads up: Plex Pass and a linked Tidal account are required, no cap ๐
uploadSubtitles(filepath)
Uploads a subtitle file for the video.
Parameters
filepath(str) โ path to the subtitle file.
searchSubtitles(language='en', hearingImpaired=0, forced=0)
Searches for on-demand subtitles for the video. See โ https://support.plex.tv/articles/subtitle-search/.
Parameters
language(str, optional) โ language code (ISO 639-1) of the subtitles to search for. Default'en'.hearingImpaired(int, optional) โ search option for SDH subtitles. Default0. (0= Prefer non-SDH subtitles,1= Prefer SDH subtitles,2= Only show SDH subtitles,3= Only show non-SDH subtitles)forced(int, optional) โ search option for forced subtitles. Default0. (0= Prefer non-forced subtitles,1= Prefer forced subtitles,2= Only show forced subtitles,3= Only show non-forced subtitles)
Returns
A list of SubtitleStream objects.
Return type
List<SubtitleStream>
downloadSubtitles(subtitleStream)
Downloads on-demand subtitles for the video. See โ https://support.plex.tv/articles/subtitle-search/.
Note: this method is asynchronous and returns immediately before the subtitles are fully downloaded. So don't go looking for the file the second you call it, bestie ๐ญ
Parameters
subtitleStream(SubtitleStream) โ subtitle object returned fromsearchSubtitles().
removeSubtitles(subtitleStream=None, streamID=None, streamTitle=None)
Removes an uploaded or downloaded subtitle from the video.
Note: if the subtitle file lives inside the video directory, it will be deleted. Files outside of the video directory are not affected. Embedded subtitles cannot be removed โ periodt ๐
Parameters
subtitleStream(SubtitleStream, optional) โ subtitle object to remove.streamID(int, optional) โ ID of the subtitle stream to remove.streamTitle(str, optional) โ title of the subtitle stream to remove.
optimize(title='', target='', deviceProfile='', videoQuality=None, locationID=-1, limit=None, unwatched=False)
Makes an optimized version of the video โจ
Parameters
title(str, optional) โ title of the optimized video.target(str, optional) โ target quality profile:"Optimized for Mobile"("mobile"),"Optimized for TV"("tv"),"Original Quality"("original"), or a custom quality profile name (default"Custom: {deviceProfile}").deviceProfile(str, optional) โ custom quality device profile:"Android","iOS","Universal Mobile","Universal TV","Windows Phone","Windows","Xbox One". Required iftargetis custom.videoQuality(int, optional) โ index of the quality profile, one of theVIDEO_QUALITY_*values defined in thesyncmodule. Only used iftargetis custom.locationID(intorLocation, optional) โ defaults to-1for"In folder with original items", otherwise aLocationobject or ID. See examples below.limit(int, optional) โ maximum count of items to optimize, unlimited ifNone.unwatched(bool, optional) โTrueto only optimize unwatched videos.
Raises
BadRequestโ unknown quality profile target or missingdeviceProfileandvideoQuality.BadRequestโ unknown location ID.
Example
# Optimize for mobile using defaults
video.optimize(target="mobile")
# Optimize for Android at 10 Mbps 1080p
from plexapi.sync import VIDEO_QUALITY_10_MBPS_1080p
video.optimize(deviceProfile="Android", videoQuality=sync.VIDEO_QUALITY_10_MBPS_1080p)
# Optimize for iOS at original quality in library location
from plexapi.sync import VIDEO_QUALITY_ORIGINAL
locations = plex.library.section("Movies")._locations()
video.optimize(deviceProfile="iOS", videoQuality=VIDEO_QUALITY_ORIGINAL, locationID=locations[0])
# Optimize for tv the next 5 unwatched episodes
show.optimize(target="tv", limit=5, unwatched=True)
sync(videoQuality, client=None, clientId=None, limit=None, unwatched=False, title=None)
Adds the current video (movie, tv-show, season or episode) as a sync item for a specified device. See sync() for possible exceptions.
Parameters
videoQuality(int) โ idx of quality of the video, one of theVIDEO_QUALITY_*values defined in thesyncmodule.client(MyPlexDevice) โ sync destination, seesync().clientId(str) โ sync destination, seesync().limit(int) โ maximum count of items to sync, unlimited ifNone.unwatched(bool) โ ifTrue, watched videos wouldn't be synced.title(str) โ descriptive title for the newSyncItem; if empty, the value would be generated from the metadata of the current media.
Returns
an instance of the created syncItem.
Return type
SyncItem
๐ class plexapi.video.Movie(server, data, initpath=None, parent=None)
Bases: Video, Playable, MovieMixins
Represents a single Movie ๐ฌ main character energy fr fr
Variables
TAG(str) โ'Video'TYPE(str) โ'movie'audienceRating(float) โ audience rating (usually from Rotten Tomatoes).audienceRatingImage(str) โ key to audience rating image (rottentomatoes://image.rating.spilled).chapters(List<Chapter>) โ list of chapter objects.chapterSource(str) โ chapter source (agent;media;mixed).collections(List<Collection>) โ list of collection objects.commonSenseMedia(CommonSenseMedia) โ Common Sense Media object.contentRating(str) โ content rating (PG-13;NR;TV-G)countries(List<Country>) โ list of country objects.directors(List<Director>) โ list of director objects.duration(int) โ duration of the movie in milliseconds.editionTitle(str) โ the edition title of the movie (e.g.Director's Cut,Extended Edition, etc.).enableCreditsMarkerGeneration(int) โ setting that indicates if credits markers detection is enabled. (-1= Library default,0= Disabled)genres(List<Genre>) โ list of genre objects.guids(List<Guid>) โ list of guid objects.labels(List<Label>) โ the list of label objects, bestie ๐languageOverride(str) โ setting that says whether a language overrides the metadata (eg.en-CA,None= Library default).markers(List<Marker>) โ list of marker objects โจmedia(List<Media>) โ list of media objects, the actual files basically.originallyAvailableAt(datetime) โ the datetime the movie was released ๐originalTitle(str) โ the original title, and yes it's often the foreign one (่ปขใ;์ฝ๊ธฐ์ ์ธ ๊ทธ๋ ) โ iconic honestly.primaryExtraKey(str) โ Primary extra key (/library/metadata/66351)producers(List<Producer>) โ list of producers objects.rating(float) โ movie critic rating (7.9;9.8;8.1).ratingImage(str) โ key to the critic rating image (rottentomatoes://image.rating.rotten).ratings(List<Rating>) โ list of rating objects โญroles(List<Role>) โ list of role objects.slug(str) โ the clean watch.plex.tv URL identifier for the movie ๐ฆsimilar(List<Similar>) โ list of Similar objects.sourceURI(str) โ Remote server URI (server://<machineIdentifier>/com.plexapp.plugins.library) (remote playlist item only).studio(str) โ studio that created the movie (Di Bonaventura Pictures;21 Laps Entertainment).tagline(str) โ movie tag line (Back 2 Work;Who says men can't change?).theme(str) โ URL to the theme resource (/library/metadata/<ratingkey>/theme/<themeid>).ultraBlurColors(UltraBlurColors) โ ultra blur color object, the aesthetic one ๐useOriginalTitle(int) โ setting that indicates if the original title is used for the movie (-1= Library default,0= No,1= Yes).viewOffset(int) โ view offset in milliseconds.writers(List<Writer>) โ list of writers objects โ๏ธyear(int) โ year the movie was released.
๐ธ property actors
Alias to self.roles. same thing, different name, we love a double identity moment ๐
๐ธ property locations
Ok so real talk: this does not exist in the plex xml response, it's added here so there's a common interface for getting the locations of the movie. no cap.
Returns
List<str> of file paths where the movie is found on disk. ๐
๐ธ property hasCreditsMarker
Returns True if the movie has a credits marker. periodt.
๐ธ property hasVoiceActivity
Returns True if any of the media has voice activity analyzed ๐
๐ธ property hasPreviewThumbnails
Returns True if any of the media parts has generated preview (BIF) thumbnails ๐ฅ
๐ธ reviews()
Returns a list of Review objects.
๐ธ editions()
Returns a list of Movie objects for other editions of the same movie. yes, the director's cut girlies stay fed ๐ฌ
๐ธ removeFromContinueWatching()
Remove the movie from continue watching. bye bestie ๐
๐ธ property metadataDirectory
Returns the Plex Media Server data directory where the metadata is stored. ๐๏ธ
๐ class plexapi.video.Show(server, data, initpath=None, parent=None)
Bases: Video, ShowMixins
Represents a single Show (including all seasons and episodes). the whole era, not just one ep ๐
Variables
TAG(str) โ'Directory'TYPE(str) โ'show'audienceRating(float) โ audience rating (TMDB or TVDB).audienceRatingImage(str) โ key to the audience rating image (tmdb://image.rating).audioLanguage(str) โ setting that indicates the preferred audio language.autoDeletionItemPolicyUnwatchedLibrary(int) โ setting that indicates the number of unplayed episodes to keep for the show (0= All episodes,5= 5 latest episodes,3= 3 latest episodes,1= 1 latest episode,-3= Episodes added in the past 3 days,-7= Episodes added in the past 7 days,-30= Episodes added in the past 30 days).autoDeletionItemPolicyWatchedLibrary(int) โ setting that indicates if episodes are deleted after being watched for the show (0= Never,1= After a day,7= After a week,100= On next refresh).childCount(int) โ number of seasons (including Specials) in the show.collections(List<Collection>) โ list of collection objects.commonSenseMedia(CommonSenseMedia) โ Common Sense Media object.contentRating(str) โ Content rating (PG-13;NR;TV-G)duration(int) โ typical duration of the show episodes in milliseconds.enableCreditsMarkerGeneration(int) โ setting that indicates if credits markers detection is enabled. (-1= Library default,0= Disabled).episodeSort(int) โ setting that indicates how episodes are sorted for the show (-1= Library default,0= Oldest first,1= Newest first).flattenSeasons(int) โ setting that indicates if seasons are set to hidden for the show (-1= Library default,0= Hide,1= Show).genres(List<Genre>) โ list of genre objects.guids(List<Guid>) โ list of guid objects.index(int) โ Plex index number for the show.key(str) โ API URL (/library/metadata/<ratingkey>).labels(List<Label>) โ list of label objects ๐languageOverride(str) โ setting that indicates if a language is used to override metadata (eg.en-CA,None= Library default).leafCount(int) โ number of items in the show view.locations(List<str>) โ list of folder paths where the show is found on disk.network(str) โ the network that distributed the show ๐บoriginallyAvailableAt(datetime) โ datetime the show was released.originalTitle(str) โ the original title of the show.rating(float) โ show rating (7.9;9.8;8.1).ratings(List<Rating>) โ list of rating objects.roles(List<Role>) โ list of role objects.seasonCount(int) โ number of seasons (excluding Specials) in the show.showOrdering(str) โ setting that indicates the episode ordering for the show (None= Library default,tmdbAiring= The Movie Database (Aired),aired= TheTVDB (Aired),dvd= TheTVDB (DVD),absolute= TheTVDB (Absolute)).similar(List<Similar>) โ list of Similar objects.slug(str) โ the clean watch.plex.tv URL identifier for the show ๐ฆstudio(str) โ studio that created the show (Di Bonaventura Pictures;21 Laps Entertainment).subtitleLanguage(str) โ setting that indicates the preferred subtitle language.subtitleMode(int) โ setting that indicates the auto-select subtitle mode. (-1= Account default,0= Manually selected,1= Shown with foreign audio,2= Always enabled).tagline(str) โ show tag line.theme(str) โ URL to theme resource (/library/metadata/<ratingkey>/theme/<themeid>).ultraBlurColors(UltraBlurColors) โ ultra blur color object โจuseOriginalTitle(int) โ setting that indicates if the original title is used for the show (-1= Library default,0= No,1= Yes).viewedLeafCount(int) โ number of items marked as played in the show view.year(int) โ year the show was released.
๐ฆ property actors
Alias to self.roles. again!! same energy, different name ๐
๐ฆ property isPlayed
Returns True if the show is fully played. like, every single ep. respect.
๐ฆ onDeck()
Returns the show's On Deck Video object or None. If the show is unwatched, the return will likely be the first episode. main character energy ๐
๐ฆ season(title=None, season=None)
Returns the season with the specified title or number.
Parameters
title(str) โ title of the season to return.season(int) โ season number (default:None; required if title not specified).
Raises BadRequest โ if the title or season parameter is missing. bestie you gotta give it something ๐ญ
๐ฆ seasons(**kwargs)
Returns a list of Season objects in the show.
๐ฆ episode(title=None, season=None, episode=None)
Find an episode using a title or season and episode.
Parameters
title(str) โ title of the episode to returnseason(int) โ season number (default:None; required if title not specified).episode(int) โ episode number (default:None; required if title not specified).
Raises BadRequest โ if the title or season and episode parameters are missing.
๐ฆ episodes(**kwargs)
Returns a list of Episode objects in the show. the whole binge, unlocked ๐ฅ
๐ฆ get(title=None, season=None, episode=None)
Alias to episode(). iykyk ๐
๐ฆ watched()
Returns a list of watched Episode objects.
๐ฆ unwatched()
Returns a list of unwatched Episode objects. (me, looking at my watchlist ๐)
๐ฆ download(savepath=None, keep_original_name=False, subfolders=False, **kwargs)
Download all episodes from the show. See download() for details โ every single one, no skips ๐ซถ
Parameters
savepath(str) โ defaults to the current working dir. ๐พkeep_original_name(bool) โ passTrueto keep the original filename, otherwise a friendlier filename gets generated. slay.subfolders(bool) โTruesplits episodes into season folders. ๐๏ธ**kwargsโ extra options, and they get passed straight intogetStreamURL().
๐ธ property metadataDirectory
Returns the Plex Media Server data directory where the metadata lives. that's the spot โจ
๐ class plexapi.video.Season(server, data, initpath=None, parent=None)
Bases: Video, SeasonMixins
Represents a single Season. one season, one iconic era, no cap ๐
Variables
TAG(str) โ'Directory'TYPE(str) โ'season'audienceRating(float) โ audience rating.audioLanguage(str) โ setting that indicates the preferred audio language.collections(List<Collection>) โ list of collection objects.guids(List<Guid>) โ list of guid objects.index(int) โ season number.key(str) โ API URL (/library/metadata/<ratingkey>).labels(List<Label>) โ list of label objects.leafCount(int) โ number of items in the season view.parentGuid(str) โ Plex GUID for the show (plex://show/5d9c086fe9d5a1001f4d9fe6).parentIndex(int) โ Plex index number for the show.parentKey(str) โ API URL of the show (/library/metadata/<parentRatingKey>).parentRatingKey(int) โ unique key identifying the show.parentSlug(str) โ the cleanwatch.plex.tvURL identifier for the show.parentStudio(str) โ studio that created the show.parentTheme(str) โ URL to the show theme resource (/library/metadata/<parentRatingkey>/theme/<themeid>).parentThumb(str) โ URL to the show thumbnail image (/library/metadata/<parentRatingKey>/thumb/<thumbid>).parentTitle(str) โ name of the show for the season.rating(float) โ season rating (7.9;9.8;8.1).ratings(List<Rating>) โ list of rating objects.subtitleLanguage(str) โ setting that indicates the preferred subtitle language.subtitleMode(int) โ setting that indicates the auto-select subtitle mode:-1= Series default0= Manually selected1= Shown with foreign audio2= Always enabled
ultraBlurColors(UltraBlurColors) โ ultra blur color object. aesthetic ๐viewedLeafCount(int) โ number of items marked as played in the season view.year(int) โ year the season was released.
property isPlayed
Returns True if the season is fully played. bestie finished the whole season, respect ๐ซถ
property seasonNumber
Returns the season number.
onDeck()
Returns the season's On Deck Video object or None. Heads up: it'll only return a match if the show's On Deck episode is actually in this season. no match, no vibes ๐ญ
episode(title=None, episode=None)
Returns the episode with the given title or number.
Parameters
title(str) โ title of the episode to return.episode(int) โ episode number (default:None; required iftitlenot specified).
Raises BadRequest โ if the title or episode parameter is missing. give it something to go on ๐
episodes(**kwargs)
Returns a list of Episode objects in the season. the whole lineup โจ
get(title=None, episode=None)
Alias to episode().
show()
Return the season's Show.
watched()
Returns a list of watched Episode objects.
unwatched()
Returns a list of unwatched Episode objects. your weekend plans, lowkey ๐
download(savepath=None, keep_original_name=False, **kwargs)
Download all episodes from the season. See download() for details.
Parameters
savepath(str) โ defaults to the current working dir.keep_original_name(bool) โTrueto keep the original filename, otherwise a friendlier filename is generated.**kwargsโ additional options passed intogetStreamURL().
property metadataDirectory
Returns the Plex Media Server data directory where the metadata is stored.
๐ฆ class plexapi.video.Episode(server, data, initpath=None, parent=None)
Bases: Video, Playable, EpisodeMixins
Represents a single Episode. the main character unit of television, fr fr ๐
Variables
TAG(str) โ'Video'TYPE(str) โ'episode'audienceRating(float) โ audience rating (TMDB or TVDB).audienceRatingImage(str) โ key to the audience rating image (tmdb://image.rating).chapters(List<Chapter>) โ list of chapter objects.chapterSource(str) โ chapter source (agent;media;mixed).collections(List<Collection>) โ list of collection objects.contentRating(str) โ content rating (PG-13;NR;TV-G)directors(List<Director>) โ list of director objects.duration(int) โ duration of the episode in milliseconds.grandparentArt(str) โ URL to the show artwork (/library/metadata/<grandparentRatingKey>/art/<artid>).grandparentGuid(str) โ Plex GUID for the show (plex://show/5d9c086fe9d5a1001f4d9fe6).grandparentKey(str) โ API URL of the show (/library/metadata/<grandparentRatingKey>).grandparentRatingKey(int) โ unique key identifying the show.grandparentSlug(str) โ the cleanwatch.plex.tvURL identifier for the show.grandparentTheme(str) โ URL to the show theme resource (/library/metadata/<grandparentRatingkey>/theme/<themeid>).grandparentThumb(str) โ URL to the show thumbnail image (/library/metadata/<grandparentRatingKey>/thumb/<thumbid>).grandparentTitle(str) โ name of the show for the episode.guids(List<Guid>) โ list of guid objects.index(int) โ episode number.labels(List<Label>) โ list of label objects.markers(List<Marker>) โ list of marker objects.media(List<Media>) โ list of media objects.originallyAvailableAt(datetime) โ datetime the episode was released.parentGuid(str) โ Plex GUID for the season (plex://season/5d9c09e42df347001e3c2a72).parentIndex(int) โ season number of the episode.parentKey(str) โ API URL of the season (/library/metadata/<parentRatingKey>).parentRatingKey(int) โ unique key identifying the season.parentThumb(str) โ URL to the season thumbnail image (/library/metadata/<parentRatingKey>/thumb/<thumbid>).parentTitle(str) โ name of the season for the episode.parentYear(int) โ year the season was released.producers(List<Producer>) โ list of producer objects.rating(float) โ episode rating (7.9;9.8;8.1).ratings(List<Rating>) โ list of rating objects.roles(List<Role>) โ list of role objects.skipParent(bool) โTrueif the show's seasons are set to hidden. sneaky little setting ๐sourceURI(str) โ remote server URI (server://<machineIdentifier>/com.plexapp.plugins.library) (remote playlist item only).ultraBlurColors(UltraBlurColors) โ ultra blur color object.viewOffset(int) โ view offset in milliseconds.writers(List<Writer>) โ list of writer objects.year(int) โ year the episode was released.
property parentKey
Returns the parentKey. Refer to the Episode attributes.
property parentRatingKey
Returns the parentRatingKey. Refer to the Episode attributes.
property parentThumb
Returns the parentThumb. Refer to the Episode attributes.
property actors
Alias to self.roles. โจ the cast โจ
property locations
This does not exist in the plex xml response but is added to have a common interface to get the locations of the episode.
Returns List<str> of file paths where the episode is found on disk. found it on your drive, bestie ๐
property episodeNumber
Returns the episode number.
property seasonNumber
Returns the episode's season number.
property seasonEpisode
Returns the s00e00 string containing the season and episode numbers. this is the format, periodt ๐
property hasCommercialMarker
Returns True if the episode has a commercial marker.
property hasIntroMarker
Returns True if the episode has an intro marker. skip button who? ๐
property hasCreditsMarker
Returns True if the episode has a credits marker.
property hasVoiceActivity
Returns True if any of the media has voice activity analyzed.
property hasPreviewThumbnails
Returns True if any of the media parts has generated preview (BIF) thumbnails.
season()
Return the episode's Season.
show()
Return the episode's Show.
removeFromContinueWatching()โ takes the movie off your continue watching row, so it stops living rent-free in your "resume" shelf โจ- property
metadataDirectoryโ hands you the Plex Media Server data directory where the metadata is stored. that's it, that's the whole vibe ๐
๐ฌ class plexapi.video.Clip(server, data, initpath=None, parent=None) ๐
Bases: Video, Playable, ClipMixins
Represents a single Clip. one little snippet of video, off living its best life ๐ฆ
Variables
TAG(str) โ'Video'TYPE(str) โ'clip'duration(int) โ Duration of the clip in milliseconds.extraType(int) โ Unknown.index(int) โ Plex index number for the clip.media(List<Media>) โ List of media objects.originallyAvailableAt(datetime) โ Datetime the clip was released.skipDetails(int) โ Unknown.subtype(str) โ Type of clip (trailer,behindTheScenes,sceneOrSample, etc.).thumbAspectRatio(str) โ Aspect ratio of the thumbnail image.viewOffset(int) โ View offset in milliseconds.year(int) โ Year clip was released.
nglextraTypeandskipDetailsbeing literally labelled "Unknown" is so on brand for a media library API ๐ญ we don't know what they do either, and we're not gonna pretend ๐
- property
locationsโ okay so this one is a lil special: it does not exist in plex xml response but is added to have a common interface to get the locations of the clip. iconic workaround behavior, honestly ๐
Returns: List<str> of file paths where the clip is found on disk.
- property
metadataDirectoryโ Returns the Plex Media Server data directory where the metadata is stored. same energy, every class, we love consistency ๐ซถ
๐ class plexapi.video.Extra(server, data, initpath=None, parent=None) ๐
Bases: Clip
Represents a single Extra (trailer, behindTheScenes, etc). yes bestie, it's a Clip with a costume change โ same bones, different genre ๐
๐ธ class plexapi.video.MovieSession(server, data, initpath=None, parent=None) ๐ธ
Bases: PlexSession, Movie
Represents a single Movie session loaded from sessions(). so when someone's actively watching a movie, this is the lil object that knows about it ๐ฅ
๐ฆ class plexapi.video.EpisodeSession(server, data, initpath=None, parent=None) ๐ฆ
Bases: PlexSession, Episode
Represents a single Episode session loaded from sessions(). same deal, but make it a TV episode ๐
๐ class plexapi.video.ClipSession(server, data, initpath=None, parent=None) ๐
Bases: PlexSession, Clip
Represents a single Clip session loaded from sessions(). tiny video, full session rights ๐
โญ class plexapi.video.MovieHistory(server, data, initpath=None, parent=None) โญ
Bases: PlexHistory, Movie
Represents a single Movie history entry loaded from history(). that's the watched it already energy, not the watching it now energy ๐
๐ง class plexapi.video.EpisodeHistory(server, data, initpath=None, parent=None) ๐ง
Bases: PlexHistory, Episode
Represents a single Episode history entry loaded from history(). episode, but the past tense version โจ
๐ class plexapi.video.ClipHistory(server, data, initpath=None, parent=None) ๐
Bases: PlexHistory, Clip
Represents a single Clip history entry loaded from history(). and that rounds out the trio, we ate fr fr ๐ฅ
๐ USAGE & CONTRIBUTIONS ๐
- Source is available on the Github Project Page. go be nosy, it's encouraged ๐ซถ
- Contributors to python-plexapi own their own contributions and may distribute that code under the BSD license. yes, your code stays yours, we're not out here stealing anybody's work ๐
๐ AUTHOR ๐
M.Shepanski
๐ธ COPYRIGHT ๐ธ
2023, M.Shepanski
and that's a wrap on the whole page, bestie!! ๐ this is version 4.18.1, dated May 05, 2026 โ go forth and script your media server into submission, you absolute main character ๐
๐โจ
๐ฆ where this page comes from
- alpine 3.24: py3-plexapi-doc 4.18.1-r0 ยท BSD-3-Clause
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms