Skip to content

Commit

Permalink
Refine the docstrings and typing for server
Browse files Browse the repository at this point in the history
Signed-off-by: Akashdeep Dhar <akashdeep.dhar@gmail.com>
  • Loading branch information
gridhead committed Nov 10, 2024
1 parent c0cf347 commit 6c4e3f2
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 4 deletions.
17 changes: 17 additions & 0 deletions expedite/server/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@

class ExpediteConnection:
def __init__(self, iden: str = standard.client_iden, plan: str = standard.client_plan, scan: str = standard.client_endo, time: int = standard.client_time) -> None:
"""
Initialize the Expedite connection with the client identity, operation intent, target identity and waiting time
:param iden: Identity provided by the exchange server to the connecting client to be recognized within the network
:param plan: Operation intent of the connecting client - This can be either SEND or RECV depending on the purpose
:param scan: Target client sought by the connecting client - This can be either empty string or hexadecimal string
:param time: Time for which a connecting client will stay connected to the network and wait for a pairing process
"""
self.iden = iden
self.plan = plan
self.scan = scan if scan != "" else None
Expand All @@ -36,5 +44,14 @@ def __init__(self, iden: str = standard.client_iden, plan: str = standard.client
self.ptsc = None

def pair_connection(self, ptid: str = standard.client_endo, ptsc: WebSocketServerProtocol = None) -> None:
"""
Configure the partner identity and partner sought when the pairing process with both the clients has completed
These attributes belong to the pairmate and are populated for the client after the pairing process is complete
:param ptid: Identity provided by the exchange server to the connecting client to be recognized within the network
:param ptsc: Websocket object belonging to the connecting client
:return:
"""
self.ptid = ptid
self.ptsc = ptsc
77 changes: 77 additions & 0 deletions expedite/server/conn.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@


async def exchange_insert(sock: WebSocketServerProtocol, plan: str = standard.client_plan, scan: str = standard.client_endo, time: int = standard.client_time) -> str | bool:
"""
Comply with the client request of joining the network
If client ABC joins before client XYZ
- assuming that client ABC wants to connect to client XYZ
- client ABC does not need to provide any target identity
- client XYZ has to provide client ABC as target identity
:param sock: Websocket object belonging to the connecting client
:param plan: Operation intent of the connecting client - This can be either SEND or RECV depending on the purpose
:param scan: Target client sought by the connecting client - This can be either empty string or hexadecimal string
:param time: Identity provided by the exchange server to the connecting client to be recognized within the network
:return: Confirmation of the action completion
"""
if sock not in standard.connection_dict:
if plan in ["SEND", "RECV"]:
iden = uuid4().hex[0:8].upper()
Expand All @@ -53,6 +67,24 @@ async def exchange_insert(sock: WebSocketServerProtocol, plan: str = standard.cl


async def exchange_remove(sock: WebSocketServerProtocol) -> bool:
"""
Inform the client about them being booted off the network
Here is how the logic works -
Once participant ABC is flagged for removal either from client side or server side
- If participant ABC exists in the connection dictionary
- If participant ABC is paired with participant XYZ
- Participant XYZ is disconnected from the network and removed from the connection dictionary
- Participant ABC is disconnected from the network and removed from the connection dictionary
- If participant ABC is not paired with anyone else
- Participant ABC is disconnected from the network and removed from the connection dictionary
- If participant ABC does not exist in the connection dictionary
- Do nothing
:param sock: Websocket object belonging to the disconnecting client
:return: Confirmation of the action completion
"""
if sock in standard.connection_dict:
if standard.connection_dict[sock].ptsc in standard.connection_dict and standard.connection_dict[sock].ptsc.state == 1:
warning(f"{standard.connection_dict[sock].ptid} left.")
Expand All @@ -67,6 +99,36 @@ async def exchange_remove(sock: WebSocketServerProtocol) -> bool:


async def exchange_inform(sock: WebSocketServerProtocol, plan: str = standard.client_plan, scan: str = standard.client_endo, iden: str = standard.client_iden) -> int:
"""
Inform the client about them being able to join the network
Here is how the logic works -
After client ABC is able to join the network with operation intent P
- If client ABC has provided that they are looking for client XYZ for DEF seconds
- If client XYZ has not yet joined the network
- Client ABC will wait until the client XYZ will join the network [Code 3]
- Client ABC will disconnect after DEF seconds if the client XYZ does not turn up
- If client XYZ has been connected to the network for a while
- If client XYZ is not yet paired with anyone else
- If client XYZ has the operation intent Q (opposite of operation intent P of client ABC)
- Client ABC will be paired with client XYZ due to the positive operation intents [Code 0]
- Client XYZ will be paired with client ABC due to the positive operation intents [Code 0]
- If client XYZ has the operation intent P (selfsame of operation intent P of client ABC)
- Client ABC will be booted off the network due to the negative operation intents [Code 1]
- Client XYZ will be booted off the network due to the negative operation intents [Code 1]
- If client XYZ has already paired with anyone else
- Client ABC will be booted off the network as client XYZ is already paired [Code 2]
- If client ABC has provided that they are waiting for connection for DEF seconds
- Client ABC will wait until they are connected with some client [Code 3]
- Client ABC will disconnect after DEF seconds if they are not paired until then
:param sock: Websocket object belonging to the connecting client
:param plan: Operation intent of the connecting client - This can be either SEND or RECV depending on the purpose
:param scan: Target client sought by the connecting client - This can be either empty string or hexadecimal string
:param iden: Identity provided by the exchange server to the connecting client to be recognized within the network
:return: Confirmation of the action completion
"""
for indx in standard.connection_dict:
if standard.connection_dict[indx].iden == scan:
if not standard.connection_dict[indx].ptsc:
Expand All @@ -90,6 +152,14 @@ async def exchange_inform(sock: WebSocketServerProtocol, plan: str = standard.cl


async def exchange_json(sock: WebSocketServerProtocol, note: str = "", data: str = "") -> bool:
"""
Convey the JSON elements from delivering client to collecting client
:param sock: Websocket object belonging to the delivering client
:param note: Action requested to be performed by the collecting client
:param data: Data elements that are to be conveyed across
:return: Confirmation of the action completion
"""
general(standard.server_note[note].format(sj=standard.connection_dict[sock].iden, oj=standard.connection_dict[sock].ptid))
if sock in standard.connection_dict:
if standard.connection_dict[sock].ptsc in standard.connection_dict and standard.connection_dict[sock].ptsc.state == 1:
Expand All @@ -102,6 +172,13 @@ async def exchange_json(sock: WebSocketServerProtocol, note: str = "", data: str


async def exchange_byte(sock: WebSocketServerProtocol, pack: bytes = b"") -> bool:
"""
Convey the file contents from delivering client to collecting client
:param sock: Websocket object belonging to the delivering client
:param pack: File contents that are to be conveyed across
:return: Confirmation of the action completion
"""
if sock in standard.connection_dict:
if standard.connection_dict[sock].ptsc in standard.connection_dict and standard.connection_dict[sock].ptsc.state == 1:
await standard.connection_dict[sock].ptsc.send(pack)
Expand Down
18 changes: 15 additions & 3 deletions expedite/server/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,17 @@
from expedite import __versdata__
from expedite.config import standard
from expedite.server.meet import talk
from expedite.server.room import oper
from expedite.server.room import exchange
from expedite.view import failure, general


def work():
func = serve(oper, standard.server_addr, standard.server_port)
def work() -> None:
"""
Start the worker module to serve the exchange service
:return:
"""
func = serve(exchange, standard.server_addr, standard.server_port)
get_event_loop().run_until_complete(func)
get_event_loop().run_forever()

Expand Down Expand Up @@ -66,6 +71,13 @@ def work():
version=__versdata__, prog_name="Expedite Server by Akashdeep Dhar"
)
def main(addr: str = standard.server_addr, port: int = standard.server_port) -> None:
"""
Configure the service particulars before starting it
:param addr: Interface for the service endpoint
:param port: Port value for the service endpoint
:return:
"""
try:
standard.server_addr = addr
standard.server_port = port
Expand Down
5 changes: 5 additions & 0 deletions expedite/server/meet.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@


def talk() -> None:
"""
Show information on the server side during startup
:return:
"""
success(f"Expedite Server v{__versdata__}")
general(f"Addr. {standard.server_addr}")
general(f"Port. {standard.server_port}")
9 changes: 8 additions & 1 deletion expedite/server/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from json import loads

from websockets.exceptions import ConnectionClosed
from websockets.legacy.server import WebSocketServerProtocol

from expedite.config import standard
from expedite.server.conn import (
Expand All @@ -36,7 +37,13 @@
from expedite.view import failure, general, warning


async def oper(sock):
async def exchange(sock: WebSocketServerProtocol) -> None:
"""
Exchange data among connected clients depending on client identity, operation intent and target identity
:param sock: Websocket object belonging to the client
:return:
"""
try:
async for mesgcont in sock:
if isinstance(mesgcont, str):
Expand Down

0 comments on commit 6c4e3f2

Please sign in to comment.