先日書いた記事で必要なことを、さくっとできるようにライブラリにしてPyPiに登録してみました。
どんなライブラリ
requests
を使って取得したcookieをシームレスにwebsocket-client
に引き渡すラッパーライブラリです。connect
を実行する際に、その時点で保持しているrequests
のcookieをすべて文字列に変換して引き渡すことで、セッション情報を共有しながらwebsocket
の接続をできるようにしています。
使用例
インストールはpip
だけでできます。
$ pip install wsrequests
簡単な使い方はこんな感じになります。
from wsrequests import WsRequests wsr = WsRequests() # login django wsr.get('http://localhost:3000/login') wsr.post( 'http://localhost:3000/login', data={ 'username': 'your name', 'password': 'your password', 'csrfmiddlewaretoken': wsr.cookies['csrftoken'], 'next': '/', } )
WsRequests
をインスタンス化した時点で内部的にはrequests.session()
でセッションが生成されます。get
やpost
はそのままそのセッションインスタンスのメソッドとして呼び出されるので、インターフェースはrequests
そのままです。
ここまで問題なければセッションはログイン状態になっていますので、以下のようにWebSocket
の処理ができます。
# connect websocket wsr.connect('ws://localhost:3000/ws/room') wsr.send_message({'message': 'ping'}) wsr.receive_message() wsr.disconnect()
内部的な話
WsRequests
の説明にも書いてありますが、こいつはrequests
の薄いラッパーです。get
やpost
を始めとした大半のメソッドはrequests
を使うようにし、WebSocket
関連の処理だけwebsocket-client
を使ったメソッドを呼び出せるようにすれば要件を満たせます。
ということで、実装はこんな感じになっています。
class WsRequests: def __init__(self, proxy_url=None, proxy_port=None, proxy_username=None, proxy_password=None, logger=None): : : self.http_client = self._get_http_client() : def __getattr__(self, attr_name): """ Access for not defined attribute dispatch to requests. :param str attr_name: :return: """ return getattr(self.http_client, attr_name) : def _get_http_client(self): """ get requests session instance :return: """ client = requests.session() if self.is_valid_proxy: client.trust_env = False client.proxies.update({ 'http': self._get_proxy_url(), 'https': self._get_proxy_url(), }) for proxy in client.proxies: self.logger.debug('use proxy [{}]'.format(proxy)) return client
インスタンス化した時点でself._get_http_client
を呼び出し、その中でrequests.session()
で取得したインスタンスを戻し、self.http_client
にセットしています。そして、ポイントは__getattr__
をオーバライドし、属性の呼び出しはself.http_client
にディスパッチしています。こうすることでWsRequests
自身が実装しているメソッド以外はrequests.session()
のものが呼び出されるので、ほとんどrequests
のインターフェースを保った形になっています。
最後に
とりあえず、必要な機能は実装できていますが今後要件が増えたら随時機能追加をしていこうと思います。