Package: easynetwork
EasyNetworkThe easiest way to use sockets in Python!InstallationFrom PyPI repositorypipinstall--usereasynetworkFrom sourcegitclonehttps://github.com/francis-clairicia/EasyNetwork.gitcdEasyNetwork
pipinstall--user.OverviewEasyNetwork completely encapsulates the socket handling, providing you with a higher level interface
that allows an application/software to completely handle the logic part with Python objects,
without worrying about how to process, send or receive data over the network.The communication protocol can be whatever you want, be it JSON, Pickle, ASCII, structure, base64 encoded,
compressed, encrypted, or any other format that is not part of the standard library.
You choose the data format and the library takes care of the rest.Works with TCP and UDP.UsageTCP Echo server with JSON dataimportasyncioimportloggingfromcollections.abcimportAsyncGeneratorfromtypingimportAny,TypeAliasfromeasynetwork.api_async.serverimport(AsyncStreamClient,AsyncStreamRequestHandler,AsyncTCPNetworkServer,)fromeasynetwork.protocolimportStreamProtocolfromeasynetwork.serializersimportJSONSerializer# These TypeAliases are there to help you understand# where requests and responses are used in the codeRequestType:TypeAlias=AnyResponseType:TypeAlias=AnyclassJSONProtocol(StreamProtocol[ResponseType,RequestType]):def__init__(self)->None:super().__init__(JSONSerializer())classEchoRequestHandler(AsyncStreamRequestHandler[RequestType,ResponseType]):def__init__(self)->None:self.logger:logging.Logger=logging.getLogger(self.__class__.__name__)asyncdefhandle(self,client:AsyncStreamClient[ResponseType],)->AsyncGenerator[None,RequestType]:data:Any=yield# A JSON request has been sent by this clientself.logger.info(f"{client!r}sent{data!r}")# As a good echo handler, the request is sent back to the clientawaitclient.send_packet(data)# Leaving the generator will NOT close the connection,# a new generator will be created afterwards.# You may manually close the connection if you want to:# await client.aclose()asyncdefmain()->None:host=None# Bind on all interfacesport=9000protocol=JSONProtocol()handler=EchoRequestHandler()logging.basicConfig(level=logging.INFO,format="[%(levelname)s] [%(name)s]%(message)s",)asyncwithAsyncTCPNetworkServer(host,port,protocol,handler)asserver:try:awaitserver.serve_forever()exceptasyncio.CancelledError:passif__name__=="__main__":asyncio.run(main())TCP Echo client with JSON datafromtypingimportAny,TypeAliasfromeasynetwork.api_sync.clientimportTCPNetworkClientfromeasynetwork.protocolimportStreamProtocolfromeasynetwork.serializersimportJSONSerializerRequestType:TypeAlias=AnyResponseType:TypeAlias=AnyclassJSONProtocol(StreamProtocol[RequestType,ResponseType]):def__init__(self)->None:super().__init__(JSONSerializer())defmain()->None:withTCPNetworkClient(("localhost",9000),JSONProtocol())asclient:client.send_packet({"data":{"my_body":["as json"]}})response=client.recv_packet()# response should be the sent dictionaryprint(response)# prints {'data': {'my_body': ['as json']}}if__name__=="__main__":main()Asynchronous version ( withasync def)importasynciofromtypingimportAny,TypeAliasfromeasynetwork.api_async.clientimportAsyncTCPNetworkClientfromeasynetwork.protocolimportStreamProtocolfromeasynetwork.serializersimportJSONSerializerRequestType:TypeAlias=AnyResponseType:TypeAlias=AnyclassJSONProtocol(StreamProtocol[RequestType,ResponseType]):def__init__(self)->None:super().__init__(JSONSerializer())asyncdefmain()->None:asyncwithAsyncTCPNetworkClient(("localhost",9000),JSONProtocol())asclient:awaitclient.send_packet({"data":{"my_body":["as json"]}})response=awaitclient.recv_packet()# response should be the sent dictionaryprint(response)# prints {'data': {'my_body': ['as json']}}if__name__=="__main__":asyncio.run(main())LicenseThis project is licensed under the terms of theApache Software License 2.0.