Skip to content

Instantly share code, notes, and snippets.

@comtom
Created September 13, 2017 18:07
Show Gist options
  • Select an option

  • Save comtom/4aa4c28f5386c92b44c29715473c059f to your computer and use it in GitHub Desktop.

Select an option

Save comtom/4aa4c28f5386c92b44c29715473c059f to your computer and use it in GitHub Desktop.
import asyncio
import aiomysql
loop = asyncio.get_event_loop()
# async def main(all_done):
# """Get all messages."""
# conn = await aiomysql.connect(host='127.0.0.1', port=3306, user='test',
# password='test123', db='test', loop=loop)
#
# cur = await conn.cursor(aiomysql.DictCursor)
# await cur.execute("SELECT receiver, message FROM messages")
# r = await cur.fetchall()
#
# await cur.close()
# conn.close()
# all_done.set_result(r)
class DBConnection(object):
"""Async context manager that makes a connection to db."""
def __init__(self, host, port, user, password, db):
self.conn = None
self.cur = None
self.host = host
self.port = port
self.user = user
self.password = password
self.db = db
async def __aenter__(self):
"""Enter async context manager."""
self.conn = await aiomysql.connect(host=self.host, port=self.port,
user=self.user, password=self.password, db=self.db, loop=loop)
self.cur = await self.conn.cursor(aiomysql.DictCursor)
return self.cur
async def __aexit__(self, *args):
"""Exit async context manager."""
await self.cur.close()
self.conn.close()
async def alternative(all_done):
"""Get all messages."""
async with DBConnection(host='127.0.0.1', port=3306, user='test',
password='test123', db='test') as cur:
await cur.execute("SELECT receiver, message FROM messages")
r = await cur.fetchall()
all_done.set_result(r)
"""Testing falcon.
This module contains a webservice that provides user authentication.
three endpoints are defined; login, logout and update, that allows the server
to track session times.
Remember to add more than one worker; so the emulated webservice can respond,
while the login endpoint is waiting to that ws response. Otherwise, the
request would never finish.
$ gunicorn sessions:app -w 2
"""
import falcon
import json
import requests
import sys
import asyncio
from db import alternative
class Messages(object):
"""Test an async conection to a mysql instance."""
def on_get(self, request, response):
"""Handle GET requests."""
response.status = falcon.HTTP_200
loop = asyncio.get_event_loop()
all_done = asyncio.Future()
asyncio.ensure_future(alternative(all_done))
loop.run_until_complete(all_done)
response.body = json.dumps(all_done.result())
class Ws(object):
"""Emulates a external webservice that contains user updated data."""
def on_get(self, request, response):
"""Handle GET requests."""
response.status = falcon.HTTP_200
response.body = json.dumps({'status': 10,
'first_name': 'Mick',
'last_name': 'Jagger',
'version': sys.version})
class Login(object):
"""Try to login with a card-id."""
def on_get(self, request, response):
"""Handle GET requests."""
card = request.get_param('card', required=True)
if not (len(card) == 8 or len(card) == 10):
raise falcon.HTTPInvalidParam('Invalid card number',
'card')
r = requests.get('http://localhost:8000/ws', params={})
if not r:
raise falcon.HTTPError('444', 'No response',
'API endpoint did not responded')
resp = r.json()
response.status = falcon.HTTP_200
if resp['status'] != 0 and resp['status'] != 1:
response.body = json.dumps({'success': True, 'reboot': False,
'card': card})
else:
response.body = json.dumps({'success': False, 'reboot': False,
'card': card})
class Update(object):
"""Updates session time."""
def on_get(self, request, response):
"""Handle GET requests."""
try:
time = int(request.get_param('time', required=True))
except ValueError:
raise falcon.HTTPInvalidParam('', 'time')
card = request.get_param('card', required=True)
if not (len(card) == 8 or len(card) == 10):
raise falcon.HTTPInvalidParam('Invalid card number',
'card')
if time > 0:
response.status = falcon.HTTP_200
response.body = json.dumps({'success': True, 'logout': False,
'card': card})
else:
raise falcon.HTTPError('timeError', 'Your session is over.', 'Current \
session hasn\'t more time available.')
class Logout(object):
"""Logout current user."""
def on_get(self, request, response):
""""Handle GET requests."""
time = request.get_param('time', required=False)
card = request.get_param('card', required=False)
if time > 0:
self.update_time(time)
else:
self.close_active_session()
response.status = falcon.HTTP_200
response.body = json.dumps({'success': True, 'logout': False,
'card': card})
def update():
"""Save time on session."""
pass
def close_session():
"""Mark the session as closed."""
pass
class RebootOrHalt(object):
"""Reboot a client."""
def __init__(self, action='reboot'):
"""Initialize object."""
self.action = action
def on_get(self, request, response):
""""Handle GET requests."""
ip = request.get_param('ip', required=True)
try:
r = requests.get('http://{}:9000/{}'.format(ip, self.action))
except requests.exceptions.ConnectionError:
r = None
if not r:
raise falcon.HTTPError('444', 'No response',
'API endpoint did not responded')
response.status = falcon.HTTP_200
response.body = json.dumps({'success': True})
class MicroService(object):
"""Constructs a microservice with falcon."""
def __init__(self):
"""Initialize falcon object."""
self.app = falcon.API()
class App:
"""Constructs an app handler."""
@classmethod
def main(cls, name):
"""Setup routes."""
if __name__ in [name, '__main__']:
poronga.add_route('/ws', Ws())
poronga.add_route('/login', Login())
poronga.add_route('/update', Update())
poronga.add_route('/logout', Logout())
poronga.add_route('/messages', Messages())
poronga.add_route('/reboot', RebootOrHalt('reboot'))
poronga.add_route('/halt', RebootOrHalt('halt'))
poronga = MicroService().app
App.main('sessions')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment