Large Payloads

Large payloads on remote runs

A tutorial for handling large payloads when running remotely.

If you use the Nextmv CLI or Python SDK, you do not need to worry about large payloads. They handle the complete run workflow for you.

When submitting a new run and retrieving the run's results, there are size limits to consider for the payload: 5MB for the input and output of a run.

You can use this large payloads workflow to handle bigger sizes. When using this alternative, note that:

  • There is a maximum limit of 500MB when uploading a file.
  • There is a maximum limit of 100MB when downloading a file.

To achieve this, you can use one of these interfaces:

To work with large payloads, follow these steps:

large-file

Python SDK

When using the Python SDK, large payloads are handled for you. Consider the following example:

import json
import os

from nextmv.cloud import Application, Client, PollingOptions

with open("<YOUR-INPUT-FILE>") as f:
    input = json.load(f)

client = Client(api_key=os.getenv("NEXTMV_API_KEY"))
app = Application(client=client, id="<YOUR-APP-ID>")
result = app.new_run_with_result(
    input=input,
    instance_id="<YOUR-INSTANCE-ID>",
    run_options={ # Customize run options.
        "solve.duration": "10s",
        "solve.iterations": "20",
    },
    polling_options=PollingOptions(),  # Customize polling options.
)
print(json.dumps(result.to_dict(), indent=2))  # Pretty print.
Copy

The size of the input is automatically detected and the large payload workflow is used when necessary. We also handle polling with exponential backoff and jitter for you.

If you want to handle large payloads manually, we provide the methods for you to do so. Here is an example of how to handle large payloads manually:

import json
import os
import time

from nextmv.cloud import Application, Client, DownloadURL

with open("<YOUR-INPUT-FILE>") as f:
    input = json.load(f)

# Create a client and an application object.
client = Client(api_key=os.getenv("NEXTMV_API_KEY"))
app = Application(client=client, id="<YOUR-APP-ID>")

# Get the upload URL.
upload_url = app.upload_url()

# Upload the input.
app.upload_large_input(input=input, upload_url=upload_url)

# Make a run.
run_id = app.new_run(
    instance_id="<YOUR-INSTANCE-ID>",
    upload_id=upload_url.upload_id,  # Use the upload ID from the upload URL.
    options={
        "solve_duration": "2", # Customize options.
    },
)

# You should poll for results, but we'll just sleep for now.
time.sleep(5)

# Get the download URL.
response = client.request(
    method="GET",
    endpoint=f"{app.endpoint}/runs/{run_id}",
    query_params={"format": "url"},
)
download_url = DownloadURL.from_dict(response.json()["output"])

# Download the output.
download_response = client.request(
    method="GET",
    endpoint=download_url.url,
    headers={"Content-Type": "application/json"},
)
print(json.dumps(download_response.json(), indent=2))  # Pretty print.
Copy

Note that the output returned in the final step is the native output of your application, and not the JSON response of the run result endpoint.

Cloud API

When using the Cloud API, you must handle large payloads manually. Here are the steps you need to follow.

1. Request a presigned URL

Request a presigned URL to upload your large input file to.

POSThttps://api.cloud.nextmv.io/v1/applications/{application_id}/runs/uploadurl

Retrieve unique upload URL and ID.

Retrieve a unique URL and ID for uploading run input (for large input files).

curl -sS -L -X POST \
    "https://api.cloud.nextmv.io/v1/applications/$APP_ID/runs/uploadurl" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEXTMV_API_KEY" | jq
Copy

The result will contain an upload_id and upload_url.

{
  "upload_id": "00000000-0000-0000-0000-000000000000",
  "upload_url": "https://the-upload-url.com/some-hashes"
}
Copy

This returned upload URL will only last for 15 minutes. If it expires, simply request a new one and take note of the new upload ID.

You can export the upload_id and upload_url to variables:

export UPLOAD_ID="ae7dce..."
export UPLOAD_URL="https://production-nextmv-tmp..."
Copy

2. Upload the large input

Upload your input using the upload_url that was obtained before. We use --data-binary here to make sure curl sends the content of the file unaltered.

curl -sS -L -X PUT \
  $(echo -n $UPLOAD_URL) \
  -H "Content-Type: application/json" \
  --compressed \
  --data-binary @$INPUT_FILE
Copy

An empty response means the upload was successful. Note that this may take a moment depending on the size of the input file.

3. Start the run

Once the upload has completed, you can start a new run with the large input using the upload_id from a previous step. This upload_id is sent in the body of the run request in place of the input. The result contains the run_id to retrieve the run results.

POSThttps://api.cloud.nextmv.io/v1/applications/{application_id}/runs

New application run.

Create new application run.

curl -sS -L -X POST \
    "https://api.cloud.nextmv.io/v1/applications/$APP_ID/runs?instance_id=$INSTANCE_ID" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEXTMV_API_KEY" \
    -d "{
      \"upload_id\": \"$UPLOAD_ID\", 
      \"options\": {
        \"duration\": \"2\"
      }
    }" | jq
Copy

You should receive a run_id like normal as a response.

{
  "run_id": "instance1-a_USaanxSR"
}
Copy

4. Get the run result

To get the result of your run, you use the same endpoint as with a standard run but with the appended query parameter ?format=url. This will return a standard run result payload but instead of the run output included in the returned JSON, in its place will be a URL to download the output file.

GEThttps://api.cloud.nextmv.io/v1/applications/{application_id}/runs/{run_id}

Get run result.

Get the result of a run.

Note that the ?format=url query parameter can be used regardless of your output size.

curl -sS -L -X GET \
    "https://api.cloud.nextmv.io/v1/applications/$APP_ID/runs/$RUN_ID?format=url" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $NEXTMV_API_KEY" | jq
Copy

The output.url key contains the presigned URL to download the output.

{
  "id": "instance1-a_USaanxSR",
  "user_email": user@nextmv.io,
  "name": "",
  "description": "",
  "metadata": {
    "status": "succeeded",
    "status_v2": "succeeded",
    "created_at": "2024-03-28T11:42:49.46854839Z",
    "duration": 3000,
    "input_size": 123,
    "output_size": 123,
    "error": "",
    "application_id": "00000000-0000-0000-0000-000000000000",
    "application_instance_id": "instance1",
    "application_version_id": "v1",
    "execution_class": "6c9500mb870s",
    "runtime": "python-3_11",
    "run_type": {
      "type": "standard",
      "definition_id": "",
      "reference_id": ""
    },
    "format": {
      "input": {
        "type": "json"
      },
      "output": {
        "type": "json"
      }
    },
    "options": {
      "active_options": {
        "duration": "2"
      },
      "request_options": {
        "duration": "2"
      }
    }
  },
  "output": {
    "url": "https://the-upload-url.com/some-hashes"
  }
}
Copy

Finally, you can download the output using the presigned URL:

curl -L -X GET \
  $(echo -n $OUTPUT_URL) \
  -H "Content-Type: application/json"
Copy

Page last updated

Go to on-page nav menu