#!/usr/bin/env python3.14# -*- coding: utf-8 -*-"""Minimal HTTP-over-unix-socket client, shared by the service tiers (stdlib only).Used by the callers that must not depend on aiohttp — the shell commands and theidentity resolver, which run inside the solver process:- the `users` shell command (:mod:`euler_webshell.users`) → the auth admin socket;- shell-ticket redemption (:mod:`solver.auth.identity`) → the auth public socket;- the `msg` shell command (:mod:`euler_webshell.msg.commands`) → the message spool.Deliberately tiny: JSON in/out, one request per connection, no retries — everysocket is local and the service answers immediately or not at all.This lives at :mod:`euler_site` rather than under one service package so a secondservice can use it without importing the first: :mod:`euler_webshell.msg` must not pull:mod:`euler_site.auth` into its process (web-server-guide § Messaging)."""from__future__importannotations__all__=['request']importhttp.clientimportjsonimportsocketfromtypingimportAnyclass_UnixConnection(http.client.HTTPConnection):"""An HTTPConnection whose transport is a unix domain socket."""def__init__(self,socket_path:str,timeout:float)->None:super().__init__('localhost',timeout=timeout)self._socket_path=socket_pathdefconnect(self)->None:sock=socket.socket(socket.AF_UNIX,socket.SOCK_STREAM)try:sock.settimeout(self.timeout)sock.connect(self._socket_path)exceptBaseException:# A failed connect never reaches `self.sock`, so the caller's `close()` in# `request()` cannot reach this socket either — without closing it here the fd# leaks. That is the *expected* path for two callers, not a rare one: the `msg`# command probes the public socket on every invocation from the operator's# terminal (which is deliberately not in euler-web), and `notify_staff` runs on# every checkout with no spool deployed.sock.close()raiseself.sock=sockdefrequest(socket_path:str,method:str,path:str,*,body:dict[str,Any]|None=None,headers:dict[str,str]|None=None,timeout:float=10.0)->tuple[int,dict[str,Any]|str]:"""One HTTP request over the unix socket; return `(status, parsed body)`. The body comes back as a dict when the response is JSON, else as text. Raises OSError if the socket is absent/refusing (service not running or the caller lacks group access). """connection=_UnixConnection(socket_path,timeout)try:payload=json.dumps(body).encode()ifbodyisnotNoneelseNoneall_headers={'Content-Type':'application/json',**(headersor{})}connection.request(method,path,body=payload,headers=all_headers)response=connection.getresponse()raw=response.read().decode('utf-8','replace')try:parsed:dict[str,Any]|str=json.loads(raw)ifnotisinstance(parsed,dict):parsed=rawexceptjson.JSONDecodeError:parsed=rawreturnresponse.status,parsedfinally:connection.close()