Docs
Routes
A route is code you run when a user requests an URL.
Define routes with an async function + a decorator.
@rd.get("/users")
async def get_users(request):
return rd.html(...)
@rd.post("/new_user")
async def new_user(request):
return rd.html(...)
Advanced: Other methods
PUT -@rd.put() - for
idempotent modificationsDELETE -
@rd.delete() - for
deletions
Requests
User requests can contain useful information.
There are two ways to retrieve them:
Method 1: The information is in the URL
For example, the user wants page 67 of book 42. Make them click on a
link like this: "www.site.com/books/42?page=67"
and retrieve this data like this:
@rd.get("/books/<book_id>")
async def serve_book(request):
print(request.params)
# {'book_id': '42'}
print(request.query)
# {'page': ['67']}
Method 2: The information is in the Request
This happens either when you stored the information beforehand with
cookies, or when you used Datastar's data-bind method to
link a value with an input.
@rd.post("/submit_form")
async def process_form(request):
print(request.cookies)
# {'session_id': ...}
print(request.signals)
# {'username': 'red'}
Advanced: Other data stored in request
Here is the rest of the data stored in request:request.method: "GET", ...request.raw_path: "/books/42?page=67"request.path: "/books/42"request.headers: {'host': "...", ...}request.body: b"..."
Advanced: Running code before requests
To run code before processing requests, use the@before_request decorator.A common use case is to "reject" requests that don't have a security token:
@before_request
def check_token(request):
if not request.cookies.get("secret_key"):
return rd.redirect("/")
Use sync functions under this decorator.
An early return will cancel request processing.
Responses
The way you respond to a user's request depends on the type of the request.
Case 1: Normal request(For example, when a user access a URL from the status bar, or after clicking on a link.)
Simply use rd.html():
@rd.get("/")
async def home(request):
return rd.html(<h1>Hello World!</h1>)
Advanced: Setting cookies and headers
You can pass a list of headers or a dict of cookies as additional parameters.
@rd.get("/")
async def home(request):
headers = ["X-Accel-Buffering: No"]
cookies = {'user_id': "123"}
return rd.html(
<h1>Hello World!</h1>
headers=headers,
cookies=cookies
)
If the request was triggered by a Datastar action, you can modify an element on the page.
@rd.get("/update")
async def update(request):
return rd.html("<main>...</main>")
Advanced: Patching multiple elements
You can patch multiple elements usingrd.patch().Note that you have to
yield the values.
@rd.get("/process")
async def process_user_request(request):
yield rd.patch("<main>Processing...</main>")
result = compute_stuff()
yield rd.patch(f"<main>Result is {result}</main>")
Advanced: Empty responses (CQRS pattern)
A very useful pattern in Datastar is to have one long-lived response with other "command" endpoints.The long-lived response will
yield
through a pubsub-activated generator
and the command endpoints will return empty responses.
@rd.get("/read")
async def read_stream(request):
async for message in pubsub.listen():
yield rd.patch(f"<div id='message'>{message}</div>")
@rd.post("/command")
async def handle_command(request):
user_id = request.cookies.get("user_id")
value = process(user_id)
pubsub.send(value)
return rd.empty()
Advanced: Redirection
You may redirect users if resources moved with rd.redirect():
@rd.get("/v1")
async def old_version(request):
return rd.redirect("/v2")
App
That's all! You now know how to use Red Dwarf.
The last thing you need to do is launch your app
if __name__ == "__main__":
rd.run()
Advanced: Reload mode
You can usereload=True. It will
detect any change in your Python files or in your static folder, and will
relaunch the server.Useful for prototyping, don't use it in production.
if __name__ == "__main__":
rd.run(reload=True)
Advanced: Serving on a different port
if __name__ == "__main__":
rd.run(port="123.4.5.6:7890")
Advanced: Serving on a Unix socket
if __name__ == "__main__":
rd.run(sock="/unix.sock")
Off you go!
Go build something cool!
You can continue by studying the Examples, checking the FAQ, or reading the Essays.
Have fun!