[Python] Python HTTPX multi-client architecture design concerns

Discussão em 'Python' iniciado por Stack, Fevereiro 22, 2025.

  1. Stack

    Stack Membro Participativo

    I am attempting to write a set of API calls for multiple different hardware types. Each hardware type is likely to have slightly different connection requirements, for example some will use a nonce (with incrementation) and digest authentication, others (old ones) will only use basic authentication, and some will want to use only HTTPS while other only HTTP. A mixed bag. Each manufacturer also has their own set of API calls which can be executed by either GET or POST (and with one exception PUT). A network will likely have a mix of equipment, possibly in the thousands of devices. That's the operating environment.

    The objective is to initialise / interrogate / program these devices via their API calls and do so from a set of configuration templates. This way the devices can be installed, configured, and verified far more quickly than having a few techs sit around doing it by hand - and don't even start me on the error checking and QA concerns. This means that I am going to need to be able to execute potentially tens to hundreds of API calls to hundreds if not thousands of devices on a LAN (no WAN work for this - everything is IP4 LAN only).

    What I want to try and do is reduce the code complexity as much as possible but I am hitting a 'design wall' that I cannot think my way through - I don't know how to approach this elegantly and simply.

    If I use the HTTPX client as the basis for communications I know that I can implement basic and digest authentication, store cookies and so forth. Is there a way to factory create the httpx.client instances while simultaneously customising the httpx.client behaviour to suit each of the individual connection types (device requirements)? Would I be better off extending the class into a zoo of new client types? Am I overcomplicating this? Can the clients and pools be run in parallel (processes) to massively speed up the operations? Will this affect object disposal if I am using a factory instead of a context manager? Will the connection pooling still work?

    FWIW there is nothing particularly special about the API calls themselves, they appear (according to the manufacturers documentation) to be quite ordinary GET / POST (and occasionally PUT) calls. It will probably take me about 6 months to code them all in from the paperwork but the end result - assuming I can achieve it - will be well worth it. The devices just have their own quirks for handling and maintaining connections.

    Some example code for the factory:

    @staticmethod
    def newHTTPConnection(address:str,target_port:int,username:str,password:str, authentication:bool = True) -> httpx.Client:
    try:
    if not type(address) is str: raise TypeError('Client address must be either valid url or IP4 address')
    if not type(target_port) is int: raise TypeError('The target_port value on target device must be an integer between 1 and 65535')
    if not 1 < target_port < 65535: raise ValueError('The target_port value on target device must be an integer between 1 and 65535')
    if not type(username) is str: raise TypeError('The username for authentication must be a valid string')
    if not type(password) is str: raise TypeError('The password for authentication must be a valid string')
    if not type(authentication) is bool: raise TypeError('The authentication type must be boolean (optional) and defaults to True for Digest Authentication')
    except:
    client = httpx.Client()
    else:
    #establish the necessary construction logic for the connection here
    if authentication:
    digestAuth = httpx.DigestAuth(username,password)
    client = httpx.Client(auth=digestAuth,base_url=address + ':' + str(target_port))
    else:
    client = httpx.Client(auth=(username,password),base_url=address + ':' + str(target_port))

    finally:
    return client


    Any help or guidance is greatly appreciated.

    Cheers

    The Frog

    Continue reading...

Compartilhe esta Página