新浪微博Python3客户端接口OAuth2
Keyword: Python3 Oauth2 新浪微博
本接口基于廖雪峰的weibo python SDK修改完成,其sdk为新浪官方所推荐,原作者是用python2写的
经过一些修改,这里提供基于python3的 weibo SDK
#!/usr/bin/env python
# -*- coding: utf-8 -*- __version__ = '1.04'
__author__ = 'Liao Xuefeng (askxuefeng@gmail.com)'
__publish__ = 'http://www.cnblogs.com/txw1958/' '''
Python3 client SDK for sina weibo API using OAuth 2.
''' try:
import json
except ImportError:
import simplejson as json
import time
import urllib.request
import logging def _obj_hook(pairs):
'''
convert json object to python object.
'''
o = JsonObject()
for k, v in pairs.items():
o[str(k)] = v
return o class APIError(Exception):
'''
raise APIError if got failed json message.
'''
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) class JsonObject(dict):
'''
general json object that can bind any fields but also act as a dict.
'''
def __getattr__(self, attr):
return self[attr] def __setattr__(self, attr, value):
self[attr] = value def _encode_params(**kw):
'''
Encode parameters.
'''
args = []
for k, v in kw.items():
qv = v.encode('utf-8') if isinstance(v, str) else str(v)
args.append('%s=%s' % (k, urllib.parse.quote(qv)))
return '&'.join(args) def _encode_multipart(**kw):
'''
Build a multipart/form-data body with generated random boundary.
'''
boundary = '----------%s' % hex(int(time.time() * 1000))
data = []
for k, v in kw.items():
data.append('--%s' % boundary)
if hasattr(v, 'read'):
filename = getattr(v, 'name', '')
n = filename.rfind('.')
ext = filename[n:].lower() if n != (-1) else ""
content = v.read()
content = content.decode('ISO-8859-1')
data.append('Content-Disposition: form-data; name="%s"; filename="hidden"' % k)
data.append('Content-Length: %d' % len(content))
data.append('Content-Type: %s\r\n' % _guess_content_type(ext))
data.append(content)
else:
data.append('Content-Disposition: form-data; name="%s"\r\n' % k)
data.append(v if isinstance(v, str) else v.decode('utf-8'))
data.append('--%s--\r\n' % boundary)
return '\r\n'.join(data), boundary _CONTENT_TYPES = { '.png': 'image/png', '.gif': 'image/gif', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.jpe': 'image/jpeg' } def _guess_content_type(ext):
return _CONTENT_TYPES.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 _http_call(url, method, authorization, **kw):
'''
send an http request and expect to return a json object if no error.
'''
params = None
boundary = None
if method==_HTTP_UPLOAD:
params, boundary = _encode_multipart(**kw)
else:
params = _encode_params(**kw)
http_url = '%s?%s' % (url, params) if method==_HTTP_GET else url
http_body = None if method==_HTTP_GET else params.encode(encoding='utf-8')
req = urllib.request.Request(http_url, data=http_body)
if authorization:
req.add_header('Authorization', 'OAuth2 %s' % authorization)
if boundary:
req.add_header('Content-Type', 'multipart/form-data; boundary=%s' % boundary)
resp = urllib.request.urlopen(req)
body = resp.read().decode("utf-8")
r = json.loads(body, object_hook=_obj_hook)
if 'error_code' in r:
raise APIError(r.error_code, r['error_code'], r['request'])
return r 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('', '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=''):
self.client_id = app_key
self.client_secret = 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 set_access_token(self, access_token, expires_in):
self.access_token = str(access_token)
self.expires = float(expires_in) def get_authorize_url(self, redirect_uri=None, display='default'):
'''
return the authroize url that should be redirect.
'''
redirect = redirect_uri if redirect_uri else self.redirect_uri
if not redirect:
raise APIError('', 'Parameter absent: redirect_uri', 'OAuth2 request')
return '%s%s?%s' % (self.auth_url, 'authorize', \
_encode_params(client_id = self.client_id, \
response_type = 'code', \
display = display, \
redirect_uri = redirect)) def request_access_token(self, code, redirect_uri=None):
'''
return access token as object: {"access_token":"your-access-token","expires_in":12345678}, expires_in is standard unix-epoch-time
'''
redirect = redirect_uri if redirect_uri else self.redirect_uri
if not redirect:
raise APIError('', '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') r.expires_in += int(time.time())
return r def is_expires(self):
return not self.access_token or time.time() > self.expires def __getattr__(self, attr):
return getattr(self.get, attr) def main():
try:
#step 1 定义 app key,app secret,回调地址:
APP_KEY = ""
APP_SECRET = "7be6f636faf7b17d048c0cd3c55ada45"
CALLBACK_URL = 'https://api.weibo.com/oauth2/default.html'
#step 2 引导用户到授权地址
client = APIClient(app_key=APP_KEY, app_secret=APP_SECRET, redirect_uri=CALLBACK_URL)
print(client.get_authorize_url())
#step 3 换取Access Token
r = client.request_access_token(input("Input code:"))#输入授权地址中获得的CODE
client.set_access_token(r.access_token, r.expires_in)
#step 4 使用获得的OAuth2.0 Access Token调用API
print(client.get.account__get_uid())
print(client.post.statuses__update(status='测试Python3 + OAuth 2.0发微博 ' + str(time.time())))
#print(client.upload.statuses__upload(status='测试Python3 OAuth 2.0带图片发微博 ' + str(time.time()), pic=open('test.png', 'rb'))) except Exception as pyOauth2Error:
print(pyOauth2Error) if __name__ == '__main__':
main()
新浪微博Python3客户端接口OAuth2的更多相关文章
- 新浪微博Python客户端接口OAuth2
Keyword: Python Oauth2 微博 sina weibo #!/usr/bin/env python # -*- coding: utf-8 -*- __version__ = '1. ...
- 新浪微博iOS客户端架构与优化之路
新浪微博iOS客户端架构与优化之路 随着Facebook.Twitter.微博的崛起,向UGC.PGC.OGC,自媒体提供平台的内 容消费型App逐渐形成了独特的客户端架构模式.与电商和通讯工具类 ...
- cxf的使用及安全校验-02创建简单的客户端接口
上一篇文章中,我们已经讲了如果简单的创建一个webservice接口 http://www.cnblogs.com/snowstar123/p/3395568.html 现在我们创建一个简单客户端接口 ...
- Warensoft Stock Service Api客户端接口说明
Warensoft Stock Service Api客户端接口说明 Warensoft Stock Service Api Client Reference 可使用环境(Available Envi ...
- HBase新的客户端接口
最近学习接触HBase的东西,看了<Habase in Action>,但里面关于HBase接口都是过时的接口,以下为HBase新的客户端接口: package com.n10k; imp ...
- 【python3+request】python3+requests接口自动化测试框架实例详解教程
转自:https://my.oschina.net/u/3041656/blog/820023 [python3+request]python3+requests接口自动化测试框架实例详解教程 前段时 ...
- Python3简易接口自动化测试框架设计与实现(中)
目录 7.Excel数据读取 7.1.读取配置文件 7.1.编写Excel操作类 8.用例组装 9.用例运行结果校验 10.运行用例 11 .小结 上一篇:Python3简易接口自动化测试框架设计与实 ...
- 新浪微博API OAuth1 Python3客户端
#!/usr/local/bin/python3 # coding=gbk # http://www.cnblogs.com/txw1958/ # import os, io, sys, re, ti ...
- 高级接口--OAuth2.0网页授权
官方文档 Auth是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某以网站,移动或桌面应用上存储的司名的资源(如用户个人信息,照片,视频,联系人列表),而无需将用户名和密码提供给第三 ...
随机推荐
- 基于PHP实现一个简单的在线聊天功能(轮询ajax )
基于PHP实现一个简单的在线聊天功能(轮询ajax ) 一.总结 1.用的轮询ajax 二.基于PHP实现一个简单的在线聊天功能 一直很想试着做一做这个有意思的功能,感觉复杂的不是数据交互和表结构,麻 ...
- matlab 程序发布
将matlab程序发布为可执行程序包 说明,这种可执行程序包可以在没有安装matlab的计算机上运行. 1. 打开Applicaiton Compler 如果下拉列表中没有这个APPLICATIOND ...
- [Angular2 Form] Nested formGroup, and usage of formGroupName
We can nest formGorup: this.reactiveForm = fb.group({ username: [ '', [ Validators.required, Validat ...
- LIVE555源代码研究之四:MediaServer (一)
LIVE555源代码研究之四:MediaServer (一) 从本篇文章開始我们将从简单server程序作为突破点,深入研究LIVE555源代码. 从前面的文章我们知道.不论什么一个基于LIVE555 ...
- Java文档上传问题设计
近期公司让做一个文档上传的功能,功能描写叙述大概是这样子滴 书籍名称.书籍定价.书籍封面图片(须要上传).文档内容 (须要上传) .还有其它相关的描写叙述信息. 我的设计 表 A 包括以上字段 , ...
- Spring web 工具类 WebApplicationContextUtils
概述 Spring web 的工具类 WebApplicationContextUtils 位于包 org.springframework.web.context.support 是访问一个Servl ...
- 【源代码】Timer和TimerTask源代码剖析
Timer是java.util包中的一个工具类,提供了定时器的功能. 我们能够构造一个Timer对象,然后调用其schedule方法在某个特定的时间或者若干延时之后去运行一个特定的任务.甚至你能够让其 ...
- 一个神奇的控件——Android CoordinatorLayout与Behavior使用指南
CoordinatorLayout是support.design包中的控件,它可以说是Design库中最重要的控件. 本文通过模仿知乎介绍了自定义Behavior,通过模仿百度地图介绍了BottomS ...
- Android多线程研究(9)——线程锁Lock
在前面我们在解决线程同步问题的时候使用了synchronized关键字,今天我们来看看Java 5.0以后提供的线程锁Lock. Lock接口的实现类提供了比使用synchronized关键字更加灵活 ...
- 《编程导论(Java)·3.2.4 循环语句》
本文全然复制<编程导论(Java)·3.2.4 循环语句>的内容.除[]中的说明文字.请阅读和比較其它编程教材. 我知道.假设我是一个刚開始学习的人,<编程导论(Java)>非 ...