diff --git a/assets/www/configuration.html b/assets/www/configuration.html new file mode 100644 index 0000000..f777411 --- /dev/null +++ b/assets/www/configuration.html @@ -0,0 +1,173 @@ + + + + + + PyRobusta Home + + + + +

Configuration

+ + ← Back + +

+ This page documents PyRobusta configuration options, + configuration deployment using mpremote, + and runtime access to configuration values through the + configuration API. +

+ +
+ +

Table of Contents

+ + Configuration
+ ├── Configuration Format & Deployment
+ ├── Parameter Description
+ └── Configuration API
+ +
+ + +

Configuration Format & Deployment

+ +

+ Configuration overrides can be provided through pyrobusta.env, using standard .env syntax. + pyrobusta.env must be stored in the server root. Inline comments are supported using #. +

+ + + +

Perform a soft reset and upload pyrobusta.env using mpremote.

+ + + +

Parameter Description

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionDefault
wifi_ssidName of the Wi-Fi network. When empty, Wi-Fi is not initialized by the built-in wifi.py module.None
wifi_passwordPassword of the Wi-Fi network. When empty, Wi-Fi is not initialized by the built-in wifi.py module.None
http_portPort number for HTTP.80
https_portPort number for HTTPS.443
http_multipartEnables or disables multipart request and response processing. Enabling multipart support increases memory usage.False
http_mem_cap + Fraction of available heap memory reserved for stream buffers. Valid range: (0, 1]. + 0.1
http_served_paths + Space-separated list of filesystem paths that may be served over HTTP. + /www /lib/pyrobusta
http_files_api + Enables or disables the file management API endpoint (/files), allowing upload, download, and listing of files. + False
socket_max_conMaximum number of simultaneous socket connections.2
tls + Enables or disables TLS. When enabled, cert.der and key.der must be installed at the server root. + False
log_levelLogging level. Can be one of: warning, info, debug.info
+ +

Configuration API

+ +

+ Configuration values can be accessed through the + pyrobusta.utils.config module. + Values are loaded from pyrobusta.env during server initialization. + Configuration values can be retrieved using + get_config() together with one of the + predefined CONF_* constants. +

+ +

+ After initialization, configuration values are retrieved from an internal cache. + The cached values are normalized to their expected runtime types to avoid repeated + parsing of environment strings. +

+ +

+ Configuration values are treated as immutable during runtime. + Changes are applied only when the configuration cache is reloaded. + The configuration cache can be reloaded by calling + read_config(), which re-reads pyrobusta.env + and rebuilds the internal normalized cache. +

+ + + + + + diff --git a/assets/www/file_server.html b/assets/www/file_server.html new file mode 100644 index 0000000..e54769b --- /dev/null +++ b/assets/www/file_server.html @@ -0,0 +1,207 @@ + + + + + + PyRobusta Home + + + + +

File Server API

+ + ← Back + +

This API provides file management capabilities, allowing clients to upload, + retrieve, and manage files through various HTTP methods. + http_files_api must be set to True in + pyrobusta.env to enable this API. +

+ +
+ +

Table of Contents

+ + Static Content
+ ├── Summary
+ ├── File Retrieval
+ ├── File Upload / Overwrite
+ ├── Bulk File Upload
+ └── File Delete
+ +
+ +

Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodPathDescription
GET/files/{path}Lists or retrieves metadata about files.
PUT/files/{file path}Uploads or overwrites a file at the specified path.
POST/filesUploads multiple files in multipart/form-data.
DELETE/files/{file path}Deletes a file at the specified path.
+ +
+

File Retrieval / Listing

+

Endpoint: GET /files/{path}

+ +

+ This method allows general file system interaction, enabling operations + such as listing directory contents, retrieving metadata, and downloading + files. +

+ + + +

Example Request

+ + +
+ +
+

File Upload / Overwrite

+

Endpoint: PUT /files/{file path}

+ +

+ This method uploads a file or overwrites an existing file at a specific + path. The upload path is restricted to + /www/user_data. +

+ + + +

Example Request

+ + +
+ +
+

Bulk File Upload

+

Endpoint: POST /files

+ +

+ This method handles general file uploads, designed for uploading multiple + files with per-file chunking supported. Only + multipart/form-data is accepted. +

+ +

+ Uploads are restricted to /www/user_data. The + Content-Disposition header only needs to specify the file + name; the upload directory is prepended automatically. +

+ +

+ http_multipart must be set to True in the + configuration to use this method. +

+ + + +

Example Request

+ + +
+ +
+

File Delete

+

Endpoint: DELETE /files/{file path}

+ +

+ This method deletes a file at a specific path. The path is restricted to + /www/user_data. +

+ + + +

Example Request

+ + +
+ + + + + diff --git a/assets/www/index.html b/assets/www/index.html index b3be74b..7abaf0e 100644 --- a/assets/www/index.html +++ b/assets/www/index.html @@ -4,33 +4,7 @@ PyRobusta Home - + @@ -42,7 +16,13 @@

PyRobusta Home

Available Resources

@@ -52,4 +32,4 @@

Available Resources

- \ No newline at end of file + diff --git a/assets/www/examples.html b/assets/www/introduction.html similarity index 54% rename from assets/www/examples.html rename to assets/www/introduction.html index e0cdfd9..baa1d8c 100644 --- a/assets/www/examples.html +++ b/assets/www/introduction.html @@ -4,76 +4,38 @@ PyRobusta Home - + -

Getting Started

+

Introduction

← Back -

This page presents useful examples to configure your server.

+

This page provides practical examples for using your server.


-

Server configuration

- -

+ Introduction
+ ├── Demo Application
+ └── Deployment with mpremote

-

Demo Application

-

The below application demonstrates common use cases for handling headers, status codes, query parameters, and wilcard URLs.

-
    -
  1. /version returns the version of the application. -
    Optionally, the server version is also included in the response if the 'detailed' query parameter is set to true. -
  2. -
  3. /app/version or /server/version returns the designated version string, handled by a single endpoint definition with a wildcard URL. -
  4. -
- - -

Soft reset the device and upload app.py and boot.py with mpremote.

- -

Hard reset the device to start the application and connect over REPL.

- -

Use curl to test your application.

- + +

Request Headers

+ +

Headers received in a request are available in the headers attribute of the HTTP context. + The headers attribute is a dictionary of key-value pairs. Header names and values are exposed as strings. + As a convenience, the Content-Length header is automatically converted to an integer because it is frequently used for + payload size calculations. Headers are normalized to lower case, so the key "Content-Length" is equivalent to the key + "content-length". +

+ +

Request headers must contain only a subset of US-ASCII characters:

+ +
+ +
+ + + +

Request Bodies

+ +

A request payload is passed as the second positional argument of the + route handler. Unless the request uses streaming or multipart encoding, the payload + is provided as a memoryview to avoid unnecessary memory allocations. Deserialization must be done + by the user application. +

+ + + +

Streamed Requests

+ +

PyRobusta supports streaming requests by processing individual + chunks of the request body as they are received. To enforce bounded memory usage, + request chunks are processed individually by calling registered route handlers + for each chunk received. As a result, the application must process the request body + incrementally rather than assuming the full payload is available at once. +

+ + + +

Multipart Requests

+ +

Multipart requests allow clients to send composite payloads with + the option of varying content metadata or multiple resources in a single request. + Similar to streamed requests, multipart requests are processed one part at a time. + The route handler is invoked once for each part. Unlike regular request bodies, multipart + parts are parsed by the server before being passed to the application. Peprocessed parts + consist of headers (dictionary) and the raw part body (bytes), passed as a tuple. +

+ +
+ Multipart state tracking
+ The HTTP context exposes the boolean attributes + mp_is_first and + mp_is_last + to identify the first and final part of a multipart request. This allows stateful processing + of multiple parts belonging to the same request. +

+ + + + + + diff --git a/assets/www/response.html b/assets/www/response.html new file mode 100644 index 0000000..f149882 --- /dev/null +++ b/assets/www/response.html @@ -0,0 +1,311 @@ + + + + + + PyRobusta Home + + + + +

Response Processing

+ + ← Back + +

Response processing controls how route handlers construct HTTP responses. + This includes setting status codes, configuring response headers, serializing response bodies, + and generating streamed or multipart responses. +

+
+ +

Table of Contents

+ + Response Processing
+ ├── Status Codes
+ ├── Response Headers
+ ├── Cache Control
+ ├── Content Types & Serialization
+ ├── Streamed Responses
+ └── Streamed Multipart Responses
+ +
+ +

Status Codes

+ +

Route handlers may optionally set the status code of the HTTP response. + If unspecified, the server defaults to HTTP 200. The status code can be overridden + through the terminate() method of the HTTP context. +

+ +

The terminate() method updates the response status code and marks the + request as complete, but does not interrupt execution. Route handlers should still return + an appropriate response body. +

+ + + +

Response Headers

+ +

Response headers and response bodies can be configured through methods exposed by the HTTP context + (set_response_header(), set_response_body()). + Alternatively, route handlers may return a (content_type, body) tuple. +

+ + + + +

Cache Control

+ +

+ PyRobusta implements a simple caching policy. + Unless overridden by the application, all HTTP responses include the + header Cache-Control: no-store. + + Conditional requests and cache validation mechanisms are not supported. + This includes ETag, Last-Modified, + If-None-Match, and If-Modified-Since. + + This design reduces implementation complexity and avoids additional + filesystem metadata lookups on resource-constrained devices. +

+ +

Content Types & Serialization

+ +

PyRobusta can automatically serialize a limited set of built-in types and data structures. + Unsupported types must be serialized by the application before being returned as either a string or a bytes-like + object. The following response body types are currently supported: +

+ + + +

For non-streamed responses, the entire response body must exist in memory before it is + transmitted. As a result, the maximum response size is limited by the available heap. In the meantime, a + response buffer has a fixed size depending on the configuration. Internally, response bodies are wrapped + in a BytesIO object so that both fixed-size and streamed responses can be written through the same + buffer-oriented interface. Each response body returned by a route handler has a known size, allowing the + content-length header to be filled by the server. +

+ +

Streamed Responses

+

+ Responses can be streamed in chunks when the application cannot determine the size of the response body in advance. + Such responses must use chunked transfer encoding, indicated by the Transfer-Encoding header. With chunked encoding, + the Content-Length header must be omitted; instead the size of each chunk must be indicated as the chunks are sent. + The server automatically generates the required chunk metadata. +

+ +

+ When chunked transfer encoding is enabled, the server automatically generates the required encoding format. + The application must assign a generator function to http_ctx.resp_handler. The server then invokes the generator + when data is ready to be transmitted. The generator may be resumed multiple times until the stream is complete. + The following requirements must be fulfilled by the generator: +

+ +
+
    +
  1. the generator function must accept a single response buffer argument (tx) used to write response data
  2. +
  3. the generator yields False after producing a chunk while additional data remains
  4. +
  5. the generator yields True exactly once to indicate that the stream is complete
  6. +
  7. the generator verifies the writable capacity of the buffer and + writes at most that much data to the buffer before yielding
  8. +
+
+ + + + + +

Streamed Multipart Responses

+

+ Multipart responses allow a single HTTP response to contain multiple independently typed payloads, + each with its own headers and body. Similar to streamed responses, PyRobusta uses response producer + functions to generate multipart response parts on demand. Because the total response size is not known + in advance, the server automatically uses chunked transfer encoding for multipart responses. It is + explicitly enabled in the example below for completeness. +

+ +

+ Routes producing streamed multipart responses must satisfy the following requirements: +

+ +
+
    +
  1. the route must return a tuple containing the multipart content type and a callable response producer
  2. +
  3. the response producer must return a tuple containing the content type and payload of each part
  4. +
  5. after producing the final part, the response producer must return None
  6. +
+
+ + + +

+ Try the X-Part-Count and X-Part-Size headers to arbitrarily configure the response size. +

+ + + + + + diff --git a/assets/www/routing.html b/assets/www/routing.html new file mode 100644 index 0000000..10c14c7 --- /dev/null +++ b/assets/www/routing.html @@ -0,0 +1,197 @@ + + + + + + PyRobusta Home + + + + +

Routing

+ + ← Back + +

Routing maps incoming HTTP requests to application-defined route handlers. + This page describes how routes are defined, how route handlers receive requests, and how wildcard routes + can be used to match dynamic URL paths. +

+ +
+ +

Table of Contents

+ + Routing
+ ├── Route Definitions
+ ├── Route Handlers
+ ├── Wildcard Routes
+ └── Route Registration & Deregistration
+ +
+ +

Route Definitions

+ +

Routes map HTTP requests to server-side handler functions that + process requests and manage resources. Similar to common web frameworks, PyRobusta + utilizes function decorators to map handler functions to URL paths. A route handler + can only be mapped to a single URL path and HTTP method. The same URL path may be + associated with multiple route handlers provided that each handler uses a different + HTTP method. +

+ + + +

Route Handlers

+ +

In PyRobusta, a route handler is a synchronous function registered to a + specific URL path and HTTP method. PyRobusta invokes a route handler whenever it receives a + request whose URL path and HTTP method match the registered route. Route handlers must accept + exactly two positional arguments: +

+ + +

HTTP Context

+ +

The HTTP context is an instance of the HttpEngine class that exposes the + public API used to inspect requests and construct responses. The HTTP context provides public + methods and attributes that enable user applications to process headers and structure responses. + By convention, non-public attributes and methods are prefixed with an underscore. + +

+ + Apart from the public API, the HTTP context also encapsulates the state associated with the current + request and response exchange. Internally, the HTTP context ensures protocol correctness and assists + with request routing. +

+ +

Request Body

+ +

Depending on the request type, the body argument may contain either the complete + request body or a partial payload chunk. Partial request bodies are passed to route handlers + when the request uses multipart encoding or chunked transfer encoding, with each chunk of the payload + fed incrementally to the route handler. Such request processing is documented in the + Request Processing guide. +

+ +

Wildcard Routes

+ +

Wildcard routes use placeholders in one or more segments of a URL path. + These placeholders match varying path values, allowing multiple URL paths to be mapped to + a single handler function. A placeholder matches a single path segment by default. Alternatively, + a placeholder can match multiple segments by using the :path suffix. For example: + +

/path/to/{resource:path}

+ + Placeholders that match multiple path segments are only allowed at the end of a route. For example, + /path/{to:path}/resource is disallowed because it would result in ambiguous route resolution. +

+ + + +

Route Registration & Deregistration

+ +

By convention, user applications should use decorators + to register route handlers in most cases. This approach ensures that routes are registered + during application initialization, and routes remain available for the lifetime of the application. + The public API exposed by HttpEngine allows route registration and deregistration + during an application's lifecycle, enabling applications to dynamically expose or + remove functionality at runtime. +

+ + + + + + diff --git a/assets/www/static_content.html b/assets/www/static_content.html new file mode 100644 index 0000000..344b32c --- /dev/null +++ b/assets/www/static_content.html @@ -0,0 +1,130 @@ + + + + + + PyRobusta Home + + + + +

Static Content

+ + ← Back + +

+ PyRobusta serves static content directly from the filesystem. This page + describes the directory structure, file resolution rules, and MIME type + handling used by the server. +

+ +
+ +

Table of Contents

+ + Static Content
+ ├── Static File Serving
+ ├── Directory Structure
+ └── MIME Type Handling
+ +
+ +

Static File Serving

+ +

Files stored under /www are served as static content. + Requests to the server root (/) return the default landing page (index.html). + For static content requests, the server automatically prepends /www to the requested path before + resolving the corresponding file on the filesystem. +

+ +

When the file management API is enabled (http_files_api=True), + additional filesystem locations can be exposed through the http_served_paths + configuration option. See the Server Configuration + and File Server API guide for additional details. +

+ +

Directory Structure

+ +
+root/
+├── www                     document root for static content
+│   ├── index.html
+│   ├── introduction.html
+│   ├── ...
+│   └── user_data           root for user uploads
+│       └── ...
+├── lib                     root for installed MIP packages
+│   ├── pyrobusta
+│   │   ├── bindings
+│   │   ├── connectivity
+│   │   └── ...
+│   └── <other packages>
+├── cert.der                TLS certificate
+└── key.der                 TLS key
+    
+ +

MIME Type Handling

+ +

PyRobusta automatically determines the Content-Type header for + static files based on their filename extension. The selected content type depends on the file extension. + Unknown extensions are mapped to application/octet-stream. + The following mapping between extensions and content types is maintained by the server: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExtensionContent-Type header
.htmltext/html
.csstext/css
.jsapplication/javascript
.jsonapplication/json
.icoimage/x-icon
.jpegimage/jpeg
.jpgimage/jpeg
.pngimage/png
.txttext/plain
.gifimage/gif
.raw, unknown extensionsapplication/octet-stream
+ + + + diff --git a/assets/www/styles.css b/assets/www/styles.css new file mode 100644 index 0000000..9076f4a --- /dev/null +++ b/assets/www/styles.css @@ -0,0 +1,50 @@ +body { + font-family: serif; + margin: 40px; + background: white; + color: black; +} + +h1 { + border-bottom: 1px solid #999; + padding-bottom: 10px; +} + +hr { + margin: 20px 0; +} + +a { + color: blue; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +.description { + width: clamp(300px, 70vw, 800px); +} + +table, th, td { + border: 1px solid black; + border-collapse: collapse; +} + +textarea { + resize: none; + background-color: rgb(37, 37, 37); + color: white; + box-sizing: border-box; + width: 100%; + padding-left: 10px; + field-sizing: content; + white-space: pre; +} + +.footer { + font-size: 0.9em; + color: #555; + margin-top: 30px; +} diff --git a/dist/pyrobusta/assets/www/examples.html b/dist/pyrobusta/assets/www/examples.html index 99e0481..fd5d501 100644 --- a/dist/pyrobusta/assets/www/examples.html +++ b/dist/pyrobusta/assets/www/examples.html @@ -70,7 +70,7 @@

Demo Application

  • /version returns the version of the application.
    Optionally, the server version is also included in the response if the 'detailed' query parameter is set to true.
  • -
  • /app/version or /server/version returns the designated version string, handled by a single endpoint definition with a wildcard URL. +
  • /app/version or /server/version returns the designated version string, handled by a single route handler with a wildcard URL.