Show sources
urls.pyfrom hypergen.hypergen import autourls
from websockets import views
app_name = 'websockets'
urlpatterns = autourls(views, app_name)
views.pyfrom hypergen.imports import *
from website.templates2 import base_example_template, show_sources
"""
This file has two examples of using websockets in Hypergen:
chat: Using a consumer in normal channels fashion.
chat2: Using the @consumer decorator to avoid all the boilerplate.
"""
### chat ###
# ↓ Remember to add the plugin
@liveview(perm=NO_PERM_REQUIRED, base_template=base_example_template, user_plugins=[WebsocketPlugin()])
def chat(request):
# Channels urls are not reversible the same as vanilla urls. Little helper to add protocol and port.
url = ws_url("/ws/chat/hypergen/")
# Open a websocket on the client. Can be closed at any point with: command("hypergen_websockets.close", url)
command("hypergen_websockets.open", url)
# Some custom styling.
style(""" input, textarea {width: 100%} """)
# The consumer will write here.
with p(id="counter"):
raw(" ")
# The input field where the user types the chat message.
input_(
id_="message",
type_="text",
placeholder="Write your message here and press enter.",
autofocus=True,
# This callbacks goes to the ChatConsumer in websockets.consumers, because the url starts with "ws://"
# or "wss://".
# Will only trigger when the user presses Enter.
onkeyup=callback(url, THIS, when=["hypergen.when.keycode", "Enter"], clear=True),
)
# Chat messages are shown here.
ul(id_="messages")
### chat2 ###
# ↓ Remember to add the plugin
@liveview(perm=NO_PERM_REQUIRED, base_template=base_example_template, user_plugins=[WebsocketPlugin()])
def chat2(request):
from channels.http import AsgiRequest
# @consumer decorated functions are reversible with the ".reverse()" helper.
websocket_url = receive_message.reverse()
# Open a websocket on the client. Can be closed at any point with: command("hypergen_websockets.close", url)
command("hypergen_websockets.open", websocket_url)
# Some custom styling.
style(""" input, textarea {width: 100%} """)
# The consumer will write here.
with p(id="counter"):
raw(" ")
# The input field where the user types the chat message.
input_(
id_="message",
type_="text",
placeholder="Write your message here and press enter.",
autofocus=True,
# This callbacks goes to the ChatConsumer in websockets.consumers, because the url starts with "ws://"
# or "wss://".
# Will only trigger when the user presses Enter.
onkeyup=callback(websocket_url, THIS, when=["hypergen.when.keycode", "Enter"], clear=True),
)
# Chat messages are shown here.
ul(id_="messages")
show_sources(__file__)
# Automatically creates a consumer and creates a url route for it. Works with autoconsumers() in the routing.py
# file. No other setup needed. It takes the same arguments as @action.
@consumer(perm=NO_PERM_REQUIRED, target_id="counter")
def receive_message(consumer, request, message):
# Automatically receives the channels consumer class instance and the request first.
# Then it takes the arguments from the callback.
# Ignore empty messages.
if not message:
return
# Writes into the "counter" id.
span("Length of last message is: ", len(message))
# Appends the message to the list of messages. Uses hypergen() directly to render into a string of HTML.
command("hypergen.append", "messages", hypergen(lambda: li(message)))
consumers.pyfrom hypergen.imports import *
class ChatConsumer(HypergenWebsocketConsumer):
# Custom group name can be set here. Defaults to the module, classname and url.
# def group_name(self):
# pass
# Custom permission checks can be done here.
# def check_perms(self, content):
# pass
# Similar settings that you would have to the @action decorator is defined here.
class Hypergen:
# Permissions.
perm = NO_PERM_REQUIRED # Required
any_perm = False # Optional, default: False
# One of these two is required.
base_template = None # Read target_id from base_template.target_id
target_id = "counter" # Default DOM element id to render HTML into.
# Other.
user_plugins = [] # Optional, default: []
# Render the HTML and send custom commands.
def receive_hypergen(self, message):
# Writes into the "counter" id.
span("Length of last message is: ", len(message))
# Appends the message to the list of messages. Uses hypergen() directly to render into a string of HTML.
command("hypergen.append", "messages", hypergen(lambda: li(message)))
routing.pyfrom hypergen.hypergen import autoconsumers
from django.urls import path
from . import consumers
from . import views
# Manually set routes for consumers.
websocket_urlpatterns = [path(r'ws/chat/<slug:room_name>/', consumers.ChatConsumer.as_asgi())]
# Automatically create routes for functions decorated with @consumer.
websocket_urlpatterns += autoconsumers(views, prefix="ws/websockets/")