A ReST client created by Yann Kaiser (me)
CS student at EFREI ; SE Intern at Criteo
clize:
def hello_world(name=None, *, no_capitalize=False):
$ python hello.py dave --no-capitalize
Or rather, what is it not?
A.K.A. urlib2
, urllib.request
,
six.moves.urllib.request
passwords = urllib.request.HTTPPasswordMgrWithPriorAuth()
passwords.add_password("reddit", "https://www.reddit.com/",
CLIENT_ID, CLIENT_SECRET,
is_authenticated=True)
opener = urllib.request.build_opener(
urllib.request.HTTPBasicAuthHandler(passwords))
opener.addheaders = [('User-agent', 'A urllib example/0.1')]
if not access_token:
r = opener.open(
"https://www.reddit.com/api/v1/access_token",
urllib.parse.urlencode({
'grant_type': 'authorization_code',
'code': USER_CODE,
'redirect_uri': REDIR_URL,
}).encode('utf8'))
with r:
doc = json.load(io.TextIOWrapper(r, 'utf8'))
print(doc)
access_token = doc['access_token']
opener.addheaders.append(("Authorization", "bearer " + access_token))
msgs = opener.open("https://oauth.reddit.com/message/sent?limit=1")
print(msgs.read().decode('utf8'))
A.K.A. Phew, I don't actually have to use urllib
session = requests.Session()
session.headers['User-agent'] = "requests example/0.1"
if not access_token:
r = session.post(
"https://www.reddit.com/api/v1/access_token",
{ 'grant_type': 'authorization_code', 'code': USER_CODE,
'redirect_uri': REDIR_URL },
auth=(CLIENT_ID, CLIENT_SECRET))
doc = r.json()
access_token = doc['access_token']
session.headers['Authorization'] = "bearer " + access_token
r = session.get("https://oauth.reddit.com/message/sent?limit=1")
for msg in r.json()['data']['children']:
msgdata = msg['data']
print(msgdata["subject"], "\n", msgdata["body"])
A.K.A. Hey I can use asyncio
now!
session = aiohttp.ClientSession(headers={'User-agent': "aiohttp example/0.1"})
async def req():
global access_token
if not access_token:
r = await session.post(
"https://www.reddit.com/api/v1/access_token",
{ 'grant_type': 'authorization_code', 'code': USER_CODE,
'redirect_uri': REDIR_URL })
doc = await r.json()
access_token = doc['access_token']
session._default_headers['Authorization'] = "bearer " + access_token
r = await session.get("https://oauth.reddit.com/message/sent?limit=1")
for msg in (await r.json())['data']['children']:
msgdata = msg['data']
print(msgdata["subject"], "\n", msgdata["body"])
with session:
asyncio.get_event_loop().run_until_complete(req())
It specializes in ReST HTTP requests
ReST to Python mapper
Python ⇒ Need to use a pun
ReST ≡ to rest ≡ to (take a) nap
nap + mapper = napper
from napper import SessionFactory
httpbin = SessionFactory.from_address('http://httpbin.org/')
async def using_httpbin():
with httpbin() as site:
# GET http://httpbin.org/cookies/set?spam=ham
print(await site.cookies.set.get(spam='ham'))
# GET http://httpbin.org/cookies
print(await site.cookies.get())
asyncio.get_event_loop().run_until_complete(using_httpbin())
from napper.apis import reddit
async def napper_example():
async with reddit() as site:
async for msg in site.message.sent.get(limit=1):
print(msg["subject"], "\n", msg["body"])
asyncio.get_event_loop().run_until_complete(napper_example())
from napper.apis import github
async def getstargazers():
with github() as site:
async for gist in site.gists.get():
try:
repo = await gist.owner.repos_url.get()[0]
except AttributeError, IndexError:
pass # No owner or no repos
print("{0.owner.login} {1.name} {1.stargazers_count}"
.format(gist, repo))
asyncio.get_event_loop().run_until_complete(getstargazers())
It's in alpha stage
It's for Python 3.5+ only
It's not documented yet
It's in alpha stage
It's for Python 3.5+ only
It's easy to use anyway
The "login" workflow
WebSocket support
Handling of dripping responses
XML support?
Web hook/callback support?
You tell me!
python3.5 -m pip install --user napper
Source: https://github.com/epsy/napper
Slides: https://epsy.github.io/napper/
Chat: https://gitter.im/epsy/napper