Requests で Docker Remote API にアクセスする
Posted: , Modified: Python Docker Requests Qiita
本稿は Qiita 投稿記事 のバックアップです.
概要
Python Requests から Docker Remote API を利用したい. 暗号化を行えば TCP からでも利用できるが,API を同じホストから利用することを考えているため unix ソケットを使う.
Unix ソケットの読み書き
Docker のソケットファイルは /var/run/docker.sock
にある.ソケットファイルの読み書きは,次の通り.
import socket
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect("/var/run/docker.sock")
# s.recv, s.send, etc.
Requests で独自ソケットを使う
こちらはかなり面倒で,Transport Adapterを実装する必要がある.そして,そのためには,PoolManager,HTTPConnectionPool,HTTPConnection も合わせて実装する必要がある.
import socket
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3 import PoolManager, HTTPConnectionPool
from httplib import HTTPConnection
class MyAdapter(HTTPAdapter):
def __init__(self, sockfile, **kwargs):
self._sockfile = sockfile
super(MyAdapter, self).__init__(**kwargs)
def init_poolmanager(self, connections, maxsize, **kwargs):
self.poolmanager = MyPoolManager(self._sockfile,
num_pools=connections, maxsize=maxsize)
class MyPoolManager(PoolManager):
def __init__(self, sockfile, **kwargs):
self._sockfile = sockfile
super(MyPoolManager, self).__init__(**kwargs)
def _new_pool(self, scheme, host, port):
return MyConnectionPool(self._sockfile, host, port, **self.connection_pool_kw)
class MyConnectionPool(HTTPConnectionPool):
def __init__(self, sockfile, host, port, **kwargs):
self._sockfile = sockfile
super(MyConnectionPool, self).__init__(host, port, **kwargs)
def _new_conn(self):
self.num_connections += 1
return MyConnection(self._sockfile,
host=self.host, port=self.port, strict=self.strict)
class MyConnection(HTTPConnection):
def __init__(self, sockfile, **kwargs):
self._sockfile = sockfile
HTTPConnection.__init__(self, **kwargs)
def connect(self):
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.sock.connect(self._sockfile)
if self._tunnel_host:
self._tunnel()
HTTPConnection は old-style クラスなので,初期化方法に注意.
API の利用
利用例は次の通り.
req = requests.Session()
req.mount("http://", MyAdapter("/var/run/docker.sock"))
print req.get("http://127.0.0.1/images/json?all=0").json()
http://127.0.0.1 と書いているところがダサい・・・.
参考