diff --git a/docs/examples.md b/docs/examples.md index 8cddb7b..765a447 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -1,158 +1,81 @@ -# Examples +## 📚 Examples -Middleware -```python -from socketify import App, middleware +All examples are located in the [`examples`](https://github.com/cirospaciari/socketify.py/tree/main/examples) directory. +### 🚀 Getting Started -async def get_user(authorization): - if authorization: - # you can do something async here - return {"greeting": "Hello, World"} - return None +- [`hello_world.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/hello_world.py) - Basic HTTP server setup +- [`hello_world_cli.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/hello_world_cli.py) - Command-line interface example +- [`hello_world_cli_ws.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/hello_world_cli_ws.py) - CLI with WebSocket support +- [`hello_world_unix_domain.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/hello_world_unix_domain.py) - Unix domain socket example +### 🔒 Security & HTTPS -async def auth(res, req, data=None): - user = await get_user(req.get_header("authorization")) - if not user: - res.write_status(403).end("not authorized") - # returning Falsy in middlewares just stop the execution of the next middleware - return False +- [`https.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/https.py) - HTTPS server with SSL/TLS configuration - # returns extra data - return user +### 🌐 WebSocket Examples +- [`websockets.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/websockets.py) - Basic WebSocket implementation +- [`ws_close_connection.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/ws_close_connection.py) - WebSocket connection management +- [`chat/`](https://github.com/cirospaciari/socketify.py/tree/main/examples/chat) - Real-time chat application +- [`broadcast.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/broadcast.py) - Broadcasting messages to multiple clients +- [`backpressure.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/backpressure.py) - Handling WebSocket backpressure -def another_middie(res, req, data=None): - # now we can mix sync and async and change the data here - if isinstance(data, dict): - gretting = data.get("greeting", "") - data["greeting"] = f"{gretting} from another middie ;)" - return data +### ⚙️ Middleware & Routing +- [`middleware.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/middleware.py) - Basic middleware implementation +- [`middleware_async.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/middleware_async.py) - Asynchronous middleware +- [`middleware_sync.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/middleware_sync.py) - Synchronous middleware +- [`middleware_router.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/middleware_router.py) - Router-based middleware +- [`router_and_basics.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/router_and_basics.py) - Routing fundamentals -def home(res, req, user=None): - res.cork_end(user.get("greeting", None)) +### 🔄 Async/Sync Programming +- [`async.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/async.py) - Asynchronous request handling +- [`upgrade.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/upgrade.py) - Protocol upgrade examples +- [`upgrade_async.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/upgrade_async.py) - Asynchronous protocol upgrades -app = App() -app.get("/", middleware(auth, another_middie, home)) -app.listen( - 3000, - lambda config: print("Listening on port http://localhost:%d now\n" % config.port), -) -app.run() +### 📁 File Handling & Static Content -# You can also take a loop on MiddlewareRouter in middleware_router.py ;) -``` +- [`static_files.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/static_files.py) - Serving static files +- [`file_stream.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/file_stream.py) - File streaming capabilities +- [`upload_or_post.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/upload_or_post.py) - File uploads and POST data handling -Broadcast -```python -from socketify import App, AppOptions, OpCode, CompressOptions +### 🎨 Template Engines +- [`template_jinja2.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/template_jinja2.py) - Jinja2 template integration +- [`template_mako.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/template_mako.py) - Mako template integration +- [`templates/`](https://github.com/cirospaciari/socketify.py/tree/main/examples/templates) - Template examples and resources -def ws_open(ws): - print("A WebSocket got connected!") - # Let this client listen to topic "broadcast" - ws.subscribe("broadcast") +### 🛠️ Advanced Features +- [`custom_json_serializer.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/custom_json_serializer.py) - Custom JSON serialization +- [`http_request_cache.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/http_request_cache.py) - HTTP request caching +- [`proxy.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/proxy.py) - Proxy server implementation +- [`automatic_port_selection.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/automatic_port_selection.py) - Dynamic port selection -def ws_message(ws, message, opcode): - # Broadcast this message - ws.publish("broadcast", message, opcode) +### 🔧 Server Configuration -app = App() -app.ws( - "/*", - { - "compression": CompressOptions.SHARED_COMPRESSOR, - "max_payload_length": 16 * 1024 * 1024, - "idle_timeout": 60, - "open": ws_open, - "message": ws_message, - # The library guarantees proper unsubscription at close - "close": lambda ws, code, message: print("WebSocket closed"), - "subscription": lambda ws, topic, subscriptions, subscriptions_before: print(f'subscription/unsubscription on topic {topic} {subscriptions} {subscriptions_before}'), - }, -) -app.any("/", lambda res, req: res.end("Nothing to see here!")) -app.listen( - 3000, - lambda config: print("Listening on port http://localhost:%d now\n" % (config.port)), -) -app.run() -``` +- [`listen_options.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/listen_options.py) - Server listening options +- [`graceful_shutdown.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/graceful_shutdown.py) - Graceful server shutdown +- [`forks.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/forks.py) - Multi-process server setup -HTTPS -```python -from socketify import App, AppOptions +### 📊 GraphQL Integration -app = App( - AppOptions( - key_file_name="./misc/key.pem", - cert_file_name="./misc/cert.pem", - passphrase="1234", - ) -) -app.get("/", lambda res, req: res.end("Hello World socketify from Python!")) -app.listen( - 54321, - lambda config: print("Listening on port https://localhost:%d now\n" % config.port), -) -app.run() +- [`graphiql.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/graphiql.py) - GraphiQL interface setup +- [`graphiql_raw.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/graphiql_raw.py) - Raw GraphQL implementation -# mkdir misc -# openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -passout pass:1234 -keyout ./misc/key.pem -out ./misc/cert.pem -``` +### 🐳 Development & Deployment -Backpressure -```python -from socketify import App, AppOptions, OpCode, CompressOptions +- [`docker/`](https://github.com/cirospaciari/socketify.py/tree/main/examples/docker) - Docker containerization examples +- [`requirements.txt`](https://github.com/cirospaciari/socketify.py/tree/main/examples/requirements.txt) - Example dependencies -# Number between ok and not ok -backpressure = 1024 +### 🛡️ Error Handling & Logging -# Used for statistics -messages = 0 -message_number = 0 +- [`error_handler.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/error_handler.py) - Error handling strategies +- [`better_logging.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/better_logging.py) - Advanced logging setup +- [`not_found.py`](https://github.com/cirospaciari/socketify.py/tree/main/examples/not_found.py) - Custom 404 error pages +### 🔨 Utilities & Helpers -def ws_open(ws): - print("A WebSocket got connected!") - # We begin our example by sending until we have backpressure - global message_number - global messages - while ws.get_buffered_amount() < backpressure: - ws.send("This is a message, let's call it %i" % message_number) - message_number = message_number + 1 - messages = messages + 1 - - -def ws_drain(ws): - # Continue sending when we have drained (some) - global message_number - global messages - while ws.get_buffered_amount() < backpressure: - ws.send("This is a message, let's call it %i" % message_number) - message_number = message_number + 1 - messages = messages + 1 - - -app = App() -app.ws( - "/*", - { - "compression": CompressOptions.DISABLED, - "max_payload_length": 16 * 1024 * 1024, - "idle_timeout": 60, - "open": ws_open, - "drain": ws_drain, - }, -) -app.any("/", lambda res, req: res.end("Nothing to see here!")) -app.listen( - 3000, - lambda config: print("Listening on port http://localhost:%d now\n" % (config.port)), -) -app.run() -``` +- [`helpers/`](https://github.com/cirospaciari/socketify.py/tree/main/examples/helpers) - Utility functions and helper modules