+# encoding: utf-8
+from __future__ import unicode_literals
+
try:
import urllib.request as urllib_request
import urllib.error as urllib_error
class _DEFAULT(object):
pass
+
class TwitterError(Exception):
"""
Base Exception thrown by the Twitter object when there is a
"""
pass
+
class TwitterHTTPError(TwitterError):
"""
Exception thrown by the Twitter object when there is an
fmt = ("." + self.format) if self.format else ""
return (
"Twitter sent status %i for URL: %s%s using parameters: "
- "(%s)\ndetails: %s" %(
+ "(%s)\ndetails: %s" % (
self.e.code, self.uri, fmt, self.uriparts,
self.response_data))
+
class TwitterResponse(object):
"""
Response from a twitter request. Behaves like a list or a string
class TwitterCall(object):
def __init__(
- self, auth, format, domain, callable_cls, uri="",
- uriparts=None, secure=True, timeout=None, gzip=False):
+ self, auth, format, domain, callable_cls, uri="",
+ uriparts=None, secure=True, timeout=None, gzip=False):
self.auth = auth
self.format = format
self.domain = domain
# the list of uriparts, assume the id goes at the end.
id = kwargs.pop('id', None)
if id:
- uri += "/%s" %(id)
+ uri += "/%s" % (id)
# If an _id kwarg is present, this is treated as id as a CGI
# param.
dot = ""
if self.format:
dot = "."
- uriBase = "http%s://%s/%s%s%s" %(
- secure_str, self.domain, uri, dot, self.format)
+ uriBase = "http%s://%s/%s%s%s" % (
+ secure_str, self.domain, uri, dot, self.format)
# Catch media arguments to handle oauth query differently for multipart
media = None
for arg in ['media[]', 'banner', 'image']:
if arg in kwargs:
media = kwargs.pop(arg)
+ # Check if argument tells whether img is already base64 encoded
+ b64_convert = True
+ if "_base64" in kwargs:
+ b64_convert = not kwargs.pop("_base64")
+ if b64_convert:
+ import base64
+ media = base64.b64encode(media)
mediafield = arg
break
headers = {'Accept-Encoding': 'gzip'} if self.gzip else dict()
- body = None; arg_data = None
+ body = None
+ arg_data = None
if self.auth:
headers.update(self.auth.generate_headers())
# Use urlencoded oauth args with no params when sending media
# via multipart and send it directly via uri even for post
- arg_data = self.auth.encode_params(uriBase, method,
- {} if media else kwargs )
+ arg_data = self.auth.encode_params(
+ uriBase, method, {} if media else kwargs)
if method == 'GET' or media:
uriBase += '?' + arg_data
else:
BOUNDARY = "###Python-Twitter###"
bod = []
bod.append('--' + BOUNDARY)
- bod.append('Content-Disposition: form-data; name="%s"' %
- mediafield)
+ bod.append(
+ 'Content-Disposition: form-data; name="%s"' % mediafield)
+ bod.append('Content-Transfer-Encoding: base64')
bod.append('')
bod.append(media)
for k, v in kwargs.items():
bod.append(v)
bod.append('--' + BOUNDARY + '--')
body = '\r\n'.join(bod)
- headers['Content-Type'] = 'multipart/form-data; boundary=%s' % BOUNDARY
+ headers['Content-Type'] = \
+ 'multipart/form-data; boundary=%s' % BOUNDARY
req = urllib_request.Request(uriBase, body, headers)
return self._handle_response(req, uri, arg_data, _timeout)
else:
raise TwitterHTTPError(e, uri, self.format, arg_data)
+
class Twitter(TwitterCall):
"""
The minimalist yet fully featured Twitter API class.
screen_name=','.join(A_LIST_OF_100_SCREEN_NAMES), \
_timeout=1)
+ # Overriding Method: GET/POST
+ # you should not need to use this method as this library properly
+ # detects whether GET or POST should be used, Nevertheless
+ # to force a particular method, use `_method`
+ t.statuses.oembed(_id=1234567890, _method='GET')
+
+ # Send a tweet with an image included (or set your banner or logo similarily)
+ # By just reading your image from the web or a file in a string:
+ with open("example.png", "rb") as imagefile:
+ params = {"media[]": imagefile.read(), "status": "PTT"}
+ t.statuses.update_with_media(**params)
+ # Or by sending a base64 encoded image:
+ params = {"media[]": base64_image, "status": "PTT", "_base64": True}
+ t.statuses.update_with_media(**params)
+
Searching Twitter::
"""
def __init__(
- self, format="json",
- domain="api.twitter.com", secure=True, auth=None,
- api_version=_DEFAULT):
+ self, format="json",
+ domain="api.twitter.com", secure=True, auth=None,
+ api_version=_DEFAULT):
"""
Create a new twitter API connector.
`domain` lets you change the domain you are connecting. By
- default it's `api.twitter.com` but `search.twitter.com` may be
- useful too.
+ default it's `api.twitter.com`.
If `secure` is False you will connect with HTTP instead of
HTTPS.
`api_version` is used to set the base uri. By default it's
- '1'. If you are using "search.twitter.com" set this to None.
+ '1.1'.
"""
if not auth:
auth = NoAuth()
if (format not in ("json", "xml", "")):
- raise ValueError("Unknown data format '%s'" %(format))
+ raise ValueError("Unknown data format '%s'" % (format))
if api_version is _DEFAULT:
api_version = '1.1'