runmat-runtime 0.4.1

Core runtime for RunMat with builtins, BLAS/LAPACK integration, and execution APIs
Documentation
{
  "title": "webwrite",
  "category": "io/http",
  "keywords": [
    "webwrite",
    "http post",
    "rest client",
    "json upload",
    "form post",
    "binary upload"
  ],
  "summary": "Send data to web services using HTTP POST/PUT requests and return the response.",
  "references": [
    "https://www.mathworks.com/help/matlab/ref/webwrite.html"
  ],
  "gpu_support": {
    "elementwise": false,
    "reduction": false,
    "precisions": [],
    "broadcasting": "none",
    "notes": "webwrite gathers gpuArray inputs and executes entirely on the CPU networking stack."
  },
  "fusion": {
    "elementwise": false,
    "reduction": false,
    "max_inputs": 1,
    "constants": "inline"
  },
  "requires_feature": null,
  "tested": {
    "unit": "builtins::io::http::webwrite::tests",
    "integration": [
      "builtins::io::http::webwrite::tests::webwrite_posts_form_data_by_default",
      "builtins::io::http::webwrite::tests::webwrite_sends_json_when_media_type_json",
      "builtins::io::http::webwrite::tests::webwrite_applies_basic_auth_and_custom_headers",
      "builtins::io::http::webwrite::tests::webwrite_supports_query_parameters",
      "builtins::io::http::webwrite::tests::webwrite_binary_payload_respected"
    ]
  },
  "description": "`webwrite` sends data to an HTTP or HTTPS endpoint using methods such as `POST`, `PUT`, `PATCH`, or `DELETE`. It mirrors MATLAB behaviour: request bodies are created from MATLAB values (structs, cells, strings, numeric tensors), request headers come from `weboptions` style arguments, and the response is decoded the same way as `webread`.",
  "behaviors": [
    "The first input is an absolute URL supplied as a character vector or string scalar.",
    "The second input supplies the request body. Structs and two-column cell arrays become `application/x-www-form-urlencoded` payloads. Character vectors / strings are sent as UTF-8 text, and other MATLAB values default to JSON encoding via `jsonencode`.",
    "Name-value arguments (or an options struct) accept the same fields as MATLAB `weboptions`: `ContentType`, `MediaType`, `Timeout`, `HeaderFields`, `Username`, `Password`, `UserAgent`, `RequestMethod`, and `QueryParameters`.",
    "`ContentType` controls how the response is parsed (`\"auto\"` by default). Set it to `\"json\"`, `\"text\"`, or `\"binary\"` to force JSON decoding, text return, or raw byte vectors.",
    "`MediaType` sets the outbound `Content-Type` header. When omitted, RunMat chooses a sensible default (`application/x-www-form-urlencoded`, `application/json`, `text/plain; charset=utf-8`, or `application/octet-stream`) based on the payload.",
    "Query parameters can be appended through the `QueryParameters` option or by including additional, unrecognised name-value pairs. Parameter values follow MATLAB scalar rules.",
    "HTTP errors, timeouts, TLS verification problems, and JSON encoding issues raise MATLAB-style errors with descriptive text."
  ],
  "examples": [
    {
      "description": "Posting form fields to a REST endpoint",
      "input": "payload = struct(\"name\", \"Ada\", \"score\", 42);\nopts = struct(\"ContentType\", \"json\");          % expect JSON response\nreply = webwrite(\"https://api.example.com/submit\", payload, opts);\ndisp(reply.status)",
      "output": "    \"ok\""
    },
    {
      "description": "Sending JSON payloads",
      "input": "body = struct(\"title\", \"RunMat\", \"stars\", 5);\nopts = struct(\"MediaType\", \"application/json\", \"ContentType\", \"json\");\nresp = webwrite(\"https://api.example.com/projects\", body, opts)"
    },
    {
      "description": "Uploading plain text",
      "input": "message = \"Hello from RunMat!\";\nreply = webwrite(\"https://api.example.com/echo\", message, ...\n                 \"MediaType\", \"text/plain\", \"ContentType\", \"text\")"
    },
    {
      "description": "Uploading raw binary data",
      "input": "bytes = uint8([1 2 3 4 5]);\nwebwrite(\"https://api.example.com/upload\", bytes, ...\n         \"ContentType\", \"binary\", \"MediaType\", \"application/octet-stream\")"
    },
    {
      "description": "Supplying credentials, custom headers, and query parameters",
      "input": "headers = struct(\"X-Client\", \"RunMat\", \"Accept\", \"application/json\");\nopts = struct(\"Username\", \"ada\", \"Password\", \"lovelace\", ...\n              \"HeaderFields\", headers, ...\n              \"QueryParameters\", struct(\"verbose\", true));\nprofile = webwrite(\"https://api.example.com/me\", struct(), opts)"
    }
  ],
  "faqs": [
    {
      "question": "Which HTTP methods are supported?",
      "answer": "`webwrite` defaults to `POST`. Supply `\"RequestMethod\",\"put\"` (or `\"patch\"`, `\"delete\"`) to use other verbs."
    },
    {
      "question": "How do I send JSON?",
      "answer": "Set `\"MediaType\",\"application/json\"` (optionally via a struct) or `\"ContentType\",\"json\"`. RunMat serialises the payload with `jsonencode` and sets the appropriate `Content-Type`."
    },
    {
      "question": "How are form posts encoded?",
      "answer": "Struct inputs and two-column cell arrays are turned into `application/x-www-form-urlencoded` bodies. Field values must be scalar text or numbers."
    },
    {
      "question": "Can I post binary data?",
      "answer": "Yes. Provide numeric tensors (`double`, integer, or logical) and set `\"ContentType\",\"binary\"` or `\"MediaType\",\"application/octet-stream\"`. Values must be in the 0–255 range."
    },
    {
      "question": "What controls the response decoding?",
      "answer": "`ContentType` mirrors `webread`: `\"auto\"` inspects response headers, while `\"json\"`, `\"text\"`, and `\"binary\"` force the output format."
    },
    {
      "question": "How do I add custom headers?",
      "answer": "Use `\"HeaderFields\", struct(\"Header-Name\",\"value\",...)` or a two-column cell array. Header names must be valid HTTP tokens."
    },
    {
      "question": "Does `webwrite` follow redirects?",
      "answer": "Yes. The underlying `reqwest` client follows redirects with the same credentials and headers."
    },
    {
      "question": "Can I send query parameters and a body simultaneously?",
      "answer": "Yes. Provide a `QueryParameters` struct/cell in the options. Parameters are percent-encoded and appended to the URL before the request is issued."
    },
    {
      "question": "How do timeouts work?",
      "answer": "`Timeout` accepts a scalar number of seconds. The default is 60 s. Requests exceeding the limit raise `webwrite: request to <url> timed out`."
    },
    {
      "question": "What happens with GPU inputs?",
      "answer": "They are gathered before serialisation. The function is marked as a sink to break fusion graphs and ensure residency is released."
    }
  ],
  "links": [
    {
      "label": "webread",
      "url": "./webread"
    },
    {
      "label": "jsonencode",
      "url": "./jsonencode"
    },
    {
      "label": "jsondecode",
      "url": "./jsondecode"
    },
    {
      "label": "gpuArray",
      "url": "./gpuarray"
    },
    {
      "label": "weboptions",
      "url": "./weboptions"
    }
  ],
  "source": {
    "label": "`crates/runmat-runtime/src/builtins/io/http/webwrite.rs`",
    "url": "https://github.com/runmat-org/runmat/blob/main/crates/runmat-runtime/src/builtins/io/http/webwrite.rs"
  },
  "gpu_residency": "No. `webwrite` executes on the CPU. Any GPU values are automatically gathered before serialising the payload, and results are created on the host. Manually gathering is unnecessary.",
  "gpu_behavior": [
    "`webwrite` is a sink in the execution graph. Any GPU-resident inputs (for example tensors inside structs or cell arrays) are gathered to host memory before encoding the request body. Network I/O always runs on the CPU; fusion plans are terminated with `ResidencyPolicy::GatherImmediately`."
  ]
}