kopia lustrzana https://github.com/cirospaciari/socketify.py
Porównaj commity
3 Commity
Autor | SHA1 | Data |
---|---|---|
![]() |
2ed7ec1403 | |
![]() |
b370876074 | |
![]() |
464804edef |
|
@ -4,11 +4,6 @@
|
|||
<a href="https://github.com/cirospaciari/socketify.py"><img src="https://raw.githubusercontent.com/cirospaciari/socketify.py/main/misc/logo.png" alt="Logo" height=170></a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://github.com/cirospaciari/socketify.py/actions/workflows/linux.yml" target="_blank"><img src="https://github.com/cirospaciari/socketify.py/actions/workflows/linux.yml/badge.svg" /></a>
|
||||
<a href="https://github.com/cirospaciari/socketify.py/actions/workflows/windows.yml" target="_blank"><img src="https://github.com/cirospaciari/socketify.py/actions/workflows/windows.yml/badge.svg" /></a>
|
||||
<a href="https://github.com/cirospaciari/socketify.py/actions/workflows/macos.yml" target="_blank"><img src="https://github.com/cirospaciari/socketify.py/actions/workflows/macos.yml/badge.svg" /></a>
|
||||
<a href="https://github.com/cirospaciari/socketify.py/actions/workflows/macos_arm64.yml" target="_blank"><img src="https://github.com/cirospaciari/socketify.py/actions/workflows/macos_arm64.yml/badge.svg" /></a>
|
||||
<br/>
|
||||
<a href='https://github.com/cirospaciari/socketify.py'><img alt='GitHub Clones' src='https://img.shields.io/badge/dynamic/json?color=success&label=Clones&query=count&url=https://gist.githubusercontent.com/cirospaciari/2243d59951f4abe4fd2000f1e20bc561/raw/clone.json&logo=github'></a>
|
||||
<a href='https://pypi.org/project/socketify/' target="_blank"><img alt='PyPI Downloads' src='https://static.pepy.tech/personalized-badge/socketify?period=total&units=international_system&left_color=grey&right_color=brightgreen&left_text=Downloads'></a>
|
||||
<a href="https://github.com/sponsors/cirospaciari/" target="_blank"><img src="https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&link=https://github.com/sponsors/cirospaciari"/></a>
|
||||
|
|
185
docs/examples.md
185
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
|
||||
|
|
|
@ -107,7 +107,7 @@ def ws_upgrade(ssl, response, info, socket_context, user_data):
|
|||
"root_path": "",
|
||||
"path": url.decode("utf8"),
|
||||
"raw_path": url,
|
||||
"query_string": ffi.unpack(info.query_string, info.query_string_size),
|
||||
"query_string": ffi.unpack(info.query_string, info.query_string_size)[1:],
|
||||
"headers": headers,
|
||||
"subprotocols": [protocol] if protocol else [],
|
||||
"extensions": {
|
||||
|
@ -471,7 +471,7 @@ def asgi(ssl, response, info, user_data):
|
|||
"root_path": "",
|
||||
"path": url.decode("utf8"),
|
||||
"raw_path": url,
|
||||
"query_string": ffi.unpack(info.query_string, info.query_string_size),
|
||||
"query_string": ffi.unpack(info.query_string, info.query_string_size)[1:],
|
||||
"headers": headers,
|
||||
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue