pytwitcherapi¶





This project is not developed anymore!
Twitch is a trademark or registered trademark of Twitch Interactive, Inc. in the U.S. and/or other countries. “pytwitcher” and “pytwitcherapi” is not operated by, sponsored by, or affiliated with Twitch Interactive, Inc. in any way.
Python API for interacting with twitch.tv.
Features¶
- Easy-to-use object oriented high-level API
- Search and query information about games, channels, streams and users
- Get the livestream playlist
- OAauth Authentication. Can retrieve followed streams and more...
- Good documentation and test coverage
- IRC client for the chat (with IRC v3 tag support)
Welcome to pytwitcherapi‘s documentation!¶
Contents:¶
Installation¶
At the command line either via easy_install or pip:
$ easy_install pytwitcherapi
$ pip install pytwitcherapi
Or, if you have virtualenvwrapper installed:
$ mkvirtualenv pytwitcherapi
$ pip install pytwitcherapi
Usage¶
This is a litte quickstart guide. For more information go to the Usermanual.
API requests¶
pytwitcherapi.TwitchSession
class is the central class for interacting with twitch.tv:
1 2 3 | import pytwitcherapi
ts = pytwitcherapi.TwitchSession()
|
To query all top games use:
5 | topgames = ts.top_games()
|
Get streams and playlist for every game:
7 8 9 10 11 | for game in topgames:
streams = ts.get_streams(game=game)
for stream in streams:
channel = stream.channel
playlist = ts.get_playlist(channel)
|
As you can see games, channels, streams are wrapped into objects.
See pytwitcherapi.Game
, pytwitcherapi.Channel
, pytwitcherapi.Stream
, pytwitcherapi.User
.
You can use your own Client-ID
for twitch by setting the environment variable PYTWITCHER_CLIENT_ID
.
Usermanual¶
In here you find help for using the pytwitcherapi. There are also some simple examples.
Requests¶
API requests¶
pytwitcherapi.TwitchSession
class is the central class for interacting with twitch.tv:
1 2 3 | import pytwitcherapi
ts = pytwitcherapi.TwitchSession()
|
To query all top games use:
5 | topgames = ts.top_games()
|
Get streams and playlist for every game:
7 8 9 10 11 | for game in topgames:
streams = ts.get_streams(game=game)
for stream in streams:
channel = stream.channel
playlist = ts.get_playlist(channel)
|
As you can see games, channels, streams are wrapped into objects.
See pytwitcherapi.Game
, pytwitcherapi.Channel
, pytwitcherapi.Stream
, pytwitcherapi.User
.
You can use your own Client-ID
for twitch by setting the environment variable PYTWITCHER_CLIENT_ID
.
Custom requests¶
You can also issue custom requests. The pytwitcherapi.TwitchSession
is actually a subclass of requests.Session
. So basically
you can use pytwitcherapi.TwitchSession.request()
to issue
arbitrary requests.
To make it easier to use the different twitch APIs there are a few helpers.
You can get easy access to three different twitch APIs:
- Kraken API witch uses
pytwitcherapi.session.TWITCH_KRAKENURL
. Usepytwitcherapi.session.TwitchSession.kraken_request()
.- Usher API with uses
pytwitcherapi.session.TWITCH_USHERURL
. Usepytwitcherapi.session.TwitchSession.usher_request()
.- The old twitch API
pytwitcherapi.session.TWITCH_APIURL
. Usepytwitcherapi.session.TwitchSession.oldapi_request()
.
1 2 3 4 5 6 7 8 9 10 11 | import pytwitcherapi
ts = pytwitcherapi.TwitchSession()
topgames = ts.top_games()
for game in topgames:
streams = ts.get_streams(game=game)
for stream in streams:
channel = stream.channel
playlist = ts.get_playlist(channel)
|
Authentication¶
For some methods of pytwitcherapi.TwitchSession
, the user needs to grant pytwitcher authorization.
Twitch Authentication is based on OAuth.
We use the implicit grant workflow.
In short, the user visits a website. Has to login, and allow pytwitcher. Twitch will redirect him to pytwitcherapi.constants.REDIRECT_URI
.
In the url fragment of that redirection, one can find the token we need.
To make it simple for the user, here is what should be done for authentication:
Call
pytwitcherapi.TwitchSession.start_login_server()
. This will create a thread that serves a server onpytwitcherapi.constants.LOGIN_SERVER_ADRESS
. Once the user gets redirected, this server will pick up the request and extract the token:
1 2 3 4 import pytwitcherapi ts = pytwitcherapi.TwitchSession() ts.start_login_server()Get the url
pytwitcherapi.TwitchSession.get_auth_url()
and send the user to visit that url in his favorite webbrowser. He might have to login, and allow pytwitcher, if he did not already:
6 7 8 import webbrowser url = ts.get_auth_url() webbrowser.open(url)Wait until the user finished login in. Then call
pytwitcherapi.TwitchSession.shutdown_login_server()
to shutdown the server and join the thread:
10 11 raw_input("Press ENTER when finished") ts.shutdown_login_server()Check if the user authorized the session with
pytwitcherapi.TwitchSession.authorized()
:
13 14 assert ts.authorized, "Authorization failed! Did the user allow it?" print "Login User: %s" % ts.current_userNow you can call methods that require authentication:
16 streams = ts.followed_streams()
Chat¶
The twitch chat is based on the IRC protocol RFC1459. The official documentation on the twitch chat is here: Twitch IRC Doc. The irc python lib might also be useful, because we use it as backend.
pytwitcherapi.IRCClient
is a simple client, which can only connect to one channel/server at a time.
When building applications, you probably wanna run the IRCClient in another thread, so it doesn’t block your application.
The client is thread safe and has quite a few methods to send IRC commands, if the client is running in another thread.
They are wrapped versions of methods from irc.client.ServerConnection
. E.g. you can simply call pytwitcherapi.IRCClient.quit()
from another thread. Here is a simple example, where we send messages to the channel.
Change input
to raw_input
for python 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import threading
import pytwitcherapi
session = ... # we assume an authenticated TwitchSession
channel = session.get_channel('somechannel')
client = pytwitcherapi.IRCClient(session, channel)
t = threading.Thread(target=client.process_forever)
t.start()
try:
while True:
m = input('Send Message:')
if not m: break;
# will be processed in other thread
# sends a message to the server
client.send_msg(m)
finally:
client.shutdown()
t.join()
|
Important
The connection will wait/block if you send more messages than
twitch allows. See pytwitcherapi.chat.ServerConnection3
.
You can make the client handle different IRC events. Subclass the client and create a method on_<eventtype>
.
For example to greet everyone who joins an IRC channel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import pytwitcherapi
class MyIRCClient(pytwitcherapi.IRCClient):
def on_join(self, connection, event):
"""Handles the join event and greets everone
:param connection: the connection with the event
:type connection: :class:`irc.client.ServerConnection`
:param event: the event to handle
:type event: :class:`irc.client.Event`
:returns: None
"""
target = event.source
self.privmsg(target, 'Hello %s!' % target)
|
If you override pytwitcherapi.IRCClient.on_pubmsg()
or pytwitcherapi.IRCClient.on_privmsg()
make sure to call
the super method:
1 2 3 4 5 6 7 8 | from pytwitcherapi import chat
class MyIRCClient(pytwitcherapi.IRCClient):
def on_privmsg(self, connection, event):
super(MyIRCClient, self).on_privmsg(connection, event)
print chat.Message3.from_event(event)
|
But printing out messages is not really useful. You probably want to access them in another thread.
All private and public messages are stored in a thread safe message queue. By default the queue stores the last 100 messages.
You can alter the queuesize when creating a client. 0
will make the queue store all messages.
Note
The Client is using two connections. One for sending messages (pytwitcherapi.IRCClient.in_connection
) and
one for receiving (pytwitcherapi.IRCClient.in_connection
) them.
With one message, you wouldn’t revceive your own messages processed from the server (with tags).
Here is a little example. To quit press CTRL-C
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import threading
import queue # Queue for python 2
import pytwitcherapi
session = ... # we assume an authenticated TwitchSession
channel = session.get_channel('somechannel')
client = pytwitcherapi.IRCClient(session, channel, queuesize=0)
t = threading.Thread(target=client.process_forever)
t.start()
try:
while True:
try:
m = client.messages.get(block=False)
except queue.Empty:
pass
else:
# Now you have the message in the main thread
# and can display the message in the
# GUI or wherever you want
print "Message from %s to %s: %s" % (m.source, m.target, m.text)
finally:
client.shutdown()
t.join()
|
Tags and metadata¶
Twitch does support tags.
Tags store metadata about a message, like the color of the user,
whether he is a subscriber, the pytwichterapi.chat.Emote
etc.
These messages get safed id the message queue: pytwitcherapi.IRCClient.messages
.
See the pytwitcherapi.chat.Message3
documentation for the additional metadata.
Here is a little example. To quit press CTRL-C
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import threading
import queue # Queue for python 2
import pytwitcherapi
session = ... # we assume an authenticated TwitchSession
channel = session.get_channel('somechannel')
client = pytwitcherapi.IRCClient(session, channel, queuesize=0)
t = threading.Thread(target=client.process_forever)
t.start()
try:
while True:
try:
m = client.messages.get(block=False)
except queue.Empty:
pass
else:
print m.color
print m.subscriber
print m.turbo
print m.emotes
print m.user_type
finally:
client.shutdown()
t.join()
|
Developer’s Documentation¶
Welcome to the developer’s documenation. All necessary information for contributors who want to extend the project.
Documentation¶
Build¶
To build the documentation locally, follow these instructions:
Go to the root directory of this project.
Install the requirements:
$ pip install -r docs/requirements.txt
This will install sphinx, some required packages and the project in development mode (
pip install -e .
). That’s why you have to be in the root dir.Go to the docs dir:
$ cd docs
Invoke sphinx build:
$ sphinx-build -b html -d _build/doctrees source _build/html
or alternativly with make:
$ make html
on windows:
$ make.bat html
Reference¶
Automatic generated Documenation by apidoc and autodoc.
pytwitcherapi
¶
Subpackages¶
pytwitcherapi.chat
¶
pytwitcherapi.chat.client
¶IRC client for interacting with the chat of a channel.
ChatServerStatus (server[, ip, port, status, ...]) |
Useful for comparing the performance of servers. |
IRCClient (session, channel[, queuesize]) |
Simple IRC client which can connect to a single pytwitcherapi.Channel . |
Reactor ([on_connect, on_disconnect]) |
Reactor that can exit the process_forever loop. |
Reactor3 ([on_connect, on_disconnect]) |
Reactor that uses irc v3 connections |
add_serverconnection_methods (cls) |
Add a bunch of methods to an irc.client.SimpleIRCClient to send commands and messages. |
absolute_import |
|
log |
Instances of the Logger class represent a single logging channel. |
-
pytwitcherapi.chat.client.
add_serverconnection_methods
(cls)[source]¶ Add a bunch of methods to an
irc.client.SimpleIRCClient
to send commands and messages.Basically it wraps a bunch of methdos from
irc.client.ServerConnection
to beirc.schedule.IScheduler.execute_after()
. That way, you can easily send, even if the IRCClient is running inIRCClient.process_forever
in another thread.On the plus side you can use positional and keyword arguments instead of just positional ones.
Parameters: cls ( irc.client.SimpleIRCClient
) – The class to add the methods do.Returns: None
-
pytwitcherapi.chat.client.
absolute_import
= _Feature((2, 5, 0, 'alpha', 1), (3, 0, 0, 'alpha', 0), 16384)¶
-
pytwitcherapi.chat.client.
log
= <logging.Logger object>[source]¶ Instances of the Logger class represent a single logging channel. A “logging channel” indicates an area of an application. Exactly how an “area” is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of “input processing” might include sub-areas “read CSV files”, “read XLS files” and “read Gnumeric files”). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be “input” for the upper level, and “input.csv”, “input.xls” and “input.gnu” for the sub-levels. There is no arbitrary limit to the depth of nesting.
pytwitcherapi.chat.connection
¶Event3 (type, source, target[, arguments, tags]) |
An IRC event with tags |
ServerConnection3 (reactor[, msglimit, ...]) |
ServerConncetion that can handle irc v3 tags |
log |
Instances of the Logger class represent a single logging channel. |
-
pytwitcherapi.chat.connection.
log
= <logging.Logger object>[source]¶ Instances of the Logger class represent a single logging channel. A “logging channel” indicates an area of an application. Exactly how an “area” is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of “input processing” might include sub-areas “read CSV files”, “read XLS files” and “read Gnumeric files”). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be “input” for the upper level, and “input.csv”, “input.xls” and “input.gnu” for the sub-levels. There is no arbitrary limit to the depth of nesting.
Package for interacting with the IRC chat of a channel.
The main client for connecting to the channel is IRCClient
.
IRCClient (session, channel[, queuesize]) |
Simple IRC client which can connect to a single pytwitcherapi.Channel . |
absolute_import |
-
pytwitcherapi.chat.
absolute_import
= _Feature((2, 5, 0, 'alpha', 1), (3, 0, 0, 'alpha', 0), 16384)¶
Submodules¶
pytwitcherapi.constants
¶
Collection of constants
These constants might be needed in multiple modules, so we pull them together here.
LOGIN_SERVER_ADRESS |
Server adress of server that catches the redirection and the oauth token. |
REDIRECT_URI |
The redirect url of pytwitcher. |
-
pytwitcherapi.constants.
LOGIN_SERVER_ADRESS
= ('', 42420)¶ Server adress of server that catches the redirection and the oauth token.
-
pytwitcherapi.constants.
REDIRECT_URI
= 'http://localhost:42420'¶ The redirect url of pytwitcher. We do not need to redirect anywhere so localhost is set in the twitch prefrences of pytwitcher
pytwitcherapi.exceptions
¶
Collection exceptions
NotAuthorizedError |
Exception that is raised, when the session is not authorized. |
PytwitcherException |
Base exception for pytwitcher |
pytwitcherapi.models
¶
Contains classes that wrap the jsons returned by the twitch.tv API
pytwitcherapi.oauth
¶
Twitch.tv uses OAuth2 for authorization.
We use the Implicit Grant Workflow.
The user has to visit an authorization site, login, authorize
PyTwitcher. Once he allows PyTwitcher, twitch will redirect him to
pytwitcherapi.REDIRECT_URI
.
In the url fragment, there is the access token.
This module features a server, that will respond to the redirection of
the user. So if twitch is redirecting to pytwitcherapi.REDIRECT_URI
,
the server is gonna send a website, which will extract the access token,
send it as a post request and give the user a response,
that everything worked.
LoginServer (session) |
This server responds to the redirection of the user after he granted authorization. |
RedirectHandler (request, client_address, server) |
This request handler will handle the redirection of the user when he grants authorization to PyTwitcher and twitch redirects him. |
TwitchOAuthClient (client_id[, ...]) |
This is a client needed for oauthlib.oauth2.OAuth2Session . |
log |
Instances of the Logger class represent a single logging channel. |
-
pytwitcherapi.oauth.
log
= <logging.Logger object>[source]¶ Instances of the Logger class represent a single logging channel. A “logging channel” indicates an area of an application. Exactly how an “area” is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of “input processing” might include sub-areas “read CSV files”, “read XLS files” and “read Gnumeric files”). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be “input” for the upper level, and “input.csv”, “input.xls” and “input.gnu” for the sub-levels. There is no arbitrary limit to the depth of nesting.
pytwitcherapi.session
¶
API for communicating with twitch
OAuthSession () |
Session with oauth2 support. |
TwitchSession () |
Session for making requests to the twitch api |
needs_auth (meth) |
Wraps a method of TwitchSession and raises an exceptions.NotAuthorizedError if before calling the method, the session isn’t authorized. |
AUTHORIZATION_BASE_URL |
Authorisation Endpoint |
CLIENT_ID |
The client id of pytwitcher on twitch. |
SCOPES |
The scopes that PyTwitcher needs |
TWITCH_APIURL |
The baseurl for the old twitch api |
TWITCH_HEADER_ACCEPT |
The header for the Accept key to tell twitch which api version it should use |
TWITCH_KRAKENURL |
The baseurl for the twitch api |
TWITCH_STATUSURL |
str(object=’‘) -> string |
TWITCH_USHERURL |
The baseurl for the twitch usher api |
absolute_import |
|
log |
Instances of the Logger class represent a single logging channel. |
-
pytwitcherapi.session.
needs_auth
(meth)[source]¶ Wraps a method of
TwitchSession
and raises anexceptions.NotAuthorizedError
if before calling the method, the session isn’t authorized.Parameters: meth – Returns: the wrapped method Return type: Method Raises: None
-
pytwitcherapi.session.
AUTHORIZATION_BASE_URL
= 'https://api.twitch.tv/kraken/oauth2/authorize'¶ Authorisation Endpoint
-
pytwitcherapi.session.
CLIENT_ID
= '642a2vtmqfumca8hmfcpkosxlkmqifb'¶ The client id of pytwitcher on twitch. Use environment variable
PYTWITCHER_CLIENT_ID
or pytwitcher default value.
-
pytwitcherapi.session.
SCOPES
= ['user_read', 'chat_login']¶ The scopes that PyTwitcher needs
-
pytwitcherapi.session.
TWITCH_APIURL
= 'http://api.twitch.tv/api/'¶ The baseurl for the old twitch api
-
pytwitcherapi.session.
TWITCH_HEADER_ACCEPT
= 'application/vnd.twitchtv.v3+json'¶ The header for the
Accept
key to tell twitch which api version it should use
-
pytwitcherapi.session.
TWITCH_KRAKENURL
= 'https://api.twitch.tv/kraken/'¶ The baseurl for the twitch api
-
pytwitcherapi.session.
TWITCH_STATUSURL
= 'http://twitchstatus.com/api/status?type=chat'¶ str(object=’‘) -> string
Return a nice string representation of the object. If the argument is a string, the return value is the same object.
-
pytwitcherapi.session.
TWITCH_USHERURL
= 'http://usher.twitch.tv/api/'¶ The baseurl for the twitch usher api
-
pytwitcherapi.session.
absolute_import
= _Feature((2, 5, 0, 'alpha', 1), (3, 0, 0, 'alpha', 0), 16384)¶
-
pytwitcherapi.session.
log
= <logging.Logger object>[source]¶ Instances of the Logger class represent a single logging channel. A “logging channel” indicates an area of an application. Exactly how an “area” is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of “input processing” might include sub-areas “read CSV files”, “read XLS files” and “read Gnumeric files”). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be “input” for the upper level, and “input.csv”, “input.xls” and “input.gnu” for the sub-levels. There is no arbitrary limit to the depth of nesting.
Module contents¶
Data¶
absolute_import |
-
pytwitcherapi.
absolute_import
= _Feature((2, 5, 0, 'alpha', 1), (3, 0, 0, 'alpha', 0), 16384)¶
Contributing¶
Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.
You can contribute in many ways:
Types of Contributions¶
Report Bugs¶
Report bugs at https://github.com/Pytwitcher/pytwitcherapi/issues.
If you are reporting a bug, please include:
- Your operating system name and version.
- Any details about your local setup that might be helpful in troubleshooting.
- Detailed steps to reproduce the bug.
Fix Bugs¶
Look through the GitHub issues for bugs. Anything tagged with “bug” is open to whoever wants to implement it.
Implement Features¶
Look through the GitHub issues for features. Anything tagged with “feature” is open to whoever wants to implement it.
Write Documentation¶
pytwitcherapi could always use more documentation, whether as part of the official pytwitcherapi docs, in docstrings, or even on the web in blog posts, articles, and such.
Submit Feedback¶
The best way to send feedback is to file an issue at https://github.com/Pytwitcher/pytwitcherapi/issues.
If you are proposing a feature:
- Explain in detail how it would work.
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that this is a volunteer-driven project, and that contributions are welcome :)
Get Started!¶
Ready to contribute? Here’s how to set up pytwitcherapi for local development.
Fork the pytwitcherapi repo on GitHub.
Clone your fork locally:
$ git clone git@github.com:your_name_here/pytwitcherapi.git
Create a branch for local development:
$ git checkout -b name-of-your-bugfix-or-feature
Now you can make your changes locally.
When you’re done making changes, check that your changes pass style and unit tests, including testing other Python versions with tox:
$ tox
To get tox, just pip install it.
Commit your changes and push your branch to GitHub:
$ git add . $ git commit -m "Your detailed description of your changes." $ git push origin name-of-your-bugfix-or-feature
Submit a pull request through the GitHub website.
Pull Request Guidelines¶
Before you submit a pull request, check that it meets these guidelines:
- The pull request should include tests.
- If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst.
- The pull request should work for Python 2.6, 2.7, and 3.3, and for PyPy.
Check https://travis-ci.org/Pytwitcher/pytwitcherapi
under pull requests for active pull requests or run the
tox
command and make sure that the tests pass for all supported Python versions.
History¶
0.1.1 (2015-03-15)¶
- First release on PyPI.
- Pulled pytwitcherapi out of main project pytwitcher
0.1.2 (2015-03-15)¶
- Fix wrapping search stream results due to incomplete channel json
0.1.3 (2015-03-23)¶
- Refactor twitch module into models and session module
0.1.4 (2015-03-23)¶
- Fix wrap json using actual class instead of cls
0.2.0 (2015-04-12)¶
- Authentication: User can login and TwitchSession can retrieve followed streams.
0.3.0 (2015-05-08)¶
- Easier imports. Only import the package for most of the cases.
- Added logging. Configure your logger and pytwitcher will show debug messages.
0.3.1 (2015-05-09)¶
- Fix login server shutdown by correctly closing the socket
0.4.0 (2015-05-12)¶
- IRC client for twitch chat
0.5.0 (2015-05-13)¶
- IRC v3 Tags for messages
0.5.1 (2015-05-13)¶
- Fix coverage reports via travis
0.6.0 (2015-05-16)¶
- Add limit for sending messages
0.7.0 (2015-05-16)¶
- IRCCLient manages two connections. Receives own messages from the server (with tags).
- Improved test thread saftey
0.7.1 (2015-05-22)¶
- IRCClient shutdown is now thread-safe through events
0.7.2 (2015-05-30)¶
- Add TwitchSession.get_emote_picture(emote, size).
- Capabilities for chat: twitch.tv/membership, twitch.tv/commands, twitch.tv/tags
0.8.0 (2015-05-31)¶
- Replace context managers for apis with dedicated methods. The context managers made it difficult to use a session thread-safe because they relied (more heavily) on the state of the session.
0.9.0 (2016-09-16)¶
0.9.1 (2016-09-18)¶
- Make example chat client python 3 compatible
- #16: Ignore unknown arguments from twitchstatus
- Use Client ID for old api requests as well
0.9.3 (2017-08-27)¶
- Re-release of
0.9.2
Feedback¶
If you have any suggestions or questions about pytwitcherapi feel free to email me at zuber.david@gmx.de.
If you encounter any errors or problems with pytwitcherapi, please let me know! Open an Issue at the GitHub https://github.com/Pytwitcher/pytwitcherapi main repository.