get_authorization_url() now takes a boolean that when
true uses the "sign in with twitter" flow.
See http://apiwiki.twitter.com/Sign-in-with-Twitter
++ Logging
+ + Added TweepyLogger interface which allows applications
+ to collect log messages from Tweepy for debugging purposes.
+ + Dummy, console, and file loggers available
+ Examples
+ Appengine demo (oauth)
+ Documentation of each method in api.py
from . cache import Cache, MemoryCache, FileCache, MemCache
from . auth import BasicAuthHandler, OAuthHandler
from . streaming import Stream, StreamListener
+from . logging import TweepyLogger, DummyLogger, ConsoleLogger, FileLogger
# Global, unauthenticated instance of API
api = API()
from . binder import bind_api
from . error import TweepError
from . auth import BasicAuthHandler, OAuthHandler
+from . logging import DummyLogger
from tweepy.parsers import *
"""Twitter API"""
def __init__(self, auth_handler=None, host='twitter.com', cache=None,
- secure=False, api_root='', validate=True):
+ secure=False, api_root='', validate=True, logger=DummyLogger()):
# you may access these freely
self.auth_handler = auth_handler
self.host = host
self.cache = cache
self.secure = secure
self.validate = validate
+ self.logger = logger
# not a good idea to touch these
self._username = None
if require_auth and not api.auth_handler:
raise TweepError('Authentication required!')
+ # Log some useful infomation
+ api.logger.debug('Starting request...')
+ api.logger.debug(' path: %s' % path)
+ api.logger.debug(' method: %s' % method)
+
# check for post_data parameter
if 'post_data' in kargs:
post_data = kargs['post_data']
del kargs['post_data']
+ api.logger.debug(' post data: %s' % post_data)
else:
post_data = None
del kargs['headers']
else:
headers = {}
+ api.logger.debug(' headers: %s' % headers)
# build parameter dict
if allowed_param:
if len(args) > 0 or len(kargs) > 0:
raise TweepError('This method takes no parameters!')
parameters = None
+ api.logger.debug(' parameters: %s' % parameters)
# Build url with parameters
if parameters:
# Apply authentication
if api.auth_handler:
- api.auth_handler.apply_auth(scheme + _host + url, method, headers, parameters)
+ api.auth_handler.apply_auth(
+ scheme + _host + url,
+ method, headers, parameters
+ )
# Check cache if caching enabled and method is GET
if api.cache and method == 'GET':
result._api = api
else:
cache_result._api = api
+ api.logger.debug("Cache hit!")
return cache_result
# Open connection
# Get response
resp = conn.getresponse()
+ api.logger.debug('Received response...')
+ api.logger.debug(' headers: %s' % resp.getheaders())
+ api.logger.debug(' status code: %s' % resp.status)
# If an error was returned, throw an exception
if resp.status != 200:
error_msg = parse_error(resp.read())
except Exception:
error_msg = "Twitter error response: status code = %s" % resp.status
+ api.logger.error(' Error: %s' % error_msg)
raise TweepError(error_msg)
# Pass returned body into parser and return parser output
try:
out = parser(resp.read(), api)
except Exception:
+ api.logger.error(" parse error!")
raise TweepError("Failed to parse returned data")
conn.close()
# store result in cache
if api.cache and method == 'GET':
api.cache.store(url, out)
+ api.logger.debug(" caching result")
+
+ api.logger.debug('request done.')
return out
--- /dev/null
+# Tweepy
+# Copyright 2009 Joshua Roesslein
+# See LICENSE
+
+class TweepyLogger(object):
+
+ DEBUG = 1
+ WARNING = 2
+ ERROR = 3
+
+ def debug(self, message):
+ """Output a debug log message"""
+ self.log(TweepyLogger.DEBUG, message)
+
+ def warning(self, message):
+ """Output warning log message"""
+ self.log(TweepyLogger.WARNING, message)
+
+ def error(self, message):
+ """Output error log message"""
+ self.log(TweepyLogger.ERROR, message)
+
+ def log(self, level, message):
+ """Implement this method to handle log messages"""
+ raise NotImplementedError
+
+ def format(self, message):
+ """Override this method to apply custom formating of messages"""
+ return message
+
+class DummyLogger(TweepyLogger):
+ """This logger just discards log messages"""
+
+ def log(self, level, message):
+ return
+
+class ConsoleLogger(TweepyLogger):
+ """Outputs log messages to stdout"""
+
+ def __init__(self, active_log_level=TweepyLogger.DEBUG):
+ self.active_log_level = active_log_level
+
+ def log(self, level, message):
+ if level <= self.active_log_level:
+ print message
+
+class FileLogger(TweepyLogger):
+ """Outputs log message to file"""
+
+ def __init__(self, filepath, active_log_level=TweepyLogger.DEBUG):
+ self.active_log_level = active_log_level
+ self.file = open(filepath, 'w')
+
+ def log(self, level, message):
+ if level <= self.active_log_level:
+ self.file.write(message + '\n')
+ self.file.flush()
+