Git Product home page Git Product logo

sinaweibopy's Introduction

snspy

SNSPY is a stand-alone Python script which provides

  • OAuth2.0 authentication
  • API calling wrapper

for any social network providers.

http://michaelliao.github.com/sinaweibopy/

Developed and mantained by Michael Liao. Please feel free to report bugs and your suggestions at here.

OAuth2.0

OAuth 2 is a protocol focuses on client developer simplicity while providing specific authorization flows for web applications.

There are many social networks provides OAuth 2 authentication and APIs, and snspy is a simple API wrapper for any social network such as Twitter, Facebook, LinkedIn, Sina Weibo, etc.

snspy provides a unique API interface for developers and difference of each social network APIs are handled by its mixin.

Basic Usage

You need to register your OAuth 2 application on the social network you choose:

Tweeter Facebook LinkedIn Sina Weibo QQ Connect

After setting up your account and registering for an application, you will receive YOUR_APP_KEY and YOUR_APP_SECRET. Together with YOUR_CALLBACK_URL, these are the environment variables required by snspy. And you can create the APIClient now:

from snspy import APIClient
from snspy import TwitterMixin      # suppose you are using Twitter

APP_KEY = 'YOUR_APP_KEY'            # app key
APP_SECRET = 'YOUR_APP_SECRET'      # app secret
CALLBACK_URL = 'YOUR_CALLBACK_URL'  # callback url

client = APIClient(TwitterMixin, app_key=APP_KEY, app_secret=APP_SECRET, redirect_uri=CALLBACK_URL)

Put on your website a link which redirect the user to the following authorization URL:

url = client.get_authorize_url()    # redirect the user to 'url'

After granting the privileges, the user will be redirected to YOUR_CALLBACK_URL, with parameter code=SOME_CODE attached. Then you need to get the access token using this SOME_CODE.

r = client.request_access_token(SOME_CODE)
access_token = r.access_token  # access token,e.g., abc123xyz456
expires = r.expires      # token expires time, UNIX timestamp, e.g., 1384826449.252 (10:01 am, 19 Nov 2013, UTC+8:00)
NOTE: you should store the access_token for later use.

After got access token you can init the APIClient any time:

client = APIClient(TwitterMixin,
                   app_key=APP_KEY, app_secret=APP_SECRET, redirect_uri=CALLBACK_URL,
                   access_token=YOUR_ACCESS_TOKEN, expires=EXPIRES_TIME)

Then, you are free to call whatever API you like. For example,

print client.statuses.user_timeline.get()
print client.statuses.update.post(status=u'test plain weibo')
print client.statuses.upload.post(status=u'test weibo with picture',
                                  pic=open('/Users/michael/test.png'))

How to call a particular API

Firstly, refer to the corresponding API document. Use user_timeline as an example:

API:
statuses/user_timeline

HTTP Request Method:
GET

Request Parameters:
source:       string, This parameter is not needed when using OAuth. The value
                      of this parameter is the AppKey.
access_token: string, This parameter is required when using OAuth.You will get
                      the access_token after oauth authorization. 
uid:          int64,  Return the weibos of specified ID of a user. 
screen_name:  string, The nickname of the user that ID is specified. 

Substitute / in the API with ., and call get() or post() according to the request method with all the necessary parameters excluding source and access_token.

r = client.statuses.user_timeline.get(uid=SOME_ID)
for st in r.statuses:
    print st.text

If the request method is POST, then it should be something like the following:

r = client.statuses.update.post(status=u'test weibo')

And, as for uploading pictures:

f = open('/Users/michael/test.png', 'rb')
r = client.statuses.upload.post(status=u'test weibo with picture', pic=f)
f.close()  # you need to do this manually

Please notice that what is uploaded must be a file-like object. str can be wrapped using StringIO.

wiki

For more information, please refer to the wiki.

sinaweibopy's People

Contributors

antiagainst avatar biergaizi avatar cloudaice avatar fengh16 avatar michaelliao avatar moon-clj avatar smallcode avatar takura avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sinaweibopy's Issues

can't send a Weibo which be only read by owner

Traceback (most recent call last):
File "weiboc.py", line 101, in
run2()
File "weiboc.py", line 78, in run2
client.statuses.update.post(status=content,visible=1)
File "/usr/local/python2.7.6/lib/python2.7/site-packages/sinaweibopy-1.1.3-py2.7.egg/weibo.py", line 310, in call
return _http_call('%s%s.json' % (self._client.api_url, self._path), method, self._client.access_token, **kw)
File "/usr/local/python2.7.6/lib/python2.7/site-packages/sinaweibopy-1.1.3-py2.7.egg/weibo.py", line 172, in _http_call
raise APIError(r.error_code, r.get('error', ''), r.get('request', ''))
weibo.APIError: APIError: 10017: parameter (visible)'s value invalid,expect (visible != 1), but get (1), see doc for more info., request: /2/statuses/update.json

cannot pickle JsonObject

here is what I did to add this feature:

class JsonObject(dict):
'''
general json object that can bind any fields.

'''
#NOTE: add support to JsonObject
def __getstate__(self):
    return self.copy()

def __setstate__(self, state):
    self.__dict__.update(state)

使用sinaweibopy代码协议?

我最近使用新浪的微盘,微盘的api同样是采用auth2.0,您代码大部分都适用于微盘,不过在api调用上有些需要修改。我想修改为微盘适用的代码(小部分修改)并且传至我的github代码仓库,征得您的同意。

如何调用具体API

rt,按照demo里写的,将api转化为下划线格式,比如获取followers列表,使用client.get.friendships__followers()会报错HTTP Error 400: Not Found

微博接口 2/statuses/share 调用失败

最近微博更新了接口,使用 2/statuses/share 发送微博,导致上传一张照片并发送微博的功能无法使用,错误如下:

Traceback (most recent call last):
  File "./send_message.py", line 110, in <module>
    send_msg_with_pic(client, 'table.png', get_city_data(city))
  File "./send_message.py", line 64, in send_msg_with_pic
    client.statuses.share.post(status=message, pic=f)
  File "/home/zhouzy/.pyenv/versions/2.7.13/lib/python2.7/site-packages/weibo.py", line 310, in __call__
    return _http_call('%s%s.json' % (self._client.api_url, self._path), method, self._client.access_token, **kw)
  File "/home/zhouzy/.pyenv/versions/2.7.13/lib/python2.7/site-packages/weibo.py", line 172, in _http_call
    raise APIError(r.error_code, r.get('error', ''), r.get('request', ''))
weibo.APIError: APIError: 10017: appkey not bind domain!, request: /2/statuses/share.json

提示的是appkey没有绑定域名,但是已经绑定了域名,且域名写在微博文本中。
另外,仅发送文本,不发送图片是可以成功发送的。
希望能够解决,谢谢!

_guess_content_type的返回值为None

102: def _guess_content_type(url):
107:     mimetypes.types_map.get(ext, 'application/octet-stream')

107行少了个return,在upload调用时minetype会变成None

107:     return mimetypes.types_map.get(ext, 'application/octet-stream')

Any plan to support python 3

Error when try to build on python 3

File "sinaweibopy/weibo.py", line 12, in <module>
        from cStringIO import StringIO
    ModuleNotFoundError: No module named 'cStringIO'

statuses.update.post with 10007 Error

`
from weibo import APIClient

WEIBO_APP_KEY='...'
WEIBO_APP_SECRET='...'
WEIBO_CALLBACK_URL='...'

access_token='...'
client = APIClient(app_key=WEIBO_APP_KEY, app_secret=WEIBO_APP_SECRET, redirect_uri=WEIBO_CALLBACK_URL)
client.set_access_token(access_token, 3600)

f = open('/home/ec2-user/Aromasin_4.jpg', 'rb')
client.statuses.update.post(status=u'test weibo with pic', pic=f)
f.close()
`

Error Message

weibo.APIError: APIError: 10007: unsupport mediatype (multipart/form-data;boundary=----------0x1567f936995), request: /2/statuses/update.json

OAUTH2中statuses__upload报错

这是发布一条带图片的微博,必须采用multipart/form-data编码,而源程序第115行左右只是对HTTP_UPLOAD这类请求使用了multipart/form-data。

cannot import APIClient

When I trying to use the weibo package, I get a error to import the APIClient. Python raises a error that "cannot import name APIClient" , does someone know why?

The source code is showing below:
from weibo import APIClient(error here)
import webbrowser

bug line 148, raise e,pls

except urllib2.HTTPError, e:
    r = json.loads(e.read(), object_hook=_obj_hook)
    if hasattr(r, 'error_code'):
        raise APIError(r.error_code, r.get('error', ''), r.get('request', ''))

'- raise
'+ raise e

snspy代码中有几个错误

其中和weibo.py相同的报错是mimetypes.types_map 是can't resolve import,这个错误只是编译错误,能够正常执行,其它的错误都是引用了未存在的变量,我做了修正,等会pull给你,你审一下。

weibo.APIError: APIError: 21324:

Traceback (most recent call last):
File "weibo_bot.py", line 156, in
check_user(1372451215)
File "weibo_bot.py", line 104, in check_user
token = client.request_access_token(code)
File "/usr/local/lib/python2.7/dist-packages/weibo.py", line 263, in request_access_token
code = code, grant_type = 'authorization_code')
File "/usr/local/lib/python2.7/dist-packages/weibo.py", line 119, in _http_post
return _http_call(url, _HTTP_POST, authorization, **kw)
File "/usr/local/lib/python2.7/dist-packages/weibo.py", line 172, in _http_call
raise APIError(r.error_code, r.get('error', ''), r.get('request', ''))
weibo.APIError: APIError: 21324: invalid_client, request: /oauth2/access_token

refresh_token....

def refresh_token(self, refresh_token):
    req_str = '%s%s' % (self.auth_url, 'access_token')
    r = _http_post(req_str, \
            client_id = self.client_id, \
            client_secret = self.client_secret, \
            refresh_token = refresh_token, \
            grant_type = 'refresh_token',)
    return r

请改名:expire_in=>expire_at,请完善文档:uid = r.uid

expire_in + time.time() = expire_at,请不要再使用expire_in!expire_in是一个duration的概念!而不是时间点的概念!

请在文档中加上uid = r.uid!这个信息非常重要,你不加上,使用者就只能靠猜了!

我最后还是看了你的源码才看明白的,大哥!!!

不支持 OAuth2/revokeoauth2 接口?

如题。
官方文档写得也很模糊,不知道是大写还是全小写。使用 client.oauth2.revokeoauth2.get()client.OAuth2.revokeoauth2.get() 都不行。
PS,这个接口不是在 /2/ 路径下的。

安装不了

----------------------------------------

Command "python setup.py egg_info" failed with error code 1 in
*********\sinaweibopy\

raise APIError(....getattr(r,'xxx','') .. ) will raise key error if key is missing

class JsonObject(dict):
....
return self[key] <=== key error will be raised if key is missing, which is good. but

if hasattr(r, 'error_code'):
raise APIError(r.error_code, getattr(r, 'error', ''), getattr(r, 'request', '')) <== what if a key missing?
APIError will not be raised.
return r

So:
raise APIError(r.error_code,r.('error', ''), r.get('request', ''))
Maybe this is a solution.

BTW, change a faster json lib will help :D
I'm using yajl instead of simplejson or json. ujson has a bigint bug.

不知 client.request_access_token(SOME_CODE) 为何物?

def testwb():
    APP_KEY = '3485752000'            # app key
    APP_SECRET = '576849f0f803915e5132b99eeaxxxx'      # app secret
    CALLBACK_URL = 'http://some.me'  # callback url
    client = APIClient(app_key=APP_KEY, app_secret=APP_SECRET,
                   redirect_uri= CALLBACK_URL)
    url = client.get_authorize_url()    # redirect the user to `url'

    r = client.request_access_token(SOME_CODE)  ## 没明白这里应该是什么?我只需要命令行发消息就可以了
    print r.access_token
    access_token = r.access_token  # access token,e.g., abc123xyz456
    expires_in = r.expires_in      # token expires in
    client.set_access_token(access_token, expires_in)

    print client.statuses.user_timeline.get()
    print client.statuses.update.post(status=u'test plain weibo')
    print client.statuses.upload.post(status=u'test weibo with picture')

参数代码 code

怎么自动获取参数代码code
现在每次都是手动复制下来的,有没有用程序获取的方法呢

获取access_token,服务器返回Bad Request

使用SDK中的方法去获取access_token,服务器返回Bad Request,有谁知道是哪里有问题吗?

代码如下:
import urllib2
import urllib
from snspy import APIClient
from snspy import SinaWeiboMixin

def wbAPItest():
client = APIClient(SinaWeiboMixin, app_key=appkey, app_secret=appsec, redirect_uri=redirurl)
url = client.get_authorize_url()
r = client.request_access_token(authcode)
access_token = r.access_token # access token,e.g., abc123xyz456
expires = r.expires

if name=='main':
httpHandler = urllib2.HTTPHandler(debuglevel=1)
httpsHandler = urllib2.HTTPSHandler(debuglevel=1)
opener = urllib2.build_opener(httpHandler, httpsHandler)
urllib2.install_opener(opener)
wbAPItest()

运行后日志:
ERROR:root:POST: https://api.weibo.com/oauth2/access_token
send: 'POST /oauth2/access_token HTTP/1.1\r\nContent-Length: 204\r\nAccept-Encoding: gzip\r\nConnection: close\r\nUser-Agent: Python-urllib/2.7\r\nHost: api.weibo.com\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nclient_secret=b6745a6318f713f8f00b8d715927fab5&code=b0d87cc1e249a30626b82549376d830e&grant_type=authorization_code&client_id=2066080083&redirect_uri=http%3A//open.weibo.com/apps/2066080083/privilege/oauth'

reply: 'HTTP/1.1 400 Bad Request\r\n'
header: Server: nginx/1.6.1

header: Date: Tue, 19 May 2015 08:47:05 GMT

header: Transfer-Encoding: chunked

header: Connection: close

header: Pragma: No-cache

header: Cache-Control: no-cache

header: Expires: Thu, 01 Jan 1970 00:00:00 GMT

header: Api-Server-IP: 10.75.25.115

proted to python3

version = '1.1.4.3'
author = 'ported by gcd0318, origined by Liao Xuefeng ([email protected])'

'''
Python client SDK for sina weibo API using OAuth 2.
'''

ported to python3

from io import StringIO, BytesIO
import gzip, time, json, hmac, base64, hashlib, urllib.request, urllib.parse, urllib.error, urllib.request, urllib.error, urllib.parse, logging, mimetypes, collections

class APIError(Exception):
'''
raise APIError if receiving json message indicating failure.
'''
def init(self, error_code, error, request):
self.error_code = error_code
self.error = error
self.request = request
Exception.init(self, error)

def __str__(self):
    return 'APIError: %s: %s, request: %s' % (self.error_code, self.error, self.request)

def _parse_json(s):
' parse str into JsonDict '

def _obj_hook(pairs):
    ' convert json object to python object '
    o = JsonDict()
    for k, v in list(pairs.items()):
        o[str(k)] = v
    return o
return json.loads(s, object_hook=_obj_hook)

class JsonDict(dict):
' general json object that allows attributes to be bound to and also behaves like a dict '

def __getattr__(self, attr):
    try:
        return self[attr]
    except KeyError:
        raise AttributeError(r"'JsonDict' object has no attribute '%s'" % attr)

def __setattr__(self, attr, value):
    self[attr] = value

def _encode_params(**kw):
'''
do url-encode parameters

_encode_params(a=1, b='R&D')
'a=1&b=R%26D'
_encode_params(a=u'\u4e2d\u6587', b=['A', 'B', 123])
'a=%E4%B8%AD%E6%96%87&b=A&b=B&b=123'
'''
args = []
for k, v in list(kw.items()):
qv = None
if isinstance(v, str):
qv = v
elif isinstance(v, collections.Iterable):
for i in v:
qv = str(i)
args.append('%s=%s' % (k, urllib.parse.quote(qv)))
qv = None
else:
qv = str(v)
if qv:
args.append('%s=%s' % (k, urllib.parse.quote(qv)))
return '&'.join(args)

def _encode_multipart(**kw):
boundary = '----------%s' % hex(int(time.time() * 1000))
data = []
for k, v in list(kw.items()):
data.append('--%s' % boundary)
if hasattr(v, 'read'):
# file-like object:
filename = getattr(v, 'name', '')
data.append('Content-Disposition: form-data; name="%s"; filename="hidden"' % k)
data.append('Content-Type: %s\r\n' % _guess_content_type(filename))
data.append(v.read().decode('iso-8859-1'))
else:
data.append('Content-Disposition: form-data; name="%s"\r\n' % k)

qv = urllib.parse.quote(v)

        data.append(urllib.parse.quote(v) if isinstance(v, str) else v.decode('utf-8'))
data.append('--%s--\r\n' % boundary)
return '\r\n'.join(data).encode('iso-8859-1'), boundary

def _guess_content_type(url):
n = url.rfind('.')
if n==(-1):
return 'application/octet-stream'
ext = url[n:]
return mimetypes.types_map.get(ext, 'application/octet-stream')

_HTTP_GET = 0
_HTTP_POST = 1
_HTTP_UPLOAD = 2

def _http_get(url, authorization=None, *_kw):
logging.info('GET %s' % url)
return _http_call(url, _HTTP_GET, authorization, *_kw)

def _http_post(url, authorization=None, *_kw):
logging.info('POST %s' % url)
return _http_call(url, _HTTP_POST, authorization, *_kw)

def _http_upload(url, authorization=None, *_kw):
logging.info('MULTIPART POST %s' % url)
return _http_call(url, _HTTP_UPLOAD, authorization, *_kw)

def _read_body(obj):
using_gzip = obj.headers.get('Content-Encoding', '')=='gzip'
body = obj.read()
if using_gzip:
gzipper = gzip.GzipFile(fileobj=BytesIO(body))
fcontent = gzipper.read()
gzipper.close()
return fcontent.decode('utf-8')
return body.decode('utf-8')

def _http_call(the_url, method, authorization, **kw):
'''
send an http request and return a json object if no error occurred.
'''
params = None
boundary = None
if method==_HTTP_UPLOAD:
# fix sina upload url:
the_url = the_url.replace('https://api.', 'https://upload.api.')
params, boundary = _encode_multipart(**kw)
else:
params = _encode_params(**kw)
if '/remind/' in the_url:
# fix sina remind api:
the_url = the_url.replace('https://api.', 'https://rm.api.')
http_url = '%s?%s' % (the_url, params) if method==_HTTP_GET else the_url
http_body = None if method==_HTTP_GET else params

if http_body:

http_body = http_body.encode('utf-8')

req = urllib.request.Request(http_url, data=http_body)
req.add_header('Accept-Encoding', 'gzip')
if authorization:
    req.add_header('Authorization', 'OAuth2 %s' % authorization)
if boundary:
    req.add_header('Content-Type', 'multipart/form-data; boundary=%s' % boundary)
try:
    resp = urllib.request.urlopen(req)
    body = _read_body(resp)
    r = _parse_json(body)
    if hasattr(r, 'error_code'):
        raise APIError(r.error_code, r.get('error', ''), r.get('request', ''))
    return r
except urllib.error.HTTPError as e:
    try:
        r = _parse_json(_read_body(e))
    except:
        r = None
    if hasattr(r, 'error_code'):
        raise APIError(r.error_code, r.get('error', ''), r.get('request', ''))
    raise e

class HttpObject(object):

def __init__(self, client, method):
    self.client = client
    self.method = method

def __getattr__(self, attr):
    def wrap(**kw):
        if self.client.is_expires():
            raise APIError('21327', 'expired_token', attr)
        return _http_call('%s%s.json' % (self.client.api_url, attr.replace('__', '/')), self.method, self.client.access_token, **kw)
    return wrap

class APIClient(object):
'''
API client using synchronized invocation.
'''
def init(self, app_key, app_secret, redirect_uri=None, response_type='code', domain='api.weibo.com', version='2'):
self.client_id = str(app_key)
self.client_secret = str(app_secret)
self.redirect_uri = redirect_uri
self.response_type = response_type
self.auth_url = 'https://%s/oauth2/' % domain
self.api_url = 'https://%s/%s/' % (domain, version)
self.access_token = None
self.expires = 0.0
self.get = HttpObject(self, _HTTP_GET)
self.post = HttpObject(self, _HTTP_POST)
self.upload = HttpObject(self, _HTTP_UPLOAD)

def parse_signed_request(self, signed_request):
    '''

parse signed request when using in-site app.

Returns:
dict object like { 'uid': 12345, 'access_token': 'ABC123XYZ', 'expires': unix-timestamp },
or None if parse failed.
'''

    def _b64_normalize(s):
        appendix = '=' * (4 - len(s) % 4)
        return s.replace('-', '+').replace('_', '/') + appendix

    sr = str(signed_request)
    logging.info('parse signed request: %s' % sr)
    enc_sig, enc_payload = sr.split('.', 1)
    sig = base64.b64decode(_b64_normalize(enc_sig))
    data = _parse_json(base64.b64decode(_b64_normalize(enc_payload)))
    if data['algorithm'] != 'HMAC-SHA256':
        return None
    expected_sig = hmac.new(self.client_secret, enc_payload, hashlib.sha256).digest();
    if expected_sig==sig:
        data.user_id = data.uid = data.get('user_id', None)
        data.access_token = data.get('oauth_token', None)
        expires = data.get('expires', None)
        if expires:
            data.expires = data.expires_in = time.time() + expires
        return data
    return None

def set_access_token(self, access_token, expires):
    self.access_token = str(access_token)
    self.expires = float(expires)

def get_authorize_url(self, redirect_uri=None, **kw):
    '''

return the authorization url that the user should be redirected to.
'''
redirect = redirect_uri if redirect_uri else self.redirect_uri
if not redirect:
raise APIError('21305', 'Parameter absent: redirect_uri', 'OAuth2 request')
response_type = kw.pop('response_type', 'code')
return '%s%s?%s' % (self.auth_url, 'authorize',
_encode_params(client_id = self.client_id,
response_type = response_type,
redirect_uri = redirect, **kw))

def _parse_access_token(self, r):
    '''

new:return access token as a JsonDict: {"access_token":"your-access-token","expires_in":12345678,"uid":1234}, expires_in is represented using standard unix-epoch-time
'''
current = int(time.time())
expires = r.expires_in + current
remind_in = r.get('remind_in', None)
if remind_in:
rtime = int(remind_in) + current
if rtime < expires:
expires = rtime
return JsonDict(access_token=r.access_token, expires=expires, expires_in=expires, uid=r.get('uid', None))

def request_access_token(self, code, redirect_uri=None):
    redirect = redirect_uri if redirect_uri else self.redirect_uri
    if not redirect:
        raise APIError('21305', 'Parameter absent: redirect_uri', 'OAuth2 request')
    r = _http_post('%s%s' % (self.auth_url, 'access_token'), \
            client_id = self.client_id, \
            client_secret = self.client_secret, \
            redirect_uri = redirect, \
            code = code, grant_type = 'authorization_code')
    return self._parse_access_token(r)

def refresh_token(self, refresh_token):
    req_str = '%s%s' % (self.auth_url, 'access_token')
    r = _http_post(req_str, \
        client_id = self.client_id, \
        client_secret = self.client_secret, \
        refresh_token = refresh_token, \
        grant_type = 'refresh_token')
    return self._parse_access_token(r)

def is_expires(self):
    return not self.access_token or time.time() > self.expires

def __getattr__(self, attr):
    if '__' in attr:
        return getattr(self.get, attr)
    return _Callable(self, attr)

_METHOD_MAP = { 'GET': _HTTP_GET, 'POST': _HTTP_POST, 'UPLOAD': _HTTP_UPLOAD }

class _Executable(object):

def __init__(self, client, method, path):
    self._client = client
    self._method = method
    self._path = path

def __call__(self, **kw):
    method = _METHOD_MAP[self._method]
    if method==_HTTP_POST and 'pic' in kw:
        method = _HTTP_UPLOAD
    return _http_call('%s%s.json' % (self._client.api_url, self._path), method, self._client.access_token, **kw)

def __str__(self):
    return '_Executable (%s %s)' % (self._method, self._path)

__repr__ = __str__

class _Callable(object):

def __init__(self, client, name):
    self._client = client
    self._name = name

def __getattr__(self, attr):
    if attr=='get':
        return _Executable(self._client, 'GET', self._name)
    if attr=='post':
        return _Executable(self._client, 'POST', self._name)
    name = '%s/%s' % (self._name, attr)
    return _Callable(self._client, name)

def __str__(self):
    return '_Callable (%s)' % self._name

__repr__ = __str__

if name=='main':
import doctest
doctest.testmod()

HTTPError raised when execute api client.get.statuses__repost_timeline without any parameter

the code:

    except urllib2.HTTPError as err:
        r = json.loads(err.read(), object_hook=_obj_hook)
        return {'status': 'error', 'status_code': str(err), 'rst': r}

the result:

{
    "status": "error", 
    "status_code": "HTTP Error 400: Bad Request", 
    "rst": {
        "error_code": 10016,
        "request": "/2/statuses/repost_timeline.json",
        "error": "miss required parameter (id), see doc for more info."
    }
}

despite receiving a "HTTP Error 400: Bad Request" error, i think a APIError should be raised.

invalid_grant

client = APIClient(app_key=WEIBO_APPKEY, app_secret=WEIBO_APPSECRET,redirect_uri=WEIBO_CALLBACK)
// url = client.get_authorize_url() 因为我们的accessToken是从微博手机登陆拿来的,所以我们不需要这个
r = client.request_access_token(< accessToken是从iphone手机客户端拿来的 >)

用了这个accessToken以后却获得下面这个错误.
Gives error:
APIError: APIError: 21325: invalid_grant, request: /oauth2/access_token

请问有什么解决办法或者是出了什么问题,accessToken没有过期和失效却得到这个错误.

Refresh Token

您好
謝謝您提供的lib
想請問您refresh token是否可以使用
或者想請問您他使用的條件是什麼
我呼叫他但是失敗了
想請教您使用的方式~
因為官網說還沒做好refresh token的支援
謝謝您

don't support gzip

sdk should open 'gzip' support. here are some statistics:

download 10 pages of reposts of one status, each page contains 200 reposts:

without gzip: transfered data from sina api to local : 6 344 544 Bytes, Duration 13.4246s
with gzip: transfered data from sina api to local: 459 668 Bytes, Duration 4.3794s

see the difference ?

Update the Wiki

Due to the change in Weibo API, many methods are not usable now, such as

print client.statuses.update.post(status=u'测试OAuth 2.0发微博')

A usable sample could be like this:

client.statuses.share.post(status=u'This is a test. https://github.com') # Link in the payload seems a must.

Some updates could be helpful.

Thanks.

weibo.py timeout handling

in the event that the weibo server does not return response, the weibo.py script will wait forever. This is due to the urlopen() method in weibo.py (line 159) did not specify a timeout value, which default to global value: None, and interpreted as "indefinitely"

运行例子出错

访问出错了!
你所访问的站点在新浪微博的认证失败,请你联系sad或者稍后再试。
(error:redirect_uri_mismatch)
新浪微博版权所有

HTTPError 大小写错误

真巧,上午我刚刚给 weibo.py 加上了 HTTPError 错误的捕获,刚要 pull request 的时候就看到已经有 Commit 了。

但是 139 行,HttpError 应为 HTTPError,HTTP 全大写。

最后感谢这个开源库,帮我节省了不少时间。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.