Tracking external runs¶
Info
Learn the concepts and fundamentals of external runs in the Explanation page.
It is possible to execute runs outside of the Nextmv Cloud environment and just send the results back to the platform. This can be useful if you want to do production runs on your own infrastructure while still using the Nextmv Cloud platform for monitoring and collaboration on non-production models.
You can use the Application.track_run method (or
Application.track_run_with_result) to track
external runs. Both methods take a TrackedRun
object, which represents the run to track.
Consider the following files and directories you can place in a known location that we are going to use as part of the run information.
Place the following files in the inputs directory:
{
"assets": [
{
"name": "Plotly example",
"content": [
{
"data": [
{
"marker": {
"color": "red"
},
"name": "Radius (km)",
"opacity": 0.5,
"x": [
"Patches"
],
"y": [
6378
],
"type": "bar"
},
{
"marker": {
"color": "blue"
},
"name": "Distance (Millions km)",
"opacity": 0.5,
"x": [
"Patches"
],
"y": [
147.6
],
"type": "bar"
}
],
"layout": {
"template": {
"data": {
"histogram2dcontour": [
{
"type": "histogram2dcontour",
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"choropleth": [
{
"type": "choropleth",
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
],
"histogram2d": [
{
"type": "histogram2d",
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"heatmap": [
{
"type": "heatmap",
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"contourcarpet": [
{
"type": "contourcarpet",
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
],
"contour": [
{
"type": "contour",
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"surface": [
{
"type": "surface",
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
]
}
],
"mesh3d": [
{
"type": "mesh3d",
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
],
"scatter": [
{
"fillpattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
},
"type": "scatter"
}
],
"parcoords": [
{
"type": "parcoords",
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
}
],
"scatterpolargl": [
{
"type": "scatterpolargl",
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
}
],
"bar": [
{
"error_x": {
"color": "#2a3f5f"
},
"error_y": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "bar"
}
],
"scattergeo": [
{
"type": "scattergeo",
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
}
],
"scatterpolar": [
{
"type": "scatterpolar",
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
}
],
"histogram": [
{
"marker": {
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "histogram"
}
],
"scattergl": [
{
"type": "scattergl",
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
}
],
"scatter3d": [
{
"type": "scatter3d",
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
}
],
"scattermap": [
{
"type": "scattermap",
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
}
],
"scattermapbox": [
{
"type": "scattermapbox",
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
}
],
"scatterternary": [
{
"type": "scatterternary",
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
}
],
"scattercarpet": [
{
"type": "scattercarpet",
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
}
}
],
"carpet": [
{
"aaxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"baxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"type": "carpet"
}
],
"table": [
{
"cells": {
"fill": {
"color": "#EBF0F8"
},
"line": {
"color": "white"
}
},
"header": {
"fill": {
"color": "#C8D4E3"
},
"line": {
"color": "white"
}
},
"type": "table"
}
],
"barpolar": [
{
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
},
"pattern": {
"fillmode": "overlay",
"size": 10,
"solidity": 0.2
}
},
"type": "barpolar"
}
],
"pie": [
{
"automargin": true,
"type": "pie"
}
]
},
"layout": {
"autotypenumbers": "strict",
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
],
"font": {
"color": "#2a3f5f"
},
"hovermode": "closest",
"hoverlabel": {
"align": "left"
},
"paper_bgcolor": "white",
"plot_bgcolor": "#E5ECF6",
"polar": {
"bgcolor": "#E5ECF6",
"angularaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"radialaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"ternary": {
"bgcolor": "#E5ECF6",
"aaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"baxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"caxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"coloraxis": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"colorscale": {
"sequential": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
],
"sequentialminus": [
[
0.0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1.0,
"#f0f921"
]
],
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
]
},
"xaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "white",
"automargin": true,
"zerolinewidth": 2
},
"yaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "white",
"automargin": true,
"zerolinewidth": 2
},
"scene": {
"xaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white",
"gridwidth": 2
},
"yaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white",
"gridwidth": 2
},
"zaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white",
"gridwidth": 2
}
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"annotationdefaults": {
"arrowcolor": "#2a3f5f",
"arrowhead": 0,
"arrowwidth": 1
},
"geo": {
"bgcolor": "white",
"landcolor": "#E5ECF6",
"subunitcolor": "white",
"showland": true,
"showlakes": true,
"lakecolor": "white"
},
"title": {
"x": 0.05
},
"mapbox": {
"style": "light"
}
}
},
"title": {
"text": "Radius and Distance by Planet"
},
"xaxis": {
"title": {
"text": "Planet"
}
},
"yaxis": {
"title": {
"text": "Values"
}
},
"barmode": "group"
}
}
],
"content_type": "json",
"visual": {
"schema": "plotly",
"label": "Charts",
"type": "custom-tab"
}
}
]
}
We can track an external runs for both content formats: json and
multi-file. Here is an example of how to track an external run
for both content formats:
import json
import os
import nextmv
from nextmv import cloud
from nextmv import TrackedRun, TrackedRunStatus
with open("inputs/input.json") as f:
input_data = json.load(f)
with open("outputs/output.json") as f:
output_data = json.load(f)
with open("logs.log") as f:
logs_data = f.read()
with open("metrics.json") as f:
metrics_data = json.load(f)
with open("assets.json") as f:
assets_data = json.load(f)
client = cloud.Client(api_key=os.getenv("NEXTMV_API_KEY"))
app = cloud.Application.get(client=client, id="uncanny-rodent")
tracked_run = TrackedRun(
status=TrackedRunStatus.SUCCEEDED,
input=input_data,
output=output_data,
logs=logs_data,
metrics=metrics_data,
assets=assets_data,
duration=200,
)
run_id = app.track_run(tracked_run=tracked_run)
nextmv.write({"run_id": run_id})
import json
import os
import nextmv
from nextmv import cloud
from nextmv import ContentFormat, Format, FormatInput, RunConfiguration
from nextmv import TrackedRun, TrackedRunStatus
with open("logs.log") as f:
logs_data = f.read()
with open("metrics.json") as f:
metrics_data = json.load(f)
with open("assets.json") as f:
assets_data = json.load(f)
client = cloud.Client(api_key=os.getenv("NEXTMV_API_KEY"))
app = cloud.Application.get(client=client, id="uncanny-rodent")
tracked_run = TrackedRun(
status=TrackedRunStatus.SUCCEEDED,
input_dir_path="inputs",
output_dir_path="outputs",
logs=logs_data,
metrics=metrics_data,
assets=assets_data,
duration=200,
)
run_id = app.track_run(
tracked_run=tracked_run,
configuration=RunConfiguration(
format=Format(format_input=FormatInput(input_type=ContentFormat.MULTI_FILE)),
),
)
nextmv.write({"run_id": run_id})
Tip
Unlike Application.new_run, which can infer the content
format from an input_dir_path keyword argument,
Application.track_run cannot infer it automatically.
When tracking a multi-file run, you must specify the content format
explicitly using the configuration keyword argument, as shown above.
Once you have the run_id of the external run, you can use it like you would
a normal run, with methods such as:
Application.run_informationApplication.run_resultApplication.run_logsApplication.run_inputApplication.clone_run(orApplication.clone_run_with_result)Application.compare_runs
Please note that specifying the duration keyword argument is optional. If you
want to track a failed run, you would set the status keyword argument to
TrackedRunStatus.FAILED and optionally
provide an error message with the error keyword argument.