Get started with a new decision model¶
If you are new to Nextmv, and want to explore the local experience, this guide is a great place to start. On the other hand, if you already have a Python decision model, you can head to the tutorial on getting started with an existing model instead.
Let's dive right in 🤿.
1. Initialize¶
Create a script named app1.py, or use a cell of a Jupyter notebook. Copy and
paste the following code into it:
Run the app1.py script, or the cell in the Jupyter notebook.
The local.Application.initialize method will create a
new directory (your application) under the current working directory. The dir
is named app-<RANDOM_IDENTIFIER>. The app created is a simple hello world
example, and should contain a structure similar to the following:
app-<RANDOM_IDENTIFIER>
├── .gitignore
├── app.yaml
├── input.json
├── main.py
├── README.md
├── requirements.txt
└── src
├── __init__.py
└── visuals.py
- You can specify the
srcargument to customize the name of the application (directory), and not use a random identifier. - You can specify the
destinationargument to customize the location where the application will be created. By default, it will be created in the current working directory.
Application
So, what is a Nextmv Application? A Nextmv Application is an entity that
contains a decision model as executable code. An Application can make a run
by taking an input, executing the decision model, and producing an
output. An Application is defined by its code, and a configuration file
named app.yaml, known as the "app manifest".
Think of the app as a shell that contains your decision model code, and provides the necessary structure to run it.
The app.yaml manifest file contains the configuration of the
app. This tutorial is not meant to discuss the app manifest in-depth, however,
these are the main attributes shown in the manifest:
type: it is apythonapplication.runtime: when deployed to Nextmv Cloud, this application can be run on the standardpython:3.11runtime.files: contains files that make up the executable code of the app. In this case, it includes all the files under thesrcdirectory, and themain.pyfile.python.pip-requirements: specifies the file with the Python packages that need to be installed for the application.
Make sure it works¶
cd into the app directory and follow the README.md to make sure you can run
it.
-
Install packages.
-
Run the app.
You should have obtained an output similar to the following:
Hello, Patches
You are 147.6 million km from the sun
{
"options": {
"details": true
},
"solution": {
"message": "Hello, Patches"
},
"statistics": {
"result": {
"value": 1.23,
"custom": {
"message": "Hello, Patches"
}
},
"schema": "v1"
},
"assets": [...]
}
🎉 The sample app works! But there is a better way...
2. Start a run¶
Let's use the mechanisms provided by the local package to run the app
systematically by submitting a couple of runs to the local app, using the
local.Application.new_run method.
Create another script, which you can name app2.py, or use another cell in the
Jupyter notebook. Copy and paste the following code into it, making sure you
use the correct app src (the directory name created above):
from nextmv import local
# Instantiate the local application.
local_app = local.Application(src="<YOUR_APP_SRC>")
# Provide any input you want for the app. This input can come from a file, for
# example.
input = {
"name": "Patches",
"radius": 6378,
"distance": 147.6,
}
# Execute some local runs with the provided input.
run_1 = local_app.new_run(input=input)
print("run_1:", run_1)
run_2 = local_app.new_run(input=input)
print("run_2:", run_2)
When you instantiate a local.Application, the src argument
must point to a directory where the app.yaml manifest file is
located.
This will print the IDs of the runs created. The app runs start in the background. Run the script, or notebook cell, to get an output similar to this:
3. Get a run result¶
You can get a run result using the run ID with the
local.Application.run_result method.
Create another script, which you can name app3.py, or use another cell in the
Jupyter notebook. Copy and paste the following code into it, making sure you
use the correct run ID (one of the identifiers that were printed in step 2) and
app src:
import nextmv
from nextmv import local
# Instantiate the local application.
local_app = local.Application(src="<YOUR_APP_SRC>")
# Get the result of a specific run by its ID.
result_1 = local_app.run_result(run_id="<RUN_ID_1_PRINTED_IN_STEP_2>")
nextmv.write(result_1)
Run the script, or notebook cell, and you should see an output similar to this one:
$ python app3.py
{
"description": "Local run created at 2025-10-03T09:14:49.543398Z",
"id": "local-au9xnvbj",
"metadata": {
"application_id": "/Users/sebastian-quintero/nextmv/github/nextmv-py/nextmv/app-voo59k17",
"application_instance_id": "",
"application_version_id": "",
"created_at": "2025-10-03T09:14:49.543398Z",
"duration": 1311.6,
"error": "",
"input_size": 62.0,
"output_size": 0.0,
"format": {
"input": {
"type": "json"
},
"output": {
"type": "json"
}
},
"status_v2": "succeeded"
},
"name": "local run local-au9xnvbj",
"user_email": "",
"console_url": "",
"synced_run_id": "devint-D6OCps3Ng",
"synced_at": "2025-10-03T09:15:06.868320Z",
"output": {
"options": {
"details": true
},
"solution": {
"message": "Hello, Patches"
},
"statistics": {
"result": {
"value": 1.23,
"custom": {
"message": "Hello, Patches"
}
},
"schema": "v1"
},
"assets": [...]
}
}
You'll notice that the .output field contains the same output that is
produced by "manually" running the app. However, the run result also contains
information about the run, such as its ID, creation time, duration, status, and
more.
Note
The Nextmv SDK keeps track of all the local runs you create inside your application.
4. Get run information¶
Runs may take a while to complete. We recommend you poll for the run status
until it is completed. Once the run is completed, you can get the run result as
shown above. To get the run information, use the run ID and the
local.Application.run_metadata method.
Create another script, which you can name app4.py, or use another cell in the
Jupyter notebook. Copy and paste the following code into it, making sure you
use the correct run ID (one of the identifiers that were printed in step 2) and
app src:
import nextmv
from nextmv import local
# Instantiate the local application.
local_app = local.Application(src="<YOUR_APP_SRC>")
# Get the information of a specific run by its ID.
result_info_2 = local_app.run_metadata(run_id="<RUN_ID_2_PRINTED_IN_STEP_2>")
nextmv.write(result_info_2)
Run the script, or notebook cell, and you should see an output similar to this one:
$ python app4.py
{
"description": "Local run created at 2025-11-14T19:43:15.237810Z",
"id": "local-ykfq7nej",
"metadata": {
"application_id": "app-ptpe0h5s",
"application_instance_id": "",
"application_version_id": "",
"created_at": "2025-11-14T19:43:15.237810Z",
"duration": 766.6,
"error": "",
"input_size": 62.0,
"output_size": 0.0,
"format": {
"input": {
"type": "json"
},
"output": {
"type": "json"
}
},
"status_v2": "succeeded"
},
"name": "local run local-ykfq7nej",
"user_email": "",
"console_url": ""
}
As you can see, the run information contains metadata about the run, such as its status, creation time, and more.
5. All in one¶
Since runs are started in the background, you should poll until the run
succeeds (or fails) to get the results. You can use the
local.Application.new_run_with_result method
to do everything:
- Start a run
- Poll for results
- Return them
Create another script, which you can name app5.py, or use another cell in the
Jupyter notebook. Copy and paste the following code into it, making sure you
use the correct app src:
import nextmv
from nextmv import local
# Instantiate the local application.
local_app = local.Application(src="<YOUR_APP_SRC>")
# Provide any input you want for the app. This input can come from a file, for
# example.
input = {
"name": "Patches",
"radius": 6378,
"distance": 147.6,
}
# Start a new run and get its result immediately.
result_3 = local_app.new_run_with_result(input=input)
nextmv.write(result_3)
Run the script, or notebook cell, and you should see an output similar to the one shown in the getting a run result section.
$ python app5.py
{
"description": "Local run created at 2025-11-14T20:12:13.058486Z",
"id": "local-xfsgm9t7",
"metadata": {
"application_id": "app-ptpe0h5s",
"application_instance_id": "",
"application_version_id": "",
"created_at": "2025-11-14T20:12:13.058486Z",
"duration": 759.4,
"error": "",
"input_size": 62.0,
"output_size": 0.0,
"format": {
"input": {
"type": "json"
},
"output": {
"type": "json"
}
},
"status_v2": "succeeded"
},
"name": "local run local-xfsgm9t7",
"user_email": "",
"console_url": "",
"output": {
"options": {
"details": true
},
"solution": {
"message": "Hello, Patches"
},
"statistics": {
"result": {
"value": 1.23,
"custom": {
"message": "Hello, Patches"
}
},
"schema": "v1"
},
"assets": [...]
}
}
The complete methodology for running is discussed in detail in the runs tutorial.
6. Visualize assets¶
The sample app comes with some simple visuals to illustrate how to produce
assets from your decision model. You can visualize the assets locally with the
local.Application.run_visuals method.
Create another script, which you can name app6.py, or use another cell in the
Jupyter notebook. Copy and paste the following code into it, making sure you
use the correct run ID (one of the identifiers that were printed in step 2) and
app src:
from nextmv import local
# Instantiate the local application.
local_app = local.Application(src="<YOUR_APP_SRC>")
# Display the visuals of a specific run by its ID.
local_app.run_visuals(run_id="<RUN_ID_1_PRINTED_IN_STEP_2>")
This will open a browser window for each asset produced by the run. You should see a simple plot like the following:

Warning
The run_visuals method may not work as expected in a Jupyter notebook
environment. We recommend running it from a script executed in a terminal.
7. Understanding what happened¶
If you inspect the application directory created in step 1 again, you will see a structure similar to the following:
app-<RANDOM_IDENTIFIER>
├── .gitignore
├── .nextmv
│ └── runs
│ ├── {RUN_ID_1}
│ │ ├── inputs
│ │ │ └── input.json
│ │ ├── {RUN_ID_1}.json
│ │ ├── logs
│ │ │ └── logs.log
│ │ ├── outputs
│ │ │ ├── assets
│ │ │ │ └── assets.json
│ │ │ ├── solutions
│ │ │ │ └── solution.json
│ │ │ └── statistics
│ │ │ └── statistics.json
│ │ └── visuals
│ │ └── Charts_0.html
│ ├── {RUN_ID_2}
│ │ ├── inputs
│ │ │ └── input.json
│ │ ├── {RUN_ID_2}.json
│ │ ├── logs
│ │ │ └── logs.log
│ │ ├── outputs
│ │ │ ├── assets
│ │ │ │ └── assets.json
│ │ │ ├── solutions
│ │ │ │ └── solution.json
│ │ │ └── statistics
│ │ │ └── statistics.json
│ │ └── visuals
│ │ └── Charts_0.html
│ └── {RUN_ID_3}
│ ├── inputs
│ │ └── input.json
│ ├── {RUN_ID_3}.json
│ ├── logs
│ │ └── logs.log
│ ├── outputs
│ │ ├── assets
│ │ │ └── assets.json
│ │ ├── solutions
│ │ │ └── solution.json
│ │ └── statistics
│ │ └── statistics.json
│ └── visuals
│ └── Charts_0.html
├── app.yaml
├── input.json
├── main.py
├── README.md
├── requirements.txt
└── src
├── __init__.py
└── visuals.py
The .nextmv dir is used to store and manage the local applications runs in
a structured way. The local package is used to interact with these files,
with methods for starting runs, retrieving results, visualizing charts, and
more.
🎉🎉🎉 Congratulations, you have finished this tutorial!
Next steps¶
You have successfully:
- Created a new Nextmv Application.
- Ran it locally.
- Obtained run results.
- Visualized assets.
After you complete exploring the local experience, you can unleash the full
potential of the Nextmv Platform with Cloud.