Package: p2py
What is p2pyIt's a simple peer to peer networking library based onChordmade forIPDS project.The goal of this project is to create a extraordinarly simple to use yet powerfull peer to peer networking library for Python. It's created forIPDS projectbut can be used by everyone with ease.Why p2py?That's why:It's plug-and-play,It's easy to use,It's customizableFeaturesP2py is packed with many usefull features that will help you build your p2p app faster:TCP Hole PunchingChord routing system(So you can connect to other node jus using it's numeric ID)Temporary / constant connectionsSending any type of data(that can be represented in bytes)MessagesRequests(p2py's experimental approach that will save you some time)Built-in text message typeTools for defining and handling your own message typesInstallationInstall withpipusing the command:$ pip install p2pySimple examplesJoining the network and sending text messageNode B joins the network of Node ANode A(172.17.0.2:4444)  UUID 0importp2py,timenode=p2py.Node(4444)#Create a node listening on port 4444node.start()#Start the nodewhileTrue:#Wait forevertime.sleep(1)#Listening on 172.17.0.2:4444#(172.11.0.3:4444) -> "Hi!"Node B(172.11.0.3:4445) UUID 1importp2py,timenode=p2py.Node(4445)#Create a node listening on port 4444node.start()#Start the nodenode.join_network((('172.17.0.2',4444)))#Join the network of Node Awhilenotnode.joined():#Wait until the node joins the networktime.sleep(1)msg={#Construct a message'type':'text','data':"Hi!"}node.send_to_UUID(UUID=0,msg=msg)#Send a message to Node A#Listening on 172.11.0.3:4444#Successfully joined the network! Your UUID is 1#Sent message to UUID 0Define custom request type and send requestIn this example I will define a custom request type thet will add 1 to a requested number and return the result bact to requesting peer.Node A(172.17.0.2:4444)importp2py,timenode=p2py.Node(4444)#Create a node listening on port 4444defhandle_add(node,conn,request):#Define a handlern=request.contents['data']#Get data from requestn_plus_one=n+1#Process the dataresp={#Construct a response'type':'ADD RESP','data':n_plus_one}request.respond(resp)#Respondnode.add_handler("ADD",handle_add)#Assign the handler to "ADD" message typenode.start()#Start the nodewhileTrue:#Wait forevertime.sleep(1)#Listening on 172.17.0.2:4444Node B(172.11.0.3:4445)importp2py,timenode=p2py.Node(4445)#Create a node listening on port 4444node.start()#Start the nodenode.join_network((('172.17.0.2',4444)))#Join the network of Node Awhilenotnode.joined():#Wait until the node joins the networktime.sleep(1)msg={#Construct a request'type':'ADD','data':17}resp=node.request(UUID=0,request_msg=msg)#Send a request to Node A and receive responseresult=resp['data']print(f"17 + 1 ={result}")#Listening on 172.11.0.3:4444#Successfully joined the network! Your UUID is 1#Sent message to UUID 0#17 + 1 = 18DocumentationThis is documentation of some high level functions (there is a lot more)p2py.Node(port,host[opt])Creates node object. It will listen for connections on specifiedport [int]. Ifhost [str]was not specified it will run on localhost (127.0.0.1)Example:example_node=Node(4444)Functions:Node**.connect_to_network(address_list)**Connects node to network of peer whichaddress_list [tuple]was given. Argumentaddress_listis a list of 2-tuples of host (str) and port (int):(HOST [str], PORT [int]).Example:example_node.connect_to_network([('127.0.0.1',1234)])Node.send_to_UUID(UUID,message)Creates a temporary connection withUUID [Int](that means it will be closed after sending the message) and sendsmessage [dict].Messageis a JSON dict it this form:{'type':MESSAGE_TYPE,'data':MESSAGE_DATA}Example:message={'type':'TEXT','data':'Hello!'}example_node.send_to_UUID(7,message)#sends hello to UUID 7Node.send_to_address(address,message)Creates a temporary connection withaddress [2-tuple](that means it will be closed after sending the message) and sendsmessage [dict].Example:message={'type':'TEXT','data':'Hello!'}example_node.send_to_address(('127.0.0.1',1234),message)#sends hello to 127.0.0.1:1234Node.send_to_connection(connection,message)Sendsmessage[dict]toconnection[Connection]**.Example:message={'type':'TEXT','data':'Hello!'}conn=get_connection_object()#this is a pseudo function. Don't try it as it doesnt existexample_node.send_to_connection(conn,message)#sends hello to connNode.request(UUID[opt],address[opt],connection[opt],request_msg)Sendsrequest[Request]toUUID[Int]** ORaddress[2-tuple]** ORconnection[Connection]** (at least one has to be specified). It returnsdictas a response orNoneTypeif there is no response.The requested node receivesRequest object. You can learn about handling requestsin this sectionExample:request={'type':'ADD','data':17}resp=example_node.request(UUID=7,request_msg=request)print(f"17 + 1 ={resp['data']}")Node.send_to_peer_book(message,exclude [opt])Sendsmessage [dict]to all peers in your peer book optionally excluding UUIDs[Int] inexclude [List]Example:message={'type':'TEXT','data':'Hello peer book!'}example_node.send_to_peer_book(message)#sends "Hello peer book!" to peer bookNode.close_all_connections()Closes all connections. It's synonymous to leaving the networkExample:example_node.close_all_connections()#left the networkNode.add_handler(message_type[str],handler[func])Defines a handler for a givenmessage_type. It takes 2 arguments:message_typeandhandlerfunction.Handlerfunction has to take 3 arguments:node- a pointer to the local node,conn- Connection object from which the request was sent,request- Request object sent by requesting node.Example:defsome_function(node,conn,request):#do somethingnode.add_handler("some type",some_function)node.start()VariablesNode.UUID [Int]This variable holds node's UUID. It's set toNonewhen node is not connected to any network.Example:print(example_node.UUID)#3Node.network_size [Int]This variable holds info about the number of peers in the network Node is connected toExample:print(example_node.network_size)#77p2py.Request(callback_address,contents)Creates request objectRequest.respond(response[dict])Sends theresponseto the requester.Example:msg={'type':'SOME RESP','data':'some data'}request.respond(msg)Request.bounce(address[opt],UUID[opt])Sends the requests to another node specified by eitheraddressORUUID.The request will be processed by another peerbut the response will be sent to the same requester.Example:#Oh no! I can't answer the request. Maybe UUID 7 knows the answerrequest.bounce(UUID=7)Message typesThere are many types of messages that do different things. These are some high-level ones:type TEXTmessage={'type':'TEXT','data':text_message}