nextmv 1.0.0.dev6__py3-none-any.whl → 1.0.0.dev8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nextmv/__about__.py +1 -1
- nextmv/_serialization.py +1 -1
- nextmv/cli/cloud/acceptance/create.py +12 -12
- nextmv/cli/cloud/app/push.py +15 -15
- nextmv/cli/cloud/input_set/__init__.py +0 -2
- nextmv/cli/cloud/run/create.py +9 -4
- nextmv/cli/cloud/shadow/stop.py +2 -14
- nextmv/cli/cloud/switchback/stop.py +2 -14
- nextmv/cli/community/clone.py +197 -11
- nextmv/cli/community/list.py +116 -46
- nextmv/cloud/__init__.py +0 -4
- nextmv/cloud/application/__init__.py +200 -1
- nextmv/cloud/application/_input_set.py +6 -42
- nextmv/cloud/application/_run.py +8 -1
- nextmv/cloud/application/_shadow.py +3 -9
- nextmv/cloud/application/_switchback.py +1 -10
- nextmv/cloud/batch_experiment.py +1 -3
- nextmv/cloud/client.py +1 -1
- nextmv/cloud/shadow.py +0 -25
- nextmv/default_app/main.py +4 -6
- nextmv/local/executor.py +83 -3
- nextmv/local/geojson_handler.py +1 -1
- nextmv/manifest.py +11 -7
- nextmv/model.py +2 -2
- nextmv/options.py +1 -1
- nextmv/output.py +57 -21
- nextmv/run.py +12 -3
- {nextmv-1.0.0.dev6.dist-info → nextmv-1.0.0.dev8.dist-info}/METADATA +1 -3
- {nextmv-1.0.0.dev6.dist-info → nextmv-1.0.0.dev8.dist-info}/RECORD +32 -34
- nextmv/cli/cloud/input_set/delete.py +0 -67
- nextmv/cloud/community.py +0 -441
- {nextmv-1.0.0.dev6.dist-info → nextmv-1.0.0.dev8.dist-info}/WHEEL +0 -0
- {nextmv-1.0.0.dev6.dist-info → nextmv-1.0.0.dev8.dist-info}/entry_points.txt +0 -0
- {nextmv-1.0.0.dev6.dist-info → nextmv-1.0.0.dev8.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
nextmv/__about__.py,sha256=
|
|
1
|
+
nextmv/__about__.py,sha256=gaYHqa3kcC-a8tfZv6Hq1-xsB1kwSym282AsDr7hgq8,28
|
|
2
2
|
nextmv/__entrypoint__.py,sha256=XMT-ds1f2Yc6KoI2C0YEH-rJj5gVLfJMqUdRfcA3_KQ,1070
|
|
3
3
|
nextmv/__init__.py,sha256=LwpGBSiV0UG13zKHO2N3Ikb7bCMV08Gfbl6Cp80b_2g,3813
|
|
4
|
-
nextmv/_serialization.py,sha256=
|
|
4
|
+
nextmv/_serialization.py,sha256=fT-GXiy9cNo7D2KL1blZcsAaQHHgkEVTI_JvXIFlWZc,2833
|
|
5
5
|
nextmv/base_model.py,sha256=kPFqE-c_3LcEy8fY0qDrJk_gbPYgSKtetRMby71oxE8,2298
|
|
6
6
|
nextmv/deprecated.py,sha256=U1YD-vie0dEVWFJgIwOuinxACHsyiEIQpfrt95ykhlg,1651
|
|
7
7
|
nextmv/input.py,sha256=iONLkXhcIXRCJVPNVkJdivh47A399VMepsSxNZByX2I,37649
|
|
8
8
|
nextmv/logger.py,sha256=kNIbu46MisrzYe4T0hNMpWfRTKKacDVvbtQcNys_c_E,2513
|
|
9
|
-
nextmv/manifest.py,sha256=
|
|
10
|
-
nextmv/model.py,sha256=
|
|
11
|
-
nextmv/options.py,sha256=
|
|
12
|
-
nextmv/output.py,sha256=
|
|
9
|
+
nextmv/manifest.py,sha256=VoZo7cGKGCdmcxDu5ECTZPY67J4LAUxBu6gmhgXVWRY,49216
|
|
10
|
+
nextmv/model.py,sha256=uthHjRCrC1b9OCoyQ_n-2_nfP1bFu-nMiUxYhmLf0SI,14989
|
|
11
|
+
nextmv/options.py,sha256=3BnnuAoiFD6qr0EMYv1VgAXarDjLb-t7OpC1IpsnS1M,29648
|
|
12
|
+
nextmv/output.py,sha256=7ioVUlsQiQP9MeR6baUXs9C-5q6jcBteu1DUNExcHCw,55707
|
|
13
13
|
nextmv/polling.py,sha256=fwnAxmfpuBg4d6pi53TRTyyefdpf-cHLoTG6trAu-QA,11048
|
|
14
|
-
nextmv/run.py,sha256=
|
|
14
|
+
nextmv/run.py,sha256=o6_nSPOYwGCsCaqmYYAwrtCLE_aJuqy5NHFRfXYE7TI,54440
|
|
15
15
|
nextmv/safe.py,sha256=VAK4fGEurbLNji4Pg5Okga5XQSbI4aI9JJf95_68Z20,3867
|
|
16
16
|
nextmv/status.py,sha256=VqmOgxiEK89Y88ZUxZPfUXmY0HqvN28Lc1PDt0-9PLw,1600
|
|
17
17
|
nextmv/cli/CONTRIBUTING.md,sha256=xM_skfI1WPh2UtZ1axbB8AfOLJ3LZk8YhQpZY4qtSqw,21911
|
|
@@ -23,7 +23,7 @@ nextmv/cli/options.py,sha256=ymd6Y7_ZQkln35nHw3pLnFpqivgmJfuYAnyizmEuonc,6887
|
|
|
23
23
|
nextmv/cli/version.py,sha256=VRbfNpUvCFYPcphr-F3Ph4Z4UwtVis4keyVFHj1JISw,681
|
|
24
24
|
nextmv/cli/cloud/__init__.py,sha256=pywNNBy_poHaKn3_oIZRR9DDE8w3u65KvLpnX6S0BQI,1886
|
|
25
25
|
nextmv/cli/cloud/acceptance/__init__.py,sha256=v4U1m6z5zI8mQpmIE4kFeEYOsaDxnGRnRj2j5I6WueI,711
|
|
26
|
-
nextmv/cli/cloud/acceptance/create.py,sha256=
|
|
26
|
+
nextmv/cli/cloud/acceptance/create.py,sha256=lc1EYydsIuxr2qiQ_0W7po8DnPIfXSYR-5cm_6ddYGA,14604
|
|
27
27
|
nextmv/cli/cloud/acceptance/delete.py,sha256=julZ6Bs6YcsmyuE00yPjPScIRz4QteNt-GUR4J2Hp_I,2260
|
|
28
28
|
nextmv/cli/cloud/acceptance/get.py,sha256=pb3hRdIiynTi4K7xDNCMJE7bW46FE-X3EoAQU8kQJjE,3438
|
|
29
29
|
nextmv/cli/cloud/acceptance/list.py,sha256=9tTV4B2lgDqNxDnaNXkHxeh7jUQuAu9GQJsEKJ_NqIo,1881
|
|
@@ -39,7 +39,7 @@ nextmv/cli/cloud/app/delete.py,sha256=HLgDx4eMf_LYyGC8aQxuvNrhOfnWmDuutPjk4ywILa
|
|
|
39
39
|
nextmv/cli/cloud/app/exists.py,sha256=gd9pmR1Oq_cCjaTNB82PmJtDYowrb17vBfQYjoh6E9Q,1258
|
|
40
40
|
nextmv/cli/cloud/app/get.py,sha256=_v_7PrUniaaRvHclBA02V-UVcbVe1eFixGU6CeXA4m4,1765
|
|
41
41
|
nextmv/cli/cloud/app/list.py,sha256=AI1VNNueYfzwuSAFlf-vXbZEY-th5BrzXZgn-3uusFo,1653
|
|
42
|
-
nextmv/cli/cloud/app/push.py,sha256=
|
|
42
|
+
nextmv/cli/cloud/app/push.py,sha256=mbGThAgmfxO2JqfXq8HXAdRT81b55MBfCGaDtSJQsUM,15624
|
|
43
43
|
nextmv/cli/cloud/app/update.py,sha256=4Mp8Zf40K1hdHO3KT9Md3piBWqzracfpWtujJfbPocM,4070
|
|
44
44
|
nextmv/cli/cloud/batch/__init__.py,sha256=-_UjmvrQItACUY_BQ_cOffNJixNHAb4vH_pew25sJ3o,774
|
|
45
45
|
nextmv/cli/cloud/batch/create.py,sha256=T70sjvvTxXxRpC4COFZFU5ei6ylS5MWLg6VLP3SjIso,15465
|
|
@@ -56,9 +56,8 @@ nextmv/cli/cloud/ensemble/delete.py,sha256=C1xmISSaUhtsV94w2z2rzhenp2mm9E0GXHy4d
|
|
|
56
56
|
nextmv/cli/cloud/ensemble/get.py,sha256=-4crRjI8MF8meq5uUhUR3q39lK4EIsvpzaODfGvwx3k,2135
|
|
57
57
|
nextmv/cli/cloud/ensemble/list.py,sha256=zm7TfBM5HH_8I-r4U219AbmQadET96kw1MrsjwARSAM,1887
|
|
58
58
|
nextmv/cli/cloud/ensemble/update.py,sha256=5AeuhY-CytzON1FFoEijBlo1T9oHvkq3mxV9I3qCeLA,3383
|
|
59
|
-
nextmv/cli/cloud/input_set/__init__.py,sha256=
|
|
59
|
+
nextmv/cli/cloud/input_set/__init__.py,sha256=wyt0LX9xqcGDrb-rPx-MN0WQA7o9jZnK2CpShfrki3o,867
|
|
60
60
|
nextmv/cli/cloud/input_set/create.py,sha256=nJWsaj-fPXS8rwIbh13_wXc9SitDA4ByIHhlBS51GHo,5661
|
|
61
|
-
nextmv/cli/cloud/input_set/delete.py,sha256=8-cJtgcgh_kK0K7AtHZmYSCvTmxwtyQIhWcmt6aYAZI,2125
|
|
62
61
|
nextmv/cli/cloud/input_set/get.py,sha256=MvMD6tmMA_ui4MVCwRkOnmU0WySJmSJX7x2Q-x_xXwA,1916
|
|
63
62
|
nextmv/cli/cloud/input_set/list.py,sha256=7I0F1rs19bY9d_V2TjEFxHCbHq3bNV_mO0Fd9qJ58IY,1896
|
|
64
63
|
nextmv/cli/cloud/input_set/update.py,sha256=P5b94m08hGMAGr455fH-Cd1yryeMC15r1YfmJEt2NSw,4144
|
|
@@ -77,7 +76,7 @@ nextmv/cli/cloud/managed_input/list.py,sha256=6l4zJPVErmooobteBn05RmoXHgvI0RBt_L
|
|
|
77
76
|
nextmv/cli/cloud/managed_input/update.py,sha256=E1ddfQ9VJ7SgG8V6kkRYbgKhS4vDyv06WePNbLEXUsE,3191
|
|
78
77
|
nextmv/cli/cloud/run/__init__.py,sha256=KyonwVd5lfweaq-cIpPuRAzHFrK0slfqJsIjsT_p4PU,1102
|
|
79
78
|
nextmv/cli/cloud/run/cancel.py,sha256=d7aQQQmek_i3P2cDmpOohLiwSjWxfKEiVAvBnNYAmuE,1259
|
|
80
|
-
nextmv/cli/cloud/run/create.py,sha256=
|
|
79
|
+
nextmv/cli/cloud/run/create.py,sha256=eGjlYCWGf_57Qlqbaok-iLzcLmHAaCZor6TskhMabPk,19706
|
|
81
80
|
nextmv/cli/cloud/run/get.py,sha256=bUczN6a1SV3wkW0uUPfQdO3i13BF51udixmuyiicdi8,7826
|
|
82
81
|
nextmv/cli/cloud/run/input.py,sha256=QEdDnKxEmucUwPPRAqh1VuErw5rKaAwXOHrmJESP-k0,3171
|
|
83
82
|
nextmv/cli/cloud/run/list.py,sha256=z3286Q0Aznz-qAvanCB03rXjCfGPk84A32t8AqTC2Cs,2563
|
|
@@ -104,7 +103,7 @@ nextmv/cli/cloud/shadow/get.py,sha256=8NmXl2romVPGfS9KP4G2Sv4SuSZKgRx85GZ4ClwTqW
|
|
|
104
103
|
nextmv/cli/cloud/shadow/list.py,sha256=aVFa3FAzfcUsMlD0hYgZwhoF75GQkaNDHrrq82qqylQ,1810
|
|
105
104
|
nextmv/cli/cloud/shadow/metadata.py,sha256=vHJYVDXXHwiqQrG0J0D_aRP--b47UfEgJwJOXqfskSo,2161
|
|
106
105
|
nextmv/cli/cloud/shadow/start.py,sha256=SkDYSfyQLdfHJKCOzc4CW6MVO7YBWCZCOAoGBzqSFhI,1464
|
|
107
|
-
nextmv/cli/cloud/shadow/stop.py,sha256=
|
|
106
|
+
nextmv/cli/cloud/shadow/stop.py,sha256=gb6UuNf-HNCaACKzdAix1pr8oMn-A1SQJEFUXrOr228,1333
|
|
108
107
|
nextmv/cli/cloud/shadow/update.py,sha256=l7_gODO9fXYGOLzFMJmIVpT5Jku9XQAo2PI5x3AP4xU,2880
|
|
109
108
|
nextmv/cli/cloud/switchback/__init__.py,sha256=jYeujjbqvqRGIgvC0wr3I6zavw1az7IS8jiJsAlH-z4,981
|
|
110
109
|
nextmv/cli/cloud/switchback/create.py,sha256=lEboNjN1ZFbuOCFmK2ADIRH-pIENc80NcR809rDOY3I,5085
|
|
@@ -113,7 +112,7 @@ nextmv/cli/cloud/switchback/get.py,sha256=GQKzaW4jCfV21DyZ5vDNrkFH2Tw1pR8Zv_71ji
|
|
|
113
112
|
nextmv/cli/cloud/switchback/list.py,sha256=wrXXA9aMLLcq_6WFk-dy9RopE57dFZb7TxlWdRx9G94,1882
|
|
114
113
|
nextmv/cli/cloud/switchback/metadata.py,sha256=WDhK-AVKEJQ38WhPZqPOgemHt-PI__r6sIEBFQtKxVw,2287
|
|
115
114
|
nextmv/cli/cloud/switchback/start.py,sha256=N9Bci8DmCQW8XUm93Rhj30TCf_YvK6N5qxZXMpW2X1I,1535
|
|
116
|
-
nextmv/cli/cloud/switchback/stop.py,sha256=
|
|
115
|
+
nextmv/cli/cloud/switchback/stop.py,sha256=xEF2JqDhOhxzli79qqwIGVJiNW14BnfEbfc70sXF7dE,1397
|
|
117
116
|
nextmv/cli/cloud/switchback/update.py,sha256=pILZUbqlIM6l1mrbVPtks6CGcgre5829sSnD2yMZd-0,3000
|
|
118
117
|
nextmv/cli/cloud/upload/__init__.py,sha256=khOl6NxkPd4KEqN0xMdxzmST-Ct3Vr_xk8zbMvbrLl8,511
|
|
119
118
|
nextmv/cli/cloud/upload/create.py,sha256=vRTHCeh7cbB9JSAMUCpcdQrzQ1od5FiFiNdPPh7sFqw,1216
|
|
@@ -125,20 +124,19 @@ nextmv/cli/cloud/version/get.py,sha256=eGbka3TG8UJE150h22rn0BUqTi1xRE7roVDj6yJvn
|
|
|
125
124
|
nextmv/cli/cloud/version/list.py,sha256=sKdHgyowLG1jyUEtu87yCPC5_2-0i3VDEgfmvb-bBn0,1770
|
|
126
125
|
nextmv/cli/cloud/version/update.py,sha256=mEUYXGHLGkiEGH31KK6jDDfviHEhVCdLjLQL_5u0vLk,2869
|
|
127
126
|
nextmv/cli/community/__init__.py,sha256=t2l6adm9Km6hSvSFzeKHTQzacVSnwjx4wpj2kqee5nM,612
|
|
128
|
-
nextmv/cli/community/clone.py,sha256=
|
|
129
|
-
nextmv/cli/community/list.py,sha256=
|
|
127
|
+
nextmv/cli/community/clone.py,sha256=qXDgsMfAnAcZvP9kOp-O4rqj0qw0zueg9BgWl71DqpA,9202
|
|
128
|
+
nextmv/cli/community/list.py,sha256=ad7qPPaNh29tj_ggR4lJnRkMTgWstHQFV90sqdiWcdA,7440
|
|
130
129
|
nextmv/cli/configuration/__init__.py,sha256=7oryF4PKkORh8bcdgbN2k36rZrFpJsM7Xfq_J4-MkFs,516
|
|
131
130
|
nextmv/cli/configuration/config.py,sha256=t43ubCcbfbpfq9HvkVb2WQY9V47lrLEP0KvsWfjOJ8Y,6667
|
|
132
131
|
nextmv/cli/configuration/create.py,sha256=aDj6wFl6_RRMmvCLTNIeCcFotNOGoupso785M46nh2Y,2668
|
|
133
132
|
nextmv/cli/configuration/delete.py,sha256=3l1Mx8ATCwoiggbYBjG0ArmYSbS_GlJ5cCCymG2CEhU,1935
|
|
134
133
|
nextmv/cli/configuration/list.py,sha256=HIZvDJQW5B0-o_ZqQHuxRw7N_VmxqYM46fucKCvo1zw,2208
|
|
135
|
-
nextmv/cloud/__init__.py,sha256=
|
|
134
|
+
nextmv/cloud/__init__.py,sha256=watvsgucVgOCIlwrmnvIxW8lyUfEerhDzOn-Zp-dl1I,3954
|
|
136
135
|
nextmv/cloud/acceptance_test.py,sha256=H34lvccJzN1URpnhrHstcVxgvq1s2iCymiKIPBHcToY,25828
|
|
137
136
|
nextmv/cloud/account.py,sha256=X2xQjzhgEdKR0eypH8lWKUOwDISjJSd5SwOwEnpfTVk,13573
|
|
138
137
|
nextmv/cloud/assets.py,sha256=alw634ub-DR0CHQXZy_ObeGvQthPXFLdgzgbvbH1SGY,1376
|
|
139
|
-
nextmv/cloud/batch_experiment.py,sha256=
|
|
140
|
-
nextmv/cloud/client.py,sha256=
|
|
141
|
-
nextmv/cloud/community.py,sha256=LSiKF5agLTHFbW5fBAv-m3MsWm3XuROpw4_KkPpwtZM,13060
|
|
138
|
+
nextmv/cloud/batch_experiment.py,sha256=thS94-ZdMR7Em5TeGN5UtnIDHmhzqld_U49SODyhrPU,10537
|
|
139
|
+
nextmv/cloud/client.py,sha256=FGyzpwPBXMiiT4Jr2DLvWzzhjQ64AdadPDACaCuIDGM,18100
|
|
142
140
|
nextmv/cloud/ensemble.py,sha256=_hKPjSLtuGH1xGG70ZBsmY_IL5XinZqVHHwBxtX9Omw,8570
|
|
143
141
|
nextmv/cloud/input_set.py,sha256=wsLmMI1C7BslWDN5j1RnVUA8z54-Hq1eLG9bkzyqafo,4187
|
|
144
142
|
nextmv/cloud/instance.py,sha256=rLrgNNvNyC6hZtjxIfTR2Luylmbh2emJIZVCy_hTJZ4,5495
|
|
@@ -146,40 +144,40 @@ nextmv/cloud/integration.py,sha256=S4BNX3GFGNA1SXDWaRAUeS0hW6XkYXWSdWXX-s-x_nA,1
|
|
|
146
144
|
nextmv/cloud/package.py,sha256=88XSJ15QGcHboNJAw2hGowiLKBu2O2nV5ZieZFx7XDI,17133
|
|
147
145
|
nextmv/cloud/scenario.py,sha256=1_4PI9ehYaSonEe_l59cFhZNmqQ_brXXP6-mVq9i8a8,14183
|
|
148
146
|
nextmv/cloud/secrets.py,sha256=fA5cX0jfTsPVZWV7433wzETGlXpWRLHGswuObx9e6FQ,6820
|
|
149
|
-
nextmv/cloud/shadow.py,sha256=
|
|
147
|
+
nextmv/cloud/shadow.py,sha256=DWJfFkwlbULdl988A1HkOsyQGq0l9xtLT8Q-ZzsepH0,7214
|
|
150
148
|
nextmv/cloud/switchback.py,sha256=AGA0LDMu7sHndczy2TrcZghn_ZRnTGlBDmGRZG34dZY,7344
|
|
151
149
|
nextmv/cloud/url.py,sha256=Fz70ywkWdCLmP21ZBmJwZi5kDbjpmsX_VlwVF_xQeHg,1836
|
|
152
150
|
nextmv/cloud/version.py,sha256=5_S7_pWUVBFbvAArku20eK7S645GJcHtgE2OpXLdSzQ,5300
|
|
153
|
-
nextmv/cloud/application/__init__.py,sha256=
|
|
151
|
+
nextmv/cloud/application/__init__.py,sha256=E1Q-WIly_PiNg1ynMynA81SwX88Q6uH_lqWKtQQX0tg,40369
|
|
154
152
|
nextmv/cloud/application/_acceptance.py,sha256=ZwbVkur3-1fwM_L4F8ZUqrNaIdHgYGxKd3utoOCWjSc,13679
|
|
155
153
|
nextmv/cloud/application/_batch_scenario.py,sha256=cSsX5vPOkm91UqRBPIcqlOvQ0iojwt4sQKYGZEE7x6k,28479
|
|
156
154
|
nextmv/cloud/application/_ensemble.py,sha256=05l9uR0hTnW8nQjhRzjd2TPfvCoaAqNddWP-aVRL5rg,7666
|
|
157
|
-
nextmv/cloud/application/_input_set.py,sha256=
|
|
155
|
+
nextmv/cloud/application/_input_set.py,sha256=m7PKqhR3evdE_a_RER1L6iKwftlaxTiRd1JQvgCepUU,7069
|
|
158
156
|
nextmv/cloud/application/_instance.py,sha256=Jjig8NI1jXNyBQoYj7JOfS0JFmw5jJdKLfi82fqBYgo,8386
|
|
159
157
|
nextmv/cloud/application/_managed_input.py,sha256=zaWqGpe8Y5XWheroAqZSo-xNHfn2MKblNwRUbQVXBRM,6694
|
|
160
|
-
nextmv/cloud/application/_run.py,sha256=
|
|
158
|
+
nextmv/cloud/application/_run.py,sha256=LgSKm537F0ej-LTsMVmabkyOBtFnaHjvAdInnPzL6UI,53898
|
|
161
159
|
nextmv/cloud/application/_secrets.py,sha256=hWhPAyY8aDF8zlEz9opPNLrFOYtp-COFqG_jgOZ6VxI,9476
|
|
162
|
-
nextmv/cloud/application/_shadow.py,sha256=
|
|
163
|
-
nextmv/cloud/application/_switchback.py,sha256=
|
|
160
|
+
nextmv/cloud/application/_shadow.py,sha256=8uH0Zr-9czef2BhshYLzc0yBQhIcIdBYTCIiUS1ru44,9123
|
|
161
|
+
nextmv/cloud/application/_switchback.py,sha256=MapHkquya7SeyNnEVIy7E7Um_9VuMH7XiB7FFxZx6Po,9743
|
|
164
162
|
nextmv/cloud/application/_utils.py,sha256=GqksGBHCV2sc-itL6hlWnncUJjIxhw6LH3pOjs4M-us,1643
|
|
165
163
|
nextmv/cloud/application/_version.py,sha256=o1jVLfoKJNCs-32P7hkL1IGba8Eb1hnT6vnaZpyc0dk,8543
|
|
166
164
|
nextmv/default_app/.gitignore,sha256=gsfnfXMYNt-YTroh5hAzauwBZoPDJ6D_fB17rMSnIko,8
|
|
167
165
|
nextmv/default_app/README.md,sha256=hW3zWcYzxhYfof-pThaN1Fkx93GT8tTUVRhx15edBis,662
|
|
168
166
|
nextmv/default_app/app.yaml,sha256=TKjKnuoK0SDpouB_AS7TQmE_8HZbQYjmwFvhzFL1xpc,382
|
|
169
167
|
nextmv/default_app/input.json,sha256=zgvbKL3boB0WIU6-9mEU3ZWBddQ5cQ0vhgmDwDyz4hE,63
|
|
170
|
-
nextmv/default_app/main.py,sha256=
|
|
168
|
+
nextmv/default_app/main.py,sha256=j5L0itCyXKl3ezgkaS0cToLHzSl26Ah-PYr0gvxizxU,815
|
|
171
169
|
nextmv/default_app/requirements.txt,sha256=wRE_HkYYWzCGnYZ2NuatHXul4gCHvU3iUAdsxtzpYiA,29
|
|
172
170
|
nextmv/default_app/src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
173
171
|
nextmv/default_app/src/visuals.py,sha256=WYK_YBnLmYo3TpVev1CpoNCuW5R7hk9QIkeCmvMn1Fs,1014
|
|
174
172
|
nextmv/local/__init__.py,sha256=6BsoqlK4dw6X11_uKzz9gBPfxKpdiol2FYO8R3X73SE,116
|
|
175
173
|
nextmv/local/application.py,sha256=SBOARPnffAH6q-S0GGPEjt0gYIXmeR-38-VcZMfhqKk,47745
|
|
176
|
-
nextmv/local/executor.py,sha256=
|
|
177
|
-
nextmv/local/geojson_handler.py,sha256=
|
|
174
|
+
nextmv/local/executor.py,sha256=BxR7QWb4RekeFphJ4rOvJs8fYZGIQfgWlc75b8I7GRU,39310
|
|
175
|
+
nextmv/local/geojson_handler.py,sha256=CVlW5iof-8AODudEQ-a_o6WHqAeULfQS7-oJHf1-sAQ,12538
|
|
178
176
|
nextmv/local/local.py,sha256=cp56UpI8h19Ob6Jvb_Ni0ceXH5Vv3ET_iPTDe6ftq3Y,2617
|
|
179
177
|
nextmv/local/plotly_handler.py,sha256=bLb50e3AkVr_W-F6S7lXfeRdN60mG2jk3UElNmhoMWU,1930
|
|
180
178
|
nextmv/local/runner.py,sha256=bM1dFIAG4f9pEtbyevzkRa9nSppqTeD8naomNzJVBRU,8560
|
|
181
|
-
nextmv-1.0.0.
|
|
182
|
-
nextmv-1.0.0.
|
|
183
|
-
nextmv-1.0.0.
|
|
184
|
-
nextmv-1.0.0.
|
|
185
|
-
nextmv-1.0.0.
|
|
179
|
+
nextmv-1.0.0.dev8.dist-info/METADATA,sha256=f8DkOWUbGdeNNNBWcVrcHD7z0CAP9PgAWrDr6QOFK3Q,16484
|
|
180
|
+
nextmv-1.0.0.dev8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
181
|
+
nextmv-1.0.0.dev8.dist-info/entry_points.txt,sha256=bH7kXUt_IOLpeW_O7Z-J2gALs2YYJ4CmWuzS8MdK6uY,48
|
|
182
|
+
nextmv-1.0.0.dev8.dist-info/licenses/LICENSE,sha256=ZIbK-sSWA-OZprjNbmJAglYRtl5_K4l9UwAV3PGJAPc,11349
|
|
183
|
+
nextmv-1.0.0.dev8.dist-info/RECORD,,
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This module defines the cloud input-set delete command for the Nextmv CLI.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from typing import Annotated
|
|
6
|
-
|
|
7
|
-
import typer
|
|
8
|
-
|
|
9
|
-
from nextmv.cli.configuration.config import build_app
|
|
10
|
-
from nextmv.cli.confirm import get_confirmation
|
|
11
|
-
from nextmv.cli.message import info, success
|
|
12
|
-
from nextmv.cli.options import AppIDOption, InputSetIDOption, ProfileOption
|
|
13
|
-
|
|
14
|
-
# Set up subcommand application.
|
|
15
|
-
app = typer.Typer()
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@app.command()
|
|
19
|
-
def delete(
|
|
20
|
-
app_id: AppIDOption,
|
|
21
|
-
input_set_id: InputSetIDOption,
|
|
22
|
-
yes: Annotated[
|
|
23
|
-
bool,
|
|
24
|
-
typer.Option(
|
|
25
|
-
"--yes",
|
|
26
|
-
"-y",
|
|
27
|
-
help="Agree to deletion confirmation prompt. Useful for non-interactive sessions.",
|
|
28
|
-
),
|
|
29
|
-
] = False,
|
|
30
|
-
profile: ProfileOption = None,
|
|
31
|
-
) -> None:
|
|
32
|
-
"""
|
|
33
|
-
Deletes a Nextmv Cloud input set.
|
|
34
|
-
|
|
35
|
-
This action is permanent and cannot be undone. The input set and all
|
|
36
|
-
associated data will be deleted. Use the --yes flag to skip the
|
|
37
|
-
confirmation prompt.
|
|
38
|
-
|
|
39
|
-
[bold][underline]Examples[/underline][/bold]
|
|
40
|
-
|
|
41
|
-
- Delete the input set with the ID [magenta]hop-analysis[/magenta] from application
|
|
42
|
-
[magenta]hare-app[/magenta].
|
|
43
|
-
$ [dim]nextmv cloud input-set delete --app-id hare-app --input-set-id hop-analysis[/dim]
|
|
44
|
-
|
|
45
|
-
- Delete the input set without confirmation prompt.
|
|
46
|
-
$ [dim]nextmv cloud input-set delete --app-id hare-app --input-set-id carrot-routes --yes[/dim]
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
if not yes:
|
|
50
|
-
confirm = get_confirmation(
|
|
51
|
-
f"Are you sure you want to delete input set [magenta]{input_set_id}[/magenta] "
|
|
52
|
-
f"from application [magenta]{app_id}[/magenta]? This action cannot be undone.",
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
if not confirm:
|
|
56
|
-
info(
|
|
57
|
-
msg=f"Input set [magenta]{input_set_id}[/magenta] will not be deleted.",
|
|
58
|
-
emoji=":bulb:",
|
|
59
|
-
)
|
|
60
|
-
return
|
|
61
|
-
|
|
62
|
-
cloud_app = build_app(app_id=app_id, profile=profile)
|
|
63
|
-
cloud_app.delete_input_set(input_set_id=input_set_id)
|
|
64
|
-
success(
|
|
65
|
-
f"Input set [magenta]{input_set_id}[/magenta] deleted successfully "
|
|
66
|
-
f"from application [magenta]{app_id}[/magenta]."
|
|
67
|
-
)
|
nextmv/cloud/community.py
DELETED
|
@@ -1,441 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This module contains functionality for working with Nextmv community apps.
|
|
3
|
-
|
|
4
|
-
Community apps are pre-built decision models. They are maintained in the
|
|
5
|
-
following GitHub repository: https://github.com/nextmv-io/community-apps
|
|
6
|
-
|
|
7
|
-
Classes
|
|
8
|
-
-------
|
|
9
|
-
CommunityApp
|
|
10
|
-
Representation of a Nextmv Cloud Community App.
|
|
11
|
-
|
|
12
|
-
Functions
|
|
13
|
-
---------
|
|
14
|
-
list_community_apps
|
|
15
|
-
List the available Nextmv community apps.
|
|
16
|
-
clone_community_app
|
|
17
|
-
Clone a community app locally.
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
import os
|
|
21
|
-
import shutil
|
|
22
|
-
import sys
|
|
23
|
-
import tarfile
|
|
24
|
-
import tempfile
|
|
25
|
-
from collections.abc import Callable
|
|
26
|
-
from typing import Any
|
|
27
|
-
|
|
28
|
-
import requests
|
|
29
|
-
import rich
|
|
30
|
-
import yaml
|
|
31
|
-
from pydantic import AliasChoices, Field
|
|
32
|
-
|
|
33
|
-
from nextmv.base_model import BaseModel
|
|
34
|
-
from nextmv.cloud.client import Client
|
|
35
|
-
from nextmv.logger import log
|
|
36
|
-
|
|
37
|
-
# Helpful constants.
|
|
38
|
-
LATEST_VERSION = "latest"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class CommunityApp(BaseModel):
|
|
42
|
-
"""
|
|
43
|
-
Information about a Nextmv community app.
|
|
44
|
-
|
|
45
|
-
You can import the `CommunityApp` class directly from `cloud`:
|
|
46
|
-
|
|
47
|
-
```python
|
|
48
|
-
from nextmv.cloud import CommunityApp
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Parameters
|
|
52
|
-
----------
|
|
53
|
-
app_versions : list[str]
|
|
54
|
-
Available versions of the community app.
|
|
55
|
-
description : str
|
|
56
|
-
Description of the community app.
|
|
57
|
-
latest_app_version : str
|
|
58
|
-
The latest version of the community app.
|
|
59
|
-
latest_marketplace_version : str
|
|
60
|
-
The latest version of the community app in the Nextmv Marketplace.
|
|
61
|
-
marketplace_versions : list[str]
|
|
62
|
-
Available versions of the community app in the Nextmv Marketplace.
|
|
63
|
-
name : str
|
|
64
|
-
Name of the community app.
|
|
65
|
-
app_type : str
|
|
66
|
-
Type of the community app.
|
|
67
|
-
"""
|
|
68
|
-
|
|
69
|
-
description: str
|
|
70
|
-
"""Description of the community app."""
|
|
71
|
-
name: str
|
|
72
|
-
"""Name of the community app."""
|
|
73
|
-
app_type: str = Field(
|
|
74
|
-
serialization_alias="type",
|
|
75
|
-
validation_alias=AliasChoices("type", "app_type"),
|
|
76
|
-
)
|
|
77
|
-
"""Type of the community app."""
|
|
78
|
-
|
|
79
|
-
app_versions: list[str] | None = None
|
|
80
|
-
"""Available versions of the community app."""
|
|
81
|
-
latest_app_version: str | None = None
|
|
82
|
-
"""The latest version of the community app."""
|
|
83
|
-
latest_marketplace_version: str | None = None
|
|
84
|
-
"""The latest version of the community app in the Nextmv Marketplace."""
|
|
85
|
-
marketplace_versions: list[str] | None = None
|
|
86
|
-
"""Available versions of the community app in the Nextmv Marketplace."""
|
|
87
|
-
|
|
88
|
-
def has_version(self, version: str) -> bool:
|
|
89
|
-
"""
|
|
90
|
-
Check if the community app has the specified version.
|
|
91
|
-
|
|
92
|
-
Parameters
|
|
93
|
-
----------
|
|
94
|
-
version : str
|
|
95
|
-
The version to check.
|
|
96
|
-
|
|
97
|
-
Returns
|
|
98
|
-
-------
|
|
99
|
-
bool
|
|
100
|
-
True if the app has the specified version, False otherwise.
|
|
101
|
-
"""
|
|
102
|
-
|
|
103
|
-
if version == LATEST_VERSION:
|
|
104
|
-
version = self.latest_app_version
|
|
105
|
-
|
|
106
|
-
if self.app_versions is not None and version in self.app_versions:
|
|
107
|
-
return True
|
|
108
|
-
|
|
109
|
-
return False
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
def list_community_apps(client: Client) -> list[CommunityApp]:
|
|
113
|
-
"""
|
|
114
|
-
List the available Nextmv community apps.
|
|
115
|
-
|
|
116
|
-
You can import the `list_community_apps` function directly from `cloud`:
|
|
117
|
-
|
|
118
|
-
```python
|
|
119
|
-
from nextmv.cloud import list_community_apps
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Parameters
|
|
123
|
-
----------
|
|
124
|
-
manifest : dict[str, Any]
|
|
125
|
-
The community apps manifest.
|
|
126
|
-
|
|
127
|
-
Returns
|
|
128
|
-
-------
|
|
129
|
-
list[CommunityApp]
|
|
130
|
-
A list of available community apps.
|
|
131
|
-
"""
|
|
132
|
-
|
|
133
|
-
manifest = _download_manifest(client)
|
|
134
|
-
dict_apps = manifest.get("apps", [])
|
|
135
|
-
apps = [CommunityApp.from_dict(app) for app in dict_apps]
|
|
136
|
-
|
|
137
|
-
return apps
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
def clone_community_app(
|
|
141
|
-
client: Client,
|
|
142
|
-
app: str,
|
|
143
|
-
directory: str | None = None,
|
|
144
|
-
version: str | None = LATEST_VERSION,
|
|
145
|
-
verbose: bool = False,
|
|
146
|
-
rich_print: bool = False,
|
|
147
|
-
) -> None:
|
|
148
|
-
"""
|
|
149
|
-
Clone a community app locally.
|
|
150
|
-
|
|
151
|
-
By default, the `latest` version will be used. You can
|
|
152
|
-
specify a version with the `version` parameter, and customize the output
|
|
153
|
-
directory with the `directory` parameter. If you want to list the available
|
|
154
|
-
apps, use the `list_community_apps` function.
|
|
155
|
-
|
|
156
|
-
You can import the `clone_community_app` function directly from `cloud`:
|
|
157
|
-
|
|
158
|
-
```python
|
|
159
|
-
from nextmv.cloud import clone_community_app
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Parameters
|
|
163
|
-
----------
|
|
164
|
-
client : Client
|
|
165
|
-
The Nextmv Cloud client to use for the request.
|
|
166
|
-
app : str
|
|
167
|
-
The name of the community app to clone.
|
|
168
|
-
directory : str | None, optional
|
|
169
|
-
The directory in which to clone the app. Default is the name of the app at current directory.
|
|
170
|
-
version : str | None, optional
|
|
171
|
-
The version of the community app to clone. Default is `latest`.
|
|
172
|
-
verbose : bool, optional
|
|
173
|
-
Whether to print verbose output.
|
|
174
|
-
rich_print : bool, optional
|
|
175
|
-
Whether to use rich printing for output messages.
|
|
176
|
-
"""
|
|
177
|
-
comm_app = _find_app(client, app)
|
|
178
|
-
|
|
179
|
-
if version is not None and version == "":
|
|
180
|
-
raise ValueError("`version` cannot be an empty string.")
|
|
181
|
-
|
|
182
|
-
if not comm_app.has_version(version):
|
|
183
|
-
raise ValueError(f"Community app '{app}' does not have version '{version}'.")
|
|
184
|
-
|
|
185
|
-
original_version = version
|
|
186
|
-
if version == LATEST_VERSION:
|
|
187
|
-
version = comm_app.latest_app_version
|
|
188
|
-
|
|
189
|
-
# Clean and normalize directory path in an OS-independent way
|
|
190
|
-
if directory is not None and directory != "":
|
|
191
|
-
destination = os.path.normpath(directory)
|
|
192
|
-
else:
|
|
193
|
-
destination = app
|
|
194
|
-
|
|
195
|
-
full_destination = _get_valid_path(destination, os.stat)
|
|
196
|
-
os.makedirs(full_destination, exist_ok=True)
|
|
197
|
-
|
|
198
|
-
tarball = f"{app}_{version}.tar.gz"
|
|
199
|
-
s3_file_path = f"{app}/{version}/{tarball}"
|
|
200
|
-
downloaded_object = _download_object(
|
|
201
|
-
client=client,
|
|
202
|
-
file=s3_file_path,
|
|
203
|
-
path="community-apps",
|
|
204
|
-
output_dir=full_destination,
|
|
205
|
-
output_file=tarball,
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
# Extract the tarball to a temporary directory to handle nested structure
|
|
209
|
-
with tempfile.TemporaryDirectory() as temp_dir:
|
|
210
|
-
with tarfile.open(downloaded_object, "r:gz") as tar:
|
|
211
|
-
tar.extractall(path=temp_dir)
|
|
212
|
-
|
|
213
|
-
# Find the extracted directory (typically the app name)
|
|
214
|
-
extracted_items = os.listdir(temp_dir)
|
|
215
|
-
if len(extracted_items) == 1 and os.path.isdir(os.path.join(temp_dir, extracted_items[0])):
|
|
216
|
-
# Move contents from the extracted directory to full_destination
|
|
217
|
-
extracted_dir = os.path.join(temp_dir, extracted_items[0])
|
|
218
|
-
for item in os.listdir(extracted_dir):
|
|
219
|
-
shutil.move(os.path.join(extracted_dir, item), full_destination)
|
|
220
|
-
else:
|
|
221
|
-
# If structure is unexpected, move everything directly
|
|
222
|
-
for item in extracted_items:
|
|
223
|
-
shutil.move(os.path.join(temp_dir, item), full_destination)
|
|
224
|
-
|
|
225
|
-
# Remove the tarball after extraction
|
|
226
|
-
os.remove(downloaded_object)
|
|
227
|
-
|
|
228
|
-
if not verbose:
|
|
229
|
-
return
|
|
230
|
-
|
|
231
|
-
if rich_print:
|
|
232
|
-
rich.print(
|
|
233
|
-
f":white_check_mark: Successfully cloned the [magenta]{app}[/magenta] community app, "
|
|
234
|
-
f"using version [magenta]{original_version}[/magenta] in path: [magenta]{full_destination}[/magenta].",
|
|
235
|
-
file=sys.stderr,
|
|
236
|
-
)
|
|
237
|
-
return
|
|
238
|
-
|
|
239
|
-
log(
|
|
240
|
-
f"✅ Successfully cloned the {app} community app, using version {original_version} in path: {full_destination}."
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
def _download_manifest(client: Client) -> dict[str, Any]:
|
|
245
|
-
"""
|
|
246
|
-
Downloads and returns the community apps manifest.
|
|
247
|
-
|
|
248
|
-
Parameters
|
|
249
|
-
----------
|
|
250
|
-
client : Client
|
|
251
|
-
The Nextmv Cloud client to use for the request.
|
|
252
|
-
|
|
253
|
-
Returns
|
|
254
|
-
-------
|
|
255
|
-
dict[str, Any]
|
|
256
|
-
The community apps manifest as a dictionary.
|
|
257
|
-
|
|
258
|
-
Raises
|
|
259
|
-
requests.HTTPError
|
|
260
|
-
If the response status code is not 2xx.
|
|
261
|
-
"""
|
|
262
|
-
|
|
263
|
-
response = _download_file(client=client, directory="community-apps", file="manifest.yml")
|
|
264
|
-
manifest = yaml.safe_load(response.text)
|
|
265
|
-
|
|
266
|
-
return manifest
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
def _download_file(
|
|
270
|
-
client: Client,
|
|
271
|
-
directory: str,
|
|
272
|
-
file: str,
|
|
273
|
-
) -> requests.Response:
|
|
274
|
-
"""
|
|
275
|
-
Gets a file from an internal bucket and return it.
|
|
276
|
-
|
|
277
|
-
Parameters
|
|
278
|
-
----------
|
|
279
|
-
client : Client
|
|
280
|
-
The Nextmv Cloud client to use for the request.
|
|
281
|
-
directory : str
|
|
282
|
-
The directory in the bucket where the file is located.
|
|
283
|
-
file : str
|
|
284
|
-
The name of the file to download.
|
|
285
|
-
|
|
286
|
-
Returns
|
|
287
|
-
-------
|
|
288
|
-
requests.Response
|
|
289
|
-
The response object containing the file data.
|
|
290
|
-
|
|
291
|
-
Raises
|
|
292
|
-
requests.HTTPError
|
|
293
|
-
If the response status code is not 2xx.
|
|
294
|
-
"""
|
|
295
|
-
|
|
296
|
-
# Request the download URL for the file.
|
|
297
|
-
response = client.request(
|
|
298
|
-
method="GET",
|
|
299
|
-
endpoint="v0/internal/tools",
|
|
300
|
-
headers=client.headers | {"request-source": "cli"}, # Pass `client.headers` to preserve auth.
|
|
301
|
-
query_params={"file": f"{directory}/{file}"},
|
|
302
|
-
)
|
|
303
|
-
|
|
304
|
-
# Use the URL obtained to download the file.
|
|
305
|
-
body = response.json()
|
|
306
|
-
download_response = client.request(
|
|
307
|
-
method="GET",
|
|
308
|
-
endpoint=body.get("url"),
|
|
309
|
-
headers={"Content-Type": "application/json"},
|
|
310
|
-
)
|
|
311
|
-
|
|
312
|
-
return download_response
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
def _download_object(client: Client, file: str, path: str, output_dir: str, output_file: str) -> str:
|
|
316
|
-
"""
|
|
317
|
-
Downloads an object from the internal bucket and saves it to the specified
|
|
318
|
-
output directory.
|
|
319
|
-
|
|
320
|
-
Parameters
|
|
321
|
-
----------
|
|
322
|
-
client : Client
|
|
323
|
-
The Nextmv Cloud client to use for the request.
|
|
324
|
-
file : str
|
|
325
|
-
The name of the file to download.
|
|
326
|
-
path : str
|
|
327
|
-
The directory in the bucket where the file is located.
|
|
328
|
-
output_dir : str
|
|
329
|
-
The local directory where the file will be saved.
|
|
330
|
-
output_file : str
|
|
331
|
-
The name of the output file.
|
|
332
|
-
|
|
333
|
-
Returns
|
|
334
|
-
-------
|
|
335
|
-
str
|
|
336
|
-
The path to the downloaded file.
|
|
337
|
-
"""
|
|
338
|
-
|
|
339
|
-
response = _download_file(client=client, directory=path, file=file)
|
|
340
|
-
file_name = os.path.join(output_dir, output_file)
|
|
341
|
-
|
|
342
|
-
with open(file_name, "wb") as f:
|
|
343
|
-
f.write(response.content)
|
|
344
|
-
|
|
345
|
-
return file_name
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
def _get_valid_path(path: str, stat_fn: Callable[[str], os.stat_result], ending: str = "") -> str:
|
|
349
|
-
"""
|
|
350
|
-
Validates and returns a non-existing path. If the path exists,
|
|
351
|
-
it will append a number to the path and return it. If the path does not
|
|
352
|
-
exist, it will return the path as is.
|
|
353
|
-
|
|
354
|
-
The ending parameter is used to check if the path ends with a specific
|
|
355
|
-
string. This is useful to specify if it is a file (like foo.json, in which
|
|
356
|
-
case the next iteration is foo-1.json) or a directory (like foo, in which
|
|
357
|
-
case the next iteration is foo-1).
|
|
358
|
-
|
|
359
|
-
Parameters
|
|
360
|
-
----------
|
|
361
|
-
path : str
|
|
362
|
-
The initial path to validate.
|
|
363
|
-
stat_fn : Callable[[str], os.stat_result]
|
|
364
|
-
A function that takes a path and returns its stat result.
|
|
365
|
-
ending : str, optional
|
|
366
|
-
The expected ending of the path (e.g., file extension), by default "".
|
|
367
|
-
|
|
368
|
-
Returns
|
|
369
|
-
-------
|
|
370
|
-
str
|
|
371
|
-
A valid, non-existing path.
|
|
372
|
-
|
|
373
|
-
Raises
|
|
374
|
-
------
|
|
375
|
-
Exception
|
|
376
|
-
If an unexpected error occurs during path validation
|
|
377
|
-
"""
|
|
378
|
-
base_name = os.path.basename(path)
|
|
379
|
-
name_without_ending = base_name.removesuffix(ending) if ending else base_name
|
|
380
|
-
|
|
381
|
-
while True:
|
|
382
|
-
try:
|
|
383
|
-
stat_fn(path)
|
|
384
|
-
# If we get here, the path exists
|
|
385
|
-
# Get folder/file name number, increase it and create new path
|
|
386
|
-
name = os.path.basename(path)
|
|
387
|
-
|
|
388
|
-
# Get folder/file name number
|
|
389
|
-
parts = name.split("-")
|
|
390
|
-
last = parts[-1].removesuffix(ending) if ending else parts[-1]
|
|
391
|
-
|
|
392
|
-
# Save last folder name index to be changed
|
|
393
|
-
i = path.rfind(name)
|
|
394
|
-
|
|
395
|
-
try:
|
|
396
|
-
num = int(last)
|
|
397
|
-
# Increase number and create new path
|
|
398
|
-
if ending:
|
|
399
|
-
temp_path = path[:i] + f"{name_without_ending}-{num + 1}{ending}"
|
|
400
|
-
else:
|
|
401
|
-
temp_path = path[:i] + f"{base_name}-{num + 1}"
|
|
402
|
-
path = temp_path
|
|
403
|
-
except ValueError:
|
|
404
|
-
# If there is no number, add it
|
|
405
|
-
if ending:
|
|
406
|
-
temp_path = path[:i] + f"{name_without_ending}-1{ending}"
|
|
407
|
-
else:
|
|
408
|
-
temp_path = path[:i] + f"{name}-1"
|
|
409
|
-
path = temp_path
|
|
410
|
-
|
|
411
|
-
except FileNotFoundError:
|
|
412
|
-
# Path doesn't exist, we can use it
|
|
413
|
-
return path
|
|
414
|
-
except Exception as e:
|
|
415
|
-
# Re-raise unexpected errors
|
|
416
|
-
raise RuntimeError(f"An unexpected error occurred while validating the path: {path} ") from e
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
def _find_app(client: Client, app: str) -> CommunityApp | None:
|
|
420
|
-
"""
|
|
421
|
-
Finds and returns a community app from the manifest by its name.
|
|
422
|
-
|
|
423
|
-
Parameters
|
|
424
|
-
----------
|
|
425
|
-
client : Client
|
|
426
|
-
The Nextmv Cloud client to use for the request.
|
|
427
|
-
app : str
|
|
428
|
-
The name of the community app to find.
|
|
429
|
-
|
|
430
|
-
Returns
|
|
431
|
-
-------
|
|
432
|
-
CommunityApp | None
|
|
433
|
-
The community app if found, otherwise None.
|
|
434
|
-
"""
|
|
435
|
-
|
|
436
|
-
comm_apps = list_community_apps(client)
|
|
437
|
-
for comm_app in comm_apps:
|
|
438
|
-
if comm_app.name == app:
|
|
439
|
-
return comm_app
|
|
440
|
-
|
|
441
|
-
raise ValueError(f"Community app '{app}' not found.")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|