🍣
【Python】asyncio で HTTP/1 クライアントをつくる
公式マニュアルのサンプルコードをコピペして送るメッセージを修正すれば HTTP/1 クライアントになる
client.py
import asyncio
# https://docs.python.org/ja/3/library/asyncio-stream.html#tcp-echo-client-using-streams
async def tcp_client(host, port, message):
reader, writer = await asyncio.open_connection(
host, port)
print(f'Send: {message!r}')
writer.write(message.encode())
await writer.drain()
data = await reader.read(1024)
print(f'Received: {data.decode()!r}')
print('Close the connection')
writer.close()
await writer.wait_closed()
host = '127.0.0.1'
port = 8000
message = "GET / HTTP/1.1\r\n\r\n"
asyncio.run(tcp_client(host, port, message))
asyncio.Protocol
を継承するクラスの例は次のようになる
client.py
import asyncio
# https://docs.python.org/ja/3.13/library/asyncio-protocol.html#tcp-echo-client
class ClientProtocol(asyncio.Protocol):
def __init__(self, message, on_con_lost):
self.message = message
self.on_con_lost = on_con_lost
def connection_made(self, transport):
transport.write(self.message.encode())
print('Data sent: {!r}'.format(self.message))
def data_received(self, data):
print('Data received: {!r}'.format(data.decode()))
def connection_lost(self, exc):
print('The server closed the connection')
self.on_con_lost.set_result(True)
async def main():
host = '127.0.0.1'
port = 8000
message = "GET / HTTP/1.1\r\n\r\n"
loop = asyncio.get_running_loop()
on_con_lost = loop.create_future()
transport, protocol = await loop.create_connection(
lambda: ClientProtocol(message, on_con_lost),
host, port)
try:
await on_con_lost
finally:
transport.close()
asyncio.run(main())
Discussion