Skip to content

Commit

Permalink
Added documentation of the UDP clients and servers (#137)
Browse files Browse the repository at this point in the history
  • Loading branch information
francis-clairicia authored Oct 31, 2023
1 parent 1edbc00 commit 93fd6a8
Show file tree
Hide file tree
Showing 28 changed files with 1,217 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ async def handle(
#################

### On a 'return'
# When handle() returns, this means that the handling of ONE request
# has finished. There is no connection close or whatever.
# The server will immediately create a new generator.
# When handle() returns, it means that this request handler is finished.
# It does not close the connection or anything.
# The server immediately creates a new generator.
#################
return

Expand Down
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from __future__ import annotations

import asyncio

from easynetwork.api_async.client import AsyncUDPNetworkClient
from easynetwork.protocol import DatagramProtocol
from easynetwork.serializers import JSONSerializer


async def main() -> None:
protocol = DatagramProtocol(JSONSerializer())
address = ("localhost", 9000)

async with AsyncUDPNetworkClient(address, protocol) as client:
print(f"Remote address: {client.get_remote_address()}")

...


if __name__ == "__main__":
asyncio.run(main())
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from __future__ import annotations

import asyncio
import socket

from easynetwork.api_async.client import AsyncUDPNetworkClient
from easynetwork.protocol import DatagramProtocol
from easynetwork.serializers import JSONSerializer


async def obtain_a_connected_socket() -> socket.socket:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

...

return sock


async def main() -> None:
protocol = DatagramProtocol(JSONSerializer())
sock = await obtain_a_connected_socket()

async with AsyncUDPNetworkClient(sock, protocol) as client:
print(f"Remote address: {client.get_remote_address()}")

...


if __name__ == "__main__":
asyncio.run(main())
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from __future__ import annotations

from easynetwork.api_sync.client import UDPNetworkClient
from easynetwork.protocol import DatagramProtocol
from easynetwork.serializers import JSONSerializer


def main() -> None:
protocol = DatagramProtocol(JSONSerializer())
address = ("127.0.0.1", 9000)

with UDPNetworkClient(address, protocol) as client:
print(f"Remote address: {client.get_remote_address()}")

...


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from __future__ import annotations

import socket

from easynetwork.api_sync.client import UDPNetworkClient
from easynetwork.protocol import DatagramProtocol
from easynetwork.serializers import JSONSerializer


def obtain_a_connected_socket() -> socket.socket:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

...

return sock


def main() -> None:
protocol = DatagramProtocol(JSONSerializer())
sock = obtain_a_connected_socket()

with UDPNetworkClient(sock, protocol) as client:
print(f"Remote address: {client.get_remote_address()}")

...


if __name__ == "__main__":
main()
Empty file.
67 changes: 67 additions & 0 deletions docs/source/_include/examples/howto/udp_clients/usage/api_async.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from __future__ import annotations

import asyncio
import socket
from typing import Any

from easynetwork.api_async.client import AsyncUDPNetworkClient
from easynetwork.exceptions import DatagramProtocolParseError

###############
# Basic usage #
###############


async def send_packet_example1(client: AsyncUDPNetworkClient[Any, Any]) -> None:
# [start]
await client.send_packet({"data": 42})


async def recv_packet_example1(client: AsyncUDPNetworkClient[Any, Any]) -> None:
# [start]
packet = await client.recv_packet()
print(f"Received packet: {packet!r}")


async def recv_packet_example2(client: AsyncUDPNetworkClient[Any, Any]) -> None:
# [start]
try:
async with asyncio.timeout(30):
packet = await client.recv_packet()
except TimeoutError:
print("Timed out")
else:
print(f"Received packet: {packet!r}")


async def recv_packet_example3(client: AsyncUDPNetworkClient[Any, Any]) -> None:
# [start]
try:
async with asyncio.timeout(30):
packet = await client.recv_packet()
except DatagramProtocolParseError:
print("Received something, but was not valid")
except TimeoutError:
print("Timed out")
else:
print(f"Received packet: {packet!r}")


async def recv_packet_example4(client: AsyncUDPNetworkClient[Any, Any]) -> None:
# [start]
all_packets = [p async for p in client.iter_received_packets()]


async def recv_packet_example5(client: AsyncUDPNetworkClient[Any, Any]) -> None:
# [start]
all_packets = [p async for p in client.iter_received_packets(timeout=1)]


##################
# Advanced usage #
##################


async def socket_proxy_example(client: AsyncUDPNetworkClient[Any, Any]) -> None:
# [start]
client.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
64 changes: 64 additions & 0 deletions docs/source/_include/examples/howto/udp_clients/usage/api_sync.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from __future__ import annotations

import socket
from typing import Any

from easynetwork.api_sync.client import UDPNetworkClient
from easynetwork.exceptions import DatagramProtocolParseError

###############
# Basic usage #
###############


def send_packet_example1(client: UDPNetworkClient[Any, Any]) -> None:
# [start]
client.send_packet({"data": 42})


def recv_packet_example1(client: UDPNetworkClient[Any, Any]) -> None:
# [start]
packet = client.recv_packet()
print(f"Received packet: {packet!r}")


def recv_packet_example2(client: UDPNetworkClient[Any, Any]) -> None:
# [start]
try:
packet = client.recv_packet(timeout=30)
except TimeoutError:
print("Timed out")
else:
print(f"Received packet: {packet!r}")


def recv_packet_example3(client: UDPNetworkClient[Any, Any]) -> None:
# [start]
try:
packet = client.recv_packet(timeout=30)
except DatagramProtocolParseError:
print("Received something, but was not valid")
except TimeoutError:
print("Timed out")
else:
print(f"Received packet: {packet!r}")


def recv_packet_example4(client: UDPNetworkClient[Any, Any]) -> None:
# [start]
all_packets = [p for p in client.iter_received_packets()]


def recv_packet_example5(client: UDPNetworkClient[Any, Any]) -> None:
# [start]
all_packets = [p for p in client.iter_received_packets(timeout=1)]


##################
# Advanced usage #
##################


def socket_proxy_example(client: UDPNetworkClient[Any, Any]) -> None:
# [start]
client.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
49 changes: 49 additions & 0 deletions docs/source/_include/examples/howto/udp_servers/async_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from __future__ import annotations

import asyncio
from collections.abc import AsyncGenerator

from easynetwork.api_async.server import AsyncDatagramClient, AsyncDatagramRequestHandler, AsyncUDPNetworkServer
from easynetwork.protocol import DatagramProtocol


class Request:
...


class Response:
...


class MyRequestHandler(AsyncDatagramRequestHandler[Request, Response]):
async def handle(
self,
client: AsyncDatagramClient[Response],
) -> AsyncGenerator[None, Request]:
request: Request = yield

...

await client.send_packet(Response())


# NOTE: The sent packet is "Response" and the received packet is "Request"
class ServerProtocol(DatagramProtocol[Response, Request]):
def __init__(self) -> None:
...


async def main() -> None:
host, port = "localhost", 9000
protocol = ServerProtocol()
handler = MyRequestHandler()

# Create the server, binding to localhost on port 9000
async with AsyncUDPNetworkServer(host, port, protocol, handler) as server:
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
await server.serve_forever()


if __name__ == "__main__":
asyncio.run(main())
Loading

0 comments on commit 93fd6a8

Please sign in to comment.