Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Zahra Rajabi
tweepy
Commits
c48d352a
Commit
c48d352a
authored
Jan 30, 2010
by
Joshua
Browse files
Some major refactoring inside binder.py.
parent
52d95381
Changes
1
Hide whitespace changes
Inline
Side-by-side
tweepy/binder.py
View file @
c48d352a
...
...
@@ -12,157 +12,178 @@ from tweepy.error import TweepError
re_path_template
=
re
.
compile
(
'{\w+}'
)
def
bind_api
(
path
,
payload_type
=
None
,
payload_list
=
False
,
allowed_param
=
[],
method
=
'GET'
,
require_auth
=
False
,
timeout
=
None
,
search_api
=
False
):
def
bind_api
(
**
config
):
class
APIMethod
(
object
):
path
=
config
[
'path'
]
payload_type
=
config
.
get
(
'payload_type'
,
None
)
payload_list
=
config
.
get
(
'payload_list'
,
False
)
allowed_param
=
config
.
get
(
'allowed_param'
,
[])
method
=
config
.
get
(
'method'
,
'GET'
)
require_auth
=
config
.
get
(
'require_auth'
,
False
)
timeout
=
config
.
get
(
'timeout'
,
None
)
search_api
=
config
.
get
(
'search_api'
,
False
)
def
__init__
(
self
,
api
,
args
,
kargs
):
# If authentication is required and no credentials
# are provided, throw an error.
if
self
.
require_auth
and
not
api
.
auth
:
raise
TweepError
(
'Authentication required!'
)
self
.
api
=
api
self
.
post_data
=
kargs
.
pop
(
'post_data'
,
None
)
self
.
retry_count
=
kargs
.
pop
(
'retry_count'
,
api
.
retry_count
)
self
.
retry_delay
=
kargs
.
pop
(
'retry_delay'
,
api
.
retry_delay
)
self
.
retry_errors
=
kargs
.
pop
(
'retry_errors'
,
api
.
retry_errors
)
self
.
headers
=
kargs
.
pop
(
'headers'
,
{})
self
.
build_parameters
(
args
,
kargs
)
# Pick correct URL root to use
if
self
.
search_api
:
self
.
api_root
=
api
.
search_root
else
:
self
.
api_root
=
api
.
api_root
# Perform any path variable substitution
self
.
build_path
()
def
_call
(
api
,
*
args
,
**
kargs
):
# If require auth, throw exception if credentials not provided
if
require_auth
and
not
api
.
auth
:
raise
TweepError
(
'Authentication required!'
)
# check for post data
post_data
=
kargs
.
pop
(
'post_data'
,
None
)
# check for retry request parameters
retry_count
=
kargs
.
pop
(
'retry_count'
,
api
.
retry_count
)
retry_delay
=
kargs
.
pop
(
'retry_delay'
,
api
.
retry_delay
)
retry_errors
=
kargs
.
pop
(
'retry_errors'
,
api
.
retry_errors
)
# check for headers
headers
=
kargs
.
pop
(
'headers'
,
{})
# build parameter dict
parameters
=
{}
for
idx
,
arg
in
enumerate
(
args
):
if
isinstance
(
arg
,
unicode
):
arg
=
arg
.
encode
(
'utf-8'
)
elif
not
isinstance
(
arg
,
str
):
arg
=
str
(
arg
)
try
:
parameters
[
allowed_param
[
idx
]]
=
arg
except
IndexError
:
raise
TweepError
(
'Too many parameters supplied!'
)
for
k
,
arg
in
kargs
.
items
():
if
arg
is
None
:
continue
if
k
in
parameters
:
raise
TweepError
(
'Multiple values for parameter %s supplied!'
%
k
)
if
isinstance
(
arg
,
unicode
):
arg
=
arg
.
encode
(
'utf-8'
)
elif
not
isinstance
(
arg
,
str
):
arg
=
str
(
arg
)
parameters
[
k
]
=
arg
# Pick correct URL root to use
if
search_api
is
False
:
api_root
=
api
.
api_root
else
:
api_root
=
api
.
search_root
# Build the request URL
if
len
(
parameters
):
# Replace any template variables in path
tpath
=
str
(
path
)
for
template
in
re_path_template
.
findall
(
tpath
):
name
=
template
.
strip
(
'{}'
)
try
:
value
=
urllib
.
quote
(
parameters
[
name
])
tpath
=
tpath
.
replace
(
template
,
value
)
except
KeyError
:
raise
TweepError
(
'Invalid path key: %s'
%
name
)
del
parameters
[
name
]
url
=
'%s?%s'
%
(
api_root
+
tpath
,
urllib
.
urlencode
(
parameters
))
else
:
url
=
api_root
+
path
# Check cache if caching enabled and method is GET
if
api
.
cache
and
method
==
'GET'
:
cache_result
=
api
.
cache
.
get
(
url
,
timeout
)
# if cache result found and not expired, return it
if
cache_result
:
# must restore api reference
if
isinstance
(
cache_result
,
list
):
for
result
in
cache_result
:
result
.
_api
=
api
else
:
cache_result
.
_api
=
api
return
cache_result
# get scheme and host
if
api
.
secure
:
scheme
=
'https://'
else
:
scheme
=
'http://'
if
search_api
is
False
:
host
=
api
.
host
else
:
host
=
api
.
search_host
# Continue attempting request until successful
# or maximum number of retries is reached.
retries_performed
=
0
while
retries_performed
<
retry_count
+
1
:
# Open connection
# FIXME: add timeout
if
api
.
secure
:
conn
=
http
lib
.
HTTPSConnection
(
host
)
self
.
scheme
=
'
http
s://'
else
:
conn
=
httplib
.
HTTPConnection
(
host
)
# Apply authentication
if
api
.
auth
:
api
.
auth
.
apply_auth
(
scheme
+
host
+
url
,
method
,
headers
,
parameters
)
# Build request
try
:
conn
.
request
(
method
,
url
,
headers
=
headers
,
body
=
post_data
)
except
Exception
,
e
:
raise
TweepError
(
'Failed to send request: %s'
%
e
)
# Get response
resp
=
conn
.
getresponse
()
# Exit request loop if non-retry error code
if
retry_errors
is
None
:
if
resp
.
status
==
200
:
break
self
.
scheme
=
'http://'
if
self
.
search_api
:
self
.
host
=
api
.
search_host
else
:
if
resp
.
status
not
in
retry_errors
:
break
self
.
host
=
api
.
host
def
build_parameters
(
self
,
args
,
kargs
):
self
.
parameters
=
{}
for
idx
,
arg
in
enumerate
(
args
):
if
isinstance
(
arg
,
unicode
):
arg
=
arg
.
encode
(
'utf-8'
)
elif
not
isinstance
(
arg
,
str
):
arg
=
str
(
arg
)
try
:
self
.
parameters
[
self
.
allowed_param
[
idx
]]
=
arg
except
IndexError
:
raise
TweepError
(
'Too many parameters supplied!'
)
for
k
,
arg
in
kargs
.
items
():
if
arg
is
None
:
continue
if
k
in
self
.
parameters
:
raise
TweepError
(
'Multiple values for parameter %s supplied!'
%
k
)
if
isinstance
(
arg
,
unicode
):
arg
=
arg
.
encode
(
'utf-8'
)
elif
not
isinstance
(
arg
,
str
):
arg
=
str
(
arg
)
self
.
parameters
[
k
]
=
arg
def
build_path
(
self
):
for
variable
in
re_path_template
.
findall
(
self
.
path
):
name
=
variable
.
strip
(
'{}'
)
if
name
==
'user'
and
self
.
api
.
auth
:
value
=
self
.
api
.
auth
.
get_username
()
else
:
try
:
value
=
urllib
.
quote
(
self
.
parameters
[
name
])
self
.
path
=
self
.
path
.
replace
(
variable
,
value
)
except
KeyError
:
raise
TweepError
(
'No parameter value found for path variable: %s'
%
name
)
del
self
.
parameters
[
name
]
def
execute
(
self
):
# Build the request URL
url
=
self
.
api_root
+
self
.
path
if
len
(
self
.
parameters
):
url
=
'%s?%s'
%
(
url
,
urllib
.
urlencode
(
self
.
parameters
))
# Query the cache if one is available
# and this request uses a GET method.
if
self
.
api
.
cache
and
self
.
method
==
'GET'
:
cache_result
=
self
.
api
.
cache
.
get
(
url
,
self
.
timeout
)
# if cache result found and not expired, return it
if
cache_result
:
# must restore api reference
if
isinstance
(
cache_result
,
list
):
for
result
in
cache_result
:
result
.
_api
=
self
.
api
else
:
cache_result
.
_api
=
self
.
api
return
cache_result
# Continue attempting request until successful
# or maximum number of retries is reached.
retries_performed
=
0
while
retries_performed
<
self
.
retry_count
+
1
:
# Open connection
# FIXME: add timeout
if
self
.
api
.
secure
:
conn
=
httplib
.
HTTPSConnection
(
self
.
host
)
else
:
conn
=
httplib
.
HTTPConnection
(
self
.
host
)
# Apply authentication
if
self
.
api
.
auth
:
self
.
api
.
auth
.
apply_auth
(
self
.
scheme
+
self
.
host
+
url
,
self
.
method
,
self
.
headers
,
self
.
parameters
)
# Execute request
try
:
conn
.
request
(
self
.
method
,
url
,
headers
=
self
.
headers
,
body
=
self
.
post_data
)
resp
=
conn
.
getresponse
()
except
Exception
,
e
:
raise
TweepError
(
'Failed to send request: %s'
%
e
)
# Exit request loop if non-retry error code
if
self
.
retry_errors
:
if
resp
.
status
not
in
self
.
retry_errors
:
break
else
:
if
resp
.
status
==
200
:
break
# Sleep before retrying request again
time
.
sleep
(
retry_delay
)
retries_performed
+=
1
# Sleep before retrying request again
time
.
sleep
(
self
.
retry_delay
)
retries_performed
+=
1
# If an error was returned, throw an exception
api
.
last_response
=
resp
if
resp
.
status
!=
200
:
try
:
error_msg
=
parse_error
(
json
.
loads
(
resp
.
read
()))
except
Exception
:
error_msg
=
"Twitter error response: status code = %s"
%
resp
.
status
raise
TweepError
(
error_msg
)
# If an error was returned, throw an exception
self
.
api
.
last_response
=
resp
if
resp
.
status
!=
200
:
try
:
#TODO: parse error message
raise
Exception
except
Exception
:
error_msg
=
"Twitter error response: status code = %s"
%
resp
.
status
raise
TweepError
(
error_msg
)
# Parse the response payload
result
=
self
.
api
.
parser
.
parse
(
self
.
api
,
self
.
payload_type
,
self
.
payload_list
,
resp
.
read
())
conn
.
close
()
# Parse the response payload
result
=
api
.
parser
.
parse
(
api
,
payload_type
,
payload_list
,
resp
.
read
())
# Store result into cache if one is available.
if
self
.
api
.
cache
and
self
.
method
==
'GET'
and
result
:
self
.
api
.
cache
.
store
(
url
,
result
)
conn
.
close
()
return
result
# store result in cache
if
api
.
cache
and
method
==
'GET'
and
result
:
api
.
cache
.
store
(
url
,
result
)
return
result
def
_call
(
api
,
*
args
,
**
kargs
):
method
=
APIMethod
(
api
,
args
,
kargs
)
return
method
.
execute
()
# Set pagination mode
if
'cursor'
in
allowed_param
:
if
'cursor'
in
APIMethod
.
allowed_param
:
_call
.
pagination_mode
=
'cursor'
elif
'page'
in
allowed_param
:
elif
'page'
in
APIMethod
.
allowed_param
:
_call
.
pagination_mode
=
'page'
return
_call
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment