Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 0 additions & 40 deletions .github/workflows/static.yml

This file was deleted.

2 changes: 2 additions & 0 deletions .nextmv/readme/python-wf-custom-visuals/0.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export NEXTMV_API_KEY=<your-nextmv-api-key>
cat input.json | python3 main.py
2 changes: 2 additions & 0 deletions .nextmv/readme/python-wf-custom-visuals/1.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
nextmv app push -a <app-id>
nextmv app run -a <app-id> --input input.json -s <secrets-collection-id>
6 changes: 6 additions & 0 deletions .nextmv/readme/workflow-configuration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,12 @@ apps:
silent: true
- name: 2.sh
skip: true
- name: python-wf-custom-visuals
scripts:
- name: 0.sh
skip: true
- name: 1.sh
skip: true
- name: python-wf-databricks
scripts:
- name: 0.sh
Expand Down
69 changes: 69 additions & 0 deletions python-wf-custom-visuals/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Basic Workflow App for Custom Visuals

This example demonstrates how to create custom visual assets via a workflow app.
While the Nextmv console already provides a built-in visualization for routes,
this example shows how to create a custom visualization for rendering the routes
as clusters. This is useful when you want to more clearly visualize the
distribution of routes. For this, the example makes use of nextroute's (_Nextmv
Routing_) **cluster** functionality.

## Prerequisites

This example uses the _Nextmv Routing Marketplace App_. To run this example, do
the following:

1. Subscribe to the _Nextmv Routing Marketplace App_ in the [Nextmv console][console].
- Set the App ID to `routing-nextroute`.
1. Create a **workflow** app in the [Nextmv console][console]. Note that this
needs to specifically be a _workflow_ app. Note the App ID, it is referenced
as `<app-id>` in the commands below.
1. Create a secrets collection in your new app via [console][console] and add
your `NEXTMV_API_KEY` as an environment variable to it. Note the
collection ID, it is referenced as `<secrets-collection-id>` in the commands
below.
1. Install the [Nextmv CLI][cli] if you haven't done so already.

## Run the workflow locally

It is possible to run (and debug) the workflow locally. To do this, you need to
have supported Python version installed, as well as export the `NEXTMV_API_KEY`
environment variable with your Nextmv API key.

```bash
export NEXTMV_API_KEY=<your-nextmv-api-key>
cat input.json | python3 main.py
```

## Run the workflow remotely

For running the workflow remotely, we need to first push the app. Then, we can
make a remote run using the Nextmv CLI (alternatively, you can make a run using
the [Nextmv console][console]).

```bash
nextmv app push -a <app-id>
nextmv app run -a <app-id> --input input.json -s <secrets-collection-id>
```

## Sneak peek

When you run the workflow, it will attach the custom visual asset to the run.
You can see these in [console][console] for example. Here is a sneak peek of
them.

Routes plotted as clusters:

![sneak peek clusters](https://nextmv-io.github.io/community-apps/apps/python-wf-custom-visuals/clusters.png)

## Next steps

- Modify the workflow in `main.py` to suit your needs.
- Visit our [general docs][docs], [workflow docs][workflow] and [blog][blog].
Need more assistance? [Contact][contact] us!

[console]: https://cloud.nextmv.io
[docs]: https://docs.nextmv.io
[workflow]: https://nextpipe.readthedocs.io/en/latest/
[cli]: https://docs.nextmv.io/docs/using-nextmv/setup/install#nextmv-cli
[blog]: https://www.nextmv.io/blog
[contact]: https://www.nextmv.io/contact
6 changes: 6 additions & 0 deletions python-wf-custom-visuals/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type: python
runtime: ghcr.io/nextmv-io/runtime/python:3.11
files:
- main.py
python:
pip-requirements: requirements.txt
167 changes: 167 additions & 0 deletions python-wf-custom-visuals/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
{
"defaults": {
"vehicles": {
"start_time": "2024-11-07T11:00:00+00:00",
"speed": 10,
"capacity": 32
},
"stops": { "quantity": -1, "unplanned_penalty": 2000000000 }
},
"vehicles": [
{ "id": "vehicle-1" },
{ "id": "vehicle-2" },
{ "id": "vehicle-3" },
{ "id": "vehicle-4" },
{ "id": "vehicle-5" }
],
"stops": [
{ "id": "location-1", "location": { "lon": 7.6405, "lat": 51.9692 } },
{ "id": "location-2", "location": { "lon": 7.6222, "lat": 51.9711 } },
{ "id": "location-3", "location": { "lon": 7.6159, "lat": 51.961 } },
{ "id": "location-4", "location": { "lon": 7.6184, "lat": 51.9562 } },
{ "id": "location-5", "location": { "lon": 7.6408, "lat": 51.9641 } },
{ "id": "location-6", "location": { "lon": 7.6143, "lat": 51.9714 } },
{ "id": "location-7", "location": { "lon": 7.6402, "lat": 51.9749 } },
{ "id": "location-8", "location": { "lon": 7.6161, "lat": 51.9624 } },
{ "id": "location-9", "location": { "lon": 7.6134, "lat": 51.9683 } },
{ "id": "location-10", "location": { "lon": 7.6115, "lat": 51.9701 } },
{ "id": "location-11", "location": { "lon": 7.6208, "lat": 51.9624 } },
{ "id": "location-12", "location": { "lon": 7.6261, "lat": 51.962 } },
{ "id": "location-13", "location": { "lon": 7.6233, "lat": 51.9638 } },
{ "id": "location-14", "location": { "lon": 7.6372, "lat": 51.9682 } },
{ "id": "location-15", "location": { "lon": 7.6314, "lat": 51.9641 } },
{ "id": "location-16", "location": { "lon": 7.6148, "lat": 51.9703 } },
{ "id": "location-17", "location": { "lon": 7.628, "lat": 51.9635 } },
{ "id": "location-18", "location": { "lon": 7.6261, "lat": 51.9595 } },
{ "id": "location-19", "location": { "lon": 7.6279, "lat": 51.9651 } },
{ "id": "location-20", "location": { "lon": 7.6098, "lat": 51.943 } },
{ "id": "location-21", "location": { "lon": 7.6297, "lat": 51.9662 } },
{ "id": "location-22", "location": { "lon": 7.6047, "lat": 51.9604 } },
{ "id": "location-23", "location": { "lon": 7.6104, "lat": 51.9567 } },
{ "id": "location-24", "location": { "lon": 7.6337, "lat": 51.9581 } },
{ "id": "location-25", "location": { "lon": 7.6101, "lat": 51.9611 } },
{ "id": "location-26", "location": { "lon": 7.6255, "lat": 51.9693 } },
{ "id": "location-27", "location": { "lon": 7.5972, "lat": 51.9487 } },
{ "id": "location-28", "location": { "lon": 7.6333, "lat": 51.9699 } },
{ "id": "location-29", "location": { "lon": 7.6087, "lat": 51.9595 } },
{ "id": "location-30", "location": { "lon": 7.6154, "lat": 51.9546 } },
{ "id": "location-31", "location": { "lon": 7.5977, "lat": 51.9673 } },
{ "id": "location-32", "location": { "lon": 7.6278, "lat": 51.967 } },
{ "id": "location-33", "location": { "lon": 7.6212, "lat": 51.9509 } },
{ "id": "location-34", "location": { "lon": 7.6239, "lat": 51.9478 } },
{ "id": "location-35", "location": { "lon": 7.6167, "lat": 51.9458 } },
{ "id": "location-36", "location": { "lon": 7.6165, "lat": 51.9599 } },
{ "id": "location-37", "location": { "lon": 7.6468, "lat": 51.9697 } },
{ "id": "location-38", "location": { "lon": 7.6496, "lat": 51.9488 } },
{ "id": "location-39", "location": { "lon": 7.6061, "lat": 51.9556 } },
{ "id": "location-40", "location": { "lon": 7.6361, "lat": 51.97 } },
{ "id": "location-41", "location": { "lon": 7.6364, "lat": 51.9594 } },
{ "id": "location-42", "location": { "lon": 7.6444, "lat": 51.9524 } },
{ "id": "location-43", "location": { "lon": 7.6174, "lat": 51.9676 } },
{ "id": "location-44", "location": { "lon": 7.6274, "lat": 51.9553 } },
{ "id": "location-45", "location": { "lon": 7.6431, "lat": 51.9718 } },
{ "id": "location-46", "location": { "lon": 7.6047, "lat": 51.9642 } },
{ "id": "location-47", "location": { "lon": 7.6125, "lat": 51.9726 } },
{ "id": "location-48", "location": { "lon": 7.6165, "lat": 51.9499 } },
{ "id": "location-49", "location": { "lon": 7.6375, "lat": 51.9565 } },
{ "id": "location-50", "location": { "lon": 7.6023, "lat": 51.971 } },
{ "id": "location-51", "location": { "lon": 7.6295, "lat": 51.9594 } },
{ "id": "location-52", "location": { "lon": 7.6106, "lat": 51.9691 } },
{ "id": "location-53", "location": { "lon": 7.6146, "lat": 51.9592 } },
{ "id": "location-54", "location": { "lon": 7.6145, "lat": 51.9727 } },
{ "id": "location-55", "location": { "lon": 7.6344, "lat": 51.9713 } },
{ "id": "location-56", "location": { "lon": 7.6194, "lat": 51.9474 } },
{ "id": "location-57", "location": { "lon": 7.6373, "lat": 51.9577 } },
{ "id": "location-58", "location": { "lon": 7.6292, "lat": 51.9591 } },
{ "id": "location-59", "location": { "lon": 7.6269, "lat": 51.9478 } },
{ "id": "location-60", "location": { "lon": 7.6048, "lat": 51.9615 } },
{ "id": "location-61", "location": { "lon": 7.6116, "lat": 51.9659 } },
{ "id": "location-62", "location": { "lon": 7.6347, "lat": 51.9523 } },
{ "id": "location-63", "location": { "lon": 7.6376, "lat": 51.9783 } },
{ "id": "location-64", "location": { "lon": 7.6302, "lat": 51.9608 } },
{ "id": "location-65", "location": { "lon": 7.6388, "lat": 51.9591 } },
{ "id": "location-66", "location": { "lon": 7.6279, "lat": 51.9701 } },
{ "id": "location-67", "location": { "lon": 7.6223, "lat": 51.9653 } },
{ "id": "location-68", "location": { "lon": 7.6263, "lat": 51.9599 } },
{ "id": "location-69", "location": { "lon": 7.6153, "lat": 51.9688 } },
{ "id": "location-70", "location": { "lon": 7.6206, "lat": 51.963 } },
{ "id": "location-71", "location": { "lon": 7.6299, "lat": 51.9706 } },
{ "id": "location-72", "location": { "lon": 7.6156, "lat": 51.962 } },
{ "id": "location-73", "location": { "lon": 7.6214, "lat": 51.9545 } },
{ "id": "location-74", "location": { "lon": 7.6277, "lat": 51.9687 } },
{ "id": "location-75", "location": { "lon": 7.6513, "lat": 51.9568 } },
{ "id": "location-76", "location": { "lon": 7.6377, "lat": 51.9569 } },
{ "id": "location-77", "location": { "lon": 7.6126, "lat": 51.9701 } },
{ "id": "location-78", "location": { "lon": 7.6195, "lat": 51.9466 } },
{ "id": "location-79", "location": { "lon": 7.6425, "lat": 51.9684 } },
{ "id": "location-80", "location": { "lon": 7.6114, "lat": 51.9715 } },
{ "id": "location-81", "location": { "lon": 7.6367, "lat": 51.956 } },
{ "id": "location-82", "location": { "lon": 7.6289, "lat": 51.9554 } },
{ "id": "location-83", "location": { "lon": 7.6048, "lat": 51.9615 } },
{ "id": "location-84", "location": { "lon": 7.6319, "lat": 51.9677 } },
{ "id": "location-85", "location": { "lon": 7.6164, "lat": 51.9554 } },
{ "id": "location-86", "location": { "lon": 7.6096, "lat": 51.9615 } },
{ "id": "location-87", "location": { "lon": 7.638, "lat": 51.9602 } },
{ "id": "location-88", "location": { "lon": 7.6507, "lat": 51.9532 } },
{ "id": "location-89", "location": { "lon": 7.6271, "lat": 51.9623 } },
{ "id": "location-90", "location": { "lon": 7.6261, "lat": 51.961 } },
{ "id": "location-91", "location": { "lon": 7.619, "lat": 51.973 } },
{ "id": "location-92", "location": { "lon": 7.6257, "lat": 51.9603 } },
{ "id": "location-93", "location": { "lon": 7.642, "lat": 51.9705 } },
{ "id": "location-94", "location": { "lon": 7.6435, "lat": 51.9694 } },
{ "id": "location-95", "location": { "lon": 7.621, "lat": 51.9652 } },
{ "id": "location-96", "location": { "lon": 7.6211, "lat": 51.9537 } },
{ "id": "location-97", "location": { "lon": 7.6332, "lat": 51.9647 } },
{ "id": "location-98", "location": { "lon": 7.6325, "lat": 51.972 } },
{ "id": "location-99", "location": { "lon": 7.6218, "lat": 51.9827 } },
{ "id": "location-100", "location": { "lon": 7.6261, "lat": 51.9702 } },
{ "id": "location-101", "location": { "lon": 7.6249, "lat": 51.9626 } },
{ "id": "location-102", "location": { "lon": 7.6232, "lat": 51.9643 } },
{ "id": "location-103", "location": { "lon": 7.6281, "lat": 51.9663 } },
{ "id": "location-104", "location": { "lon": 7.6346, "lat": 51.9578 } },
{ "id": "location-105", "location": { "lon": 7.6367, "lat": 51.9626 } },
{ "id": "location-106", "location": { "lon": 7.6261, "lat": 51.9503 } },
{ "id": "location-107", "location": { "lon": 7.6488, "lat": 51.9551 } },
{ "id": "location-108", "location": { "lon": 7.6131, "lat": 51.9689 } },
{ "id": "location-109", "location": { "lon": 7.6531, "lat": 51.9643 } },
{ "id": "location-110", "location": { "lon": 7.62, "lat": 51.9667 } },
{ "id": "location-111", "location": { "lon": 7.6292, "lat": 51.973 } },
{ "id": "location-112", "location": { "lon": 7.6284, "lat": 51.9626 } },
{ "id": "location-113", "location": { "lon": 7.5999, "lat": 51.9554 } },
{ "id": "location-114", "location": { "lon": 7.6067, "lat": 51.9665 } },
{ "id": "location-115", "location": { "lon": 7.6127, "lat": 51.9621 } },
{ "id": "location-116", "location": { "lon": 7.6428, "lat": 51.9759 } },
{ "id": "location-117", "location": { "lon": 7.6061, "lat": 51.9468 } },
{ "id": "location-118", "location": { "lon": 7.6127, "lat": 51.9621 } },
{ "id": "location-119", "location": { "lon": 7.6168, "lat": 51.9699 } },
{ "id": "location-120", "location": { "lon": 7.6281, "lat": 51.9663 } },
{ "id": "location-121", "location": { "lon": 7.6467, "lat": 51.9583 } },
{ "id": "location-122", "location": { "lon": 7.6456, "lat": 51.952 } },
{ "id": "location-123", "location": { "lon": 7.6317, "lat": 51.9493 } },
{ "id": "location-124", "location": { "lon": 7.6112, "lat": 51.9534 } },
{ "id": "location-125", "location": { "lon": 7.621, "lat": 51.9692 } },
{ "id": "location-126", "location": { "lon": 7.6498, "lat": 51.9651 } },
{ "id": "location-127", "location": { "lon": 7.6296, "lat": 51.9643 } },
{ "id": "location-128", "location": { "lon": 7.6305, "lat": 51.9628 } },
{ "id": "location-129", "location": { "lon": 7.6206, "lat": 51.9597 } },
{ "id": "location-130", "location": { "lon": 7.6422, "lat": 51.9733 } },
{ "id": "location-131", "location": { "lon": 7.6376, "lat": 51.9504 } },
{ "id": "location-132", "location": { "lon": 7.6242, "lat": 51.9581 } },
{ "id": "location-133", "location": { "lon": 7.6263, "lat": 51.9662 } },
{ "id": "location-134", "location": { "lon": 7.6101, "lat": 51.9672 } },
{ "id": "location-135", "location": { "lon": 7.6191, "lat": 51.9551 } },
{ "id": "location-136", "location": { "lon": 7.6206, "lat": 51.9635 } },
{ "id": "location-137", "location": { "lon": 7.6312, "lat": 51.9758 } },
{ "id": "location-138", "location": { "lon": 7.6324, "lat": 51.9683 } },
{ "id": "location-139", "location": { "lon": 7.6144, "lat": 51.9625 } },
{ "id": "location-140", "location": { "lon": 7.618, "lat": 51.9648 } },
{ "id": "location-141", "location": { "lon": 7.6192, "lat": 51.9536 } },
{ "id": "location-142", "location": { "lon": 7.6257, "lat": 51.9589 } },
{ "id": "location-143", "location": { "lon": 7.621, "lat": 51.9528 } },
{ "id": "location-144", "location": { "lon": 7.6444, "lat": 51.9666 } },
{ "id": "location-145", "location": { "lon": 7.6224, "lat": 51.9574 } },
{ "id": "location-146", "location": { "lon": 7.6338, "lat": 51.9682 } },
{ "id": "location-147", "location": { "lon": 7.619, "lat": 51.9635 } },
{ "id": "location-148", "location": { "lon": 7.615, "lat": 51.9658 } }
]
}
Loading
Loading