Thought I might post this here to see what interest there is to develop this API. I started it because I simply wanted a programmable way to mark a series as always watched so it wouldn't show up in my onDeck queue. After realizing there wasn't much out there for an API, I thought I would contribute. -- Let me know if there is interest, and what areas you would like to see filled out.
Currently supports Library navigation & maintenance and Client playback.
I don't support Playlists, Browsing from off site, or shared libraries yet.
# Mark All Conan (2010) Episodes Watched
from plexapi.server import PlexServer
server = PlexServer()
server.library.find('Conan (2010)').markWatched()
# Play the Movie Avatar on my iPhone
from plexapi.server import PlexServer
server = PlexServer()
avatar = server.library.section('Movies').find('Avatar')
client = server.client("Michael's iPhone")
client.playMedia(avatar)
All my other projects are on Bitbucket as well. My brain works better thinking about code in the terms Mercurial uses, so that what I went with. If it's really an issue, I could switch it. Just a personal preference; not to mention free for all my private repos.
On a side note: I noticed with the latest release of Plex Server that we can no longer hit the localhost Plex Server without first logging in. I updated the examples and tests to show how to do this.
Awesome API, I wish I had seen this before! I had to change example 7 a bit to get it to execute (added the .section() call):
# Example 7: List files for the latest episode of Friends.
the_last_one = plex.library.section('TV Shows').get('Friends').episodes()[-1]
for part in the_last_one.iter_parts():
print part.file
Because I was getting this error:
Traceback (most recent call last):
File "./testplexapi.py", line 7, in
the_last_one = plex.library.get('Friends').episodes()[-1]
File "/usr/local/lib/python2.7/dist-packages/plexapi/library.py", line 47, in get
return video.find_item(self.server, '/library/all', title)
File "/usr/local/lib/python2.7/dist-packages/plexapi/video.py", line 195, in find_item
raise NotFound('Unable to find title: %s' % title)
Going off of what Dane touched on, I'd definitely be willing to contribute to this API if it was publicly hosted on Github.
Awesome API, I wish I had seen this before! I had to change example 7 a bit to get it to execute (added the .section() call):
Thanks for the report, I'll take a look at it tonight and fix. It should work both with and without the section('TV Shows') part, perhaps you have an item in another section titled "Friends" as well and it got confused?
Going off of what Dane touched on, I'd definitely be willing to contribute to this API if it was publicly hosted on Github.
I find it interesting that this is the common mentality. It feels like a turf war when people see I'm using BitBucket (not just you two, I never hear the end of it from pretty much everyone). Isn't it 99% identical once you clone the repo to your local machine? You and Dane convinced me. I'll switch someday in the near future simply for the fact that its not a fight I find worth fighting. I just preferred the ability to make my repos private, a feature I'll evidently lose.
It should work both with and without the section('TV Shows') part, perhaps you have an item in another section titled "Friends" as well and it got confused?
It doesn't work with the section('TV Shows) bit for me because I have movies with the word "Friends" in them. This returns multiple results in the call to .search() and calling .get() returns a NotFound exception when in reality, it found multiple results. I haven't looked into it much more than that, I just thought I'd report that one of the examples wasn't working for me and was returning a misleading exception.
I find it interesting that this is the common mentality. It feels like a turf war when people see I'm using BitBucket (not just you two, I never hear the end of it from pretty much everyone). Isn't it 99% identical once you clone the repo to your local machine? You and Dane convinced me. I'll switch someday in the near future simply for the fact that its not a fight I find worth fighting. I just preferred the ability to make my repos private, a feature I'll evidently lose.
Heh, turf war indeed. People get touchy about this topic but I'll say that I personally like being able to have private repos so I have a BitBucket for personal use and I have a few GitHub accounts for things that are going to be publicly available or that are going to be contributed to by others. The primary reason that I wanted a Python Plex API on GitHub is because I wanted to contribute to it, but the secondary reason is because virtually all Plex code is on GitHub.
Just looking for a handy way to access the plex API easily. Hope you continue working on this! the ability to control clients easily is very useful (Know its a bit late, but hoping for a future update!) Specifically playing trailers/extras on clients as i currently can't find a way to do this
Excellent job. Examples are really straight forward.
Will use the part to check “watched” status from an agent (if i can) so i can sync with Simkl api.
PKKid,
I just came across this API. Very interesting. I’ve been wanting to use an API call to my plex server and a player to start a music playlist as an alarm clock. It has been pretty straight forward although I have one problem. When I try to set client parameters I get an exception. Strangely I see the volume on the client go to 100% although it does not shuffle the playlist. Right now I just ignore the exception and play but it does not shuffle. I’m a bit new to python coming from java so I may be doing something dumb.
-- snip --
#!/usr/local/bin/python
from plexapi.server import PlexServer
from plexapi.playqueue import PlayQueue
from plexapi.playlist import Playlist
baseurl = 'http://myserver:32400'
token = 'T0k3n!@#!@#$#!@!$#'
plex = PlexServer(baseurl, token)
client = plex.client("Android Player")
for playlist in plex.playlists():
if playlist.title == "Oldies":
print ("Play this one")
try:
client.setParameters(100, 1, 1, 'music')
except:
pass
client.playMedia(playlist)
-- snip --
$ python test.py
Play this one
Traceback (most recent call last):
File “test.py”, line 20, in
client.playMedia(playlist)
File “/usr/local/lib/python2.7/site-packages/plexapi/client.py”, line 154, in playMedia
}, **params))
File “/usr/local/lib/python2.7/site-packages/plexapi/client.py”, line 85, in sendCommand
return self.query(path, headers=headers)
File “/usr/local/lib/python2.7/site-packages/plexapi/client.py”, line 71, in query
return ElementTree.fromstring(data) if data else None
File “/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/etree/ElementTree.py”, line 1300, in XML
parser.feed(text)
File “/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/etree/ElementTree.py”, line 1642, in feed
self._raiseerror(v)
File “/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xml/etree/ElementTree.py”, line 1506, in _raiseerror
raise err
xml.etree.ElementTree.ParseError: syntax error: line 1, column 0