To my knowledge, the only way to get/set socket options in Python is on a socket object (or using ctypes, which I won’t count here). When asyncio servers spawn client tasks, there’s no socket object, just generic readers and writers. What is the recommended way to query socket options?
What I was able to do involves grabbing private attributes, not something I’d normally want to do.
import os
import socket
import asyncio
def getsockopt(fd, level, opt):
sock = socket.socket(fileno=fd)
try: return sock.getsockopt(level, opt)
finally: sock.detach() # Detach even if we hit an error of some sort
async def client(reader, writer):
print("Got connection", reader)
fd = reader._transport._sock_fd
pid = getsockopt(fd, socket.SOL_SOCKET, socket.SO_PEERCRED);
print("Connection from", pid)
async def main():
print("I am", os.getpid())
await asyncio.start_unix_server(client, "/tmp/samplesocket")
await asyncio.Future()
asyncio.run(main())
Connect to this socket using another process, and it should correctly report your process ID. (This example uses a Unix socket - sorry Windows folks - but to my knowledge, this should also apply to TCP socket options.)
Is there a better way to do this? If not, should there be?
EDIT TO ADD: There is a tempting-looking API writer.get_extra_info("sock") but it returned None so I don’t know whether this fails on Unix sockets or if something else is wrong, but that was a dead end for me.