nextmv 0.27.0__py3-none-any.whl → 0.28.0__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/__init__.py +1 -0
- nextmv/base_model.py +52 -7
- nextmv/cloud/__init__.py +3 -0
- nextmv/cloud/acceptance_test.py +711 -20
- nextmv/cloud/account.py +152 -7
- nextmv/cloud/application.py +1213 -382
- nextmv/cloud/batch_experiment.py +133 -21
- nextmv/cloud/client.py +240 -46
- nextmv/cloud/input_set.py +96 -3
- nextmv/cloud/instance.py +89 -3
- nextmv/cloud/manifest.py +507 -131
- nextmv/cloud/package.py +2 -2
- nextmv/cloud/run.py +372 -41
- nextmv/cloud/safe.py +7 -7
- nextmv/cloud/scenario.py +205 -20
- nextmv/cloud/secrets.py +179 -6
- nextmv/cloud/status.py +95 -2
- nextmv/cloud/version.py +132 -4
- nextmv/deprecated.py +36 -2
- nextmv/input.py +298 -80
- nextmv/logger.py +71 -7
- nextmv/model.py +223 -56
- nextmv/options.py +281 -66
- nextmv/output.py +552 -159
- {nextmv-0.27.0.dist-info → nextmv-0.28.0.dist-info}/METADATA +1 -1
- nextmv-0.28.0.dist-info/RECORD +30 -0
- nextmv-0.27.0.dist-info/RECORD +0 -30
- {nextmv-0.27.0.dist-info → nextmv-0.28.0.dist-info}/WHEEL +0 -0
- {nextmv-0.27.0.dist-info → nextmv-0.28.0.dist-info}/licenses/LICENSE +0 -0
nextmv/input.py
CHANGED
|
@@ -1,4 +1,26 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Module for handling input sources and data.
|
|
3
|
+
|
|
4
|
+
This module provides classes and functions for loading and handling input data
|
|
5
|
+
in various formats for decision problems. It supports JSON, plain text, CSV,
|
|
6
|
+
and CSV archive formats and can load data from standard input or files.
|
|
7
|
+
|
|
8
|
+
Classes
|
|
9
|
+
-------
|
|
10
|
+
InputFormat
|
|
11
|
+
Enum defining supported input data formats (JSON, TEXT, CSV, CSV_ARCHIVE).
|
|
12
|
+
Input
|
|
13
|
+
Container for input data with format specification and options.
|
|
14
|
+
InputLoader
|
|
15
|
+
Base class for loading inputs from various sources.
|
|
16
|
+
LocalInputLoader
|
|
17
|
+
Class for loading inputs from local files or stdin.
|
|
18
|
+
|
|
19
|
+
Functions
|
|
20
|
+
---------
|
|
21
|
+
load
|
|
22
|
+
Load input data using a specified loader.
|
|
23
|
+
"""
|
|
2
24
|
|
|
3
25
|
import copy
|
|
4
26
|
import csv
|
|
@@ -14,7 +36,28 @@ from nextmv.options import Options
|
|
|
14
36
|
|
|
15
37
|
|
|
16
38
|
class InputFormat(str, Enum):
|
|
17
|
-
"""
|
|
39
|
+
"""
|
|
40
|
+
Format of an `Input`.
|
|
41
|
+
|
|
42
|
+
You can import the `InputFormat` class directly from `nextmv`:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from nextmv import InputFormat
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This enum specifies the supported formats for input data.
|
|
49
|
+
|
|
50
|
+
Attributes
|
|
51
|
+
----------
|
|
52
|
+
JSON : str
|
|
53
|
+
JSON format, utf-8 encoded.
|
|
54
|
+
TEXT : str
|
|
55
|
+
Text format, utf-8 encoded.
|
|
56
|
+
CSV : str
|
|
57
|
+
CSV format, utf-8 encoded.
|
|
58
|
+
CSV_ARCHIVE : str
|
|
59
|
+
CSV archive format: multiple CSV files.
|
|
60
|
+
"""
|
|
18
61
|
|
|
19
62
|
JSON = "json"
|
|
20
63
|
"""JSON format, utf-8 encoded."""
|
|
@@ -31,9 +74,15 @@ class Input:
|
|
|
31
74
|
"""
|
|
32
75
|
Input for a decision problem.
|
|
33
76
|
|
|
77
|
+
You can import the `Input` class directly from `nextmv`:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from nextmv import Input
|
|
81
|
+
```
|
|
82
|
+
|
|
34
83
|
Parameters
|
|
35
84
|
----------
|
|
36
|
-
data : Any
|
|
85
|
+
data : Union[dict[str, Any], str, list[dict[str, Any]], dict[str, list[dict[str, Any]]]]
|
|
37
86
|
The actual data.
|
|
38
87
|
input_format : InputFormat, optional
|
|
39
88
|
Format of the input data. Default is `InputFormat.JSON`.
|
|
@@ -47,17 +96,46 @@ class Input:
|
|
|
47
96
|
list[dict[str, Any]], # CSV
|
|
48
97
|
dict[str, list[dict[str, Any]]], # CSV_ARCHIVE
|
|
49
98
|
]
|
|
50
|
-
"""
|
|
51
|
-
|
|
99
|
+
"""
|
|
100
|
+
The actual data.
|
|
101
|
+
|
|
102
|
+
The data can be of various types, depending on the input format:
|
|
103
|
+
|
|
104
|
+
- For `JSON`: `Union[dict[str, Any], Any]`
|
|
105
|
+
- For `TEXT`: `str`
|
|
106
|
+
- For `CSV`: `list[dict[str, Any]]`
|
|
107
|
+
- For `CSV_ARCHIVE`: `dict[str, list[dict[str, Any]]]`
|
|
108
|
+
"""
|
|
52
109
|
|
|
53
110
|
input_format: Optional[InputFormat] = InputFormat.JSON
|
|
54
|
-
"""
|
|
111
|
+
"""
|
|
112
|
+
Format of the input data.
|
|
113
|
+
|
|
114
|
+
Default is `InputFormat.JSON`.
|
|
115
|
+
"""
|
|
116
|
+
|
|
55
117
|
options: Optional[Options] = None
|
|
56
|
-
"""
|
|
118
|
+
"""
|
|
119
|
+
Options that the `Input` was created with.
|
|
120
|
+
|
|
121
|
+
A copy of the options is made during initialization, ensuring the original
|
|
122
|
+
options remain unchanged even if modified later.
|
|
123
|
+
"""
|
|
57
124
|
|
|
58
125
|
def __post_init__(self):
|
|
59
|
-
"""
|
|
60
|
-
class.
|
|
126
|
+
"""
|
|
127
|
+
Check that the data matches the format given to initialize the class.
|
|
128
|
+
|
|
129
|
+
This method is automatically called after the dataclass is initialized.
|
|
130
|
+
It validates that the data provided is of the correct type according to
|
|
131
|
+
the specified input_format and makes a deep copy of the options to ensure
|
|
132
|
+
the input maintains its own copy.
|
|
133
|
+
|
|
134
|
+
Raises
|
|
135
|
+
------
|
|
136
|
+
ValueError
|
|
137
|
+
If the data type doesn't match the expected type for the given format.
|
|
138
|
+
"""
|
|
61
139
|
|
|
62
140
|
if self.input_format == InputFormat.JSON:
|
|
63
141
|
try:
|
|
@@ -96,14 +174,30 @@ class Input:
|
|
|
96
174
|
"""
|
|
97
175
|
Convert the input to a dictionary.
|
|
98
176
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
None
|
|
177
|
+
This method serializes the Input object to a dictionary format that can be
|
|
178
|
+
easily converted to JSON or other serialization formats.
|
|
102
179
|
|
|
103
180
|
Returns
|
|
104
181
|
-------
|
|
105
182
|
dict[str, Any]
|
|
106
|
-
|
|
183
|
+
A dictionary containing the input data, format, and options.
|
|
184
|
+
|
|
185
|
+
The structure is:
|
|
186
|
+
```python
|
|
187
|
+
{
|
|
188
|
+
"data": <the input data>,
|
|
189
|
+
"input_format": <the input format as a string>,
|
|
190
|
+
"options": <the options as a dictionary or None>
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Examples
|
|
195
|
+
--------
|
|
196
|
+
>>> from nextmv.input import Input, InputFormat
|
|
197
|
+
>>> input_obj = Input(data={"key": "value"}, input_format=InputFormat.JSON)
|
|
198
|
+
>>> input_dict = input_obj.to_dict()
|
|
199
|
+
>>> print(input_dict)
|
|
200
|
+
{'data': {'key': 'value'}, 'input_format': 'json', 'options': None}
|
|
107
201
|
"""
|
|
108
202
|
|
|
109
203
|
return {
|
|
@@ -114,7 +208,18 @@ class Input:
|
|
|
114
208
|
|
|
115
209
|
|
|
116
210
|
class InputLoader:
|
|
117
|
-
"""
|
|
211
|
+
"""
|
|
212
|
+
Base class for loading inputs.
|
|
213
|
+
|
|
214
|
+
You can import the `InputLoader` class directly from `nextmv`:
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
from nextmv import InputLoader
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
This abstract class defines the interface for input loaders. Subclasses must
|
|
221
|
+
implement the `load` method to provide concrete input loading functionality.
|
|
222
|
+
"""
|
|
118
223
|
|
|
119
224
|
def load(
|
|
120
225
|
self,
|
|
@@ -154,20 +259,84 @@ class InputLoader:
|
|
|
154
259
|
|
|
155
260
|
class LocalInputLoader(InputLoader):
|
|
156
261
|
"""
|
|
157
|
-
Class for loading local inputs.
|
|
158
|
-
|
|
262
|
+
Class for loading local inputs.
|
|
263
|
+
|
|
264
|
+
You can import the `LocalInputLoader` class directly from `nextmv`:
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
from nextmv import LocalInputLoader
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
This class can load input data from the local filesystem, by using stdin,
|
|
271
|
+
a file, or a directory, where applicable. It supports various input formats
|
|
272
|
+
like JSON, TEXT, CSV, and CSV archive.
|
|
273
|
+
|
|
159
274
|
Call the `load` method to read the input data.
|
|
275
|
+
|
|
276
|
+
Examples
|
|
277
|
+
--------
|
|
278
|
+
>>> from nextmv.input import LocalInputLoader, InputFormat
|
|
279
|
+
>>> loader = LocalInputLoader()
|
|
280
|
+
>>> # Load JSON from stdin or file
|
|
281
|
+
>>> input_obj = loader.load(input_format=InputFormat.JSON, path="data.json")
|
|
282
|
+
>>> # Load CSV from a file
|
|
283
|
+
>>> input_obj = loader.load(input_format=InputFormat.CSV, path="data.csv")
|
|
160
284
|
"""
|
|
161
285
|
|
|
162
286
|
def _read_text(path: str, _) -> str:
|
|
287
|
+
"""
|
|
288
|
+
Read a text file and return its contents.
|
|
289
|
+
|
|
290
|
+
Parameters
|
|
291
|
+
----------
|
|
292
|
+
path : str
|
|
293
|
+
Path to the text file.
|
|
294
|
+
_ : Any
|
|
295
|
+
Placeholder for unused parameter (for API consistency).
|
|
296
|
+
|
|
297
|
+
Returns
|
|
298
|
+
-------
|
|
299
|
+
str
|
|
300
|
+
Contents of the text file with trailing newlines removed.
|
|
301
|
+
"""
|
|
163
302
|
with open(path, encoding="utf-8") as f:
|
|
164
303
|
return f.read().rstrip("\n")
|
|
165
304
|
|
|
166
305
|
def _read_csv(path: str, csv_configurations: Optional[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
306
|
+
"""
|
|
307
|
+
Read a CSV file and return its contents as a list of dictionaries.
|
|
308
|
+
|
|
309
|
+
Parameters
|
|
310
|
+
----------
|
|
311
|
+
path : str
|
|
312
|
+
Path to the CSV file.
|
|
313
|
+
csv_configurations : dict[str, Any], optional
|
|
314
|
+
Configuration parameters for the CSV DictReader.
|
|
315
|
+
|
|
316
|
+
Returns
|
|
317
|
+
-------
|
|
318
|
+
list[dict[str, Any]]
|
|
319
|
+
List of dictionaries where each dictionary represents a row in the CSV.
|
|
320
|
+
"""
|
|
167
321
|
with open(path, encoding="utf-8") as f:
|
|
168
322
|
return list(csv.DictReader(f, **csv_configurations))
|
|
169
323
|
|
|
170
324
|
def _read_json(path: str, _) -> Union[dict[str, Any], Any]:
|
|
325
|
+
"""
|
|
326
|
+
Read a JSON file and return its parsed contents.
|
|
327
|
+
|
|
328
|
+
Parameters
|
|
329
|
+
----------
|
|
330
|
+
path : str
|
|
331
|
+
Path to the JSON file.
|
|
332
|
+
_ : Any
|
|
333
|
+
Placeholder for unused parameter (for API consistency).
|
|
334
|
+
|
|
335
|
+
Returns
|
|
336
|
+
-------
|
|
337
|
+
Union[dict[str, Any], Any]
|
|
338
|
+
Parsed JSON data.
|
|
339
|
+
"""
|
|
171
340
|
with open(path, encoding="utf-8") as f:
|
|
172
341
|
return json.load(f)
|
|
173
342
|
|
|
@@ -177,6 +346,13 @@ class LocalInputLoader(InputLoader):
|
|
|
177
346
|
InputFormat.TEXT: lambda _: sys.stdin.read().rstrip("\n"),
|
|
178
347
|
InputFormat.CSV: lambda csv_configurations: list(csv.DictReader(sys.stdin, **csv_configurations)),
|
|
179
348
|
}
|
|
349
|
+
"""
|
|
350
|
+
Dictionary of functions to read from standard input.
|
|
351
|
+
|
|
352
|
+
Each key is an InputFormat, and each value is a function that reads from
|
|
353
|
+
standard input in that format.
|
|
354
|
+
"""
|
|
355
|
+
|
|
180
356
|
# These callbacks were not implemented with lambda because we needed
|
|
181
357
|
# multiple lines. By using `open`, we needed the `with` to be able to close
|
|
182
358
|
# the file.
|
|
@@ -185,6 +361,12 @@ class LocalInputLoader(InputLoader):
|
|
|
185
361
|
InputFormat.TEXT: _read_text,
|
|
186
362
|
InputFormat.CSV: _read_csv,
|
|
187
363
|
}
|
|
364
|
+
"""
|
|
365
|
+
Dictionary of functions to read from files.
|
|
366
|
+
|
|
367
|
+
Each key is an InputFormat, and each value is a function that reads from
|
|
368
|
+
a file in that format.
|
|
369
|
+
"""
|
|
188
370
|
|
|
189
371
|
def load(
|
|
190
372
|
self,
|
|
@@ -256,8 +438,27 @@ class LocalInputLoader(InputLoader):
|
|
|
256
438
|
use_file_reader: bool = False,
|
|
257
439
|
) -> Union[dict[str, Any], str, list[dict[str, Any]]]:
|
|
258
440
|
"""
|
|
259
|
-
Load a utf-8 encoded file
|
|
260
|
-
|
|
441
|
+
Load a utf-8 encoded file from stdin or filesystem.
|
|
442
|
+
|
|
443
|
+
This internal method handles loading data in various formats from either
|
|
444
|
+
standard input or a file.
|
|
445
|
+
|
|
446
|
+
Parameters
|
|
447
|
+
----------
|
|
448
|
+
csv_configurations : dict[str, Any], optional
|
|
449
|
+
Configuration parameters for the CSV DictReader.
|
|
450
|
+
path : str, optional
|
|
451
|
+
Path to the file to read from. If None or empty, reads from stdin.
|
|
452
|
+
input_format : InputFormat, optional
|
|
453
|
+
Format of the input data. Default is JSON.
|
|
454
|
+
use_file_reader : bool, optional
|
|
455
|
+
Whether to force using the file reader even if path is None.
|
|
456
|
+
Default is False.
|
|
457
|
+
|
|
458
|
+
Returns
|
|
459
|
+
-------
|
|
460
|
+
Union[dict[str, Any], str, list[dict[str, Any]]]
|
|
461
|
+
Data read from stdin or file in the specified format.
|
|
261
462
|
"""
|
|
262
463
|
|
|
263
464
|
# If we forcibly want to use the file reader, we can do so.
|
|
@@ -277,7 +478,29 @@ class LocalInputLoader(InputLoader):
|
|
|
277
478
|
path: Optional[str] = None,
|
|
278
479
|
) -> dict[str, list[dict[str, Any]]]:
|
|
279
480
|
"""
|
|
280
|
-
Load files from a directory.
|
|
481
|
+
Load CSV files from a directory.
|
|
482
|
+
|
|
483
|
+
This internal method loads all CSV files from a specified directory,
|
|
484
|
+
organizing them into a dictionary where each key is the filename
|
|
485
|
+
(without .csv extension) and each value is the parsed CSV content.
|
|
486
|
+
|
|
487
|
+
Parameters
|
|
488
|
+
----------
|
|
489
|
+
csv_configurations : dict[str, Any], optional
|
|
490
|
+
Configuration parameters for the CSV DictReader.
|
|
491
|
+
path : str, optional
|
|
492
|
+
Path to the directory containing CSV files. If None or empty,
|
|
493
|
+
uses "./input" as the default directory.
|
|
494
|
+
|
|
495
|
+
Returns
|
|
496
|
+
-------
|
|
497
|
+
dict[str, list[dict[str, Any]]]
|
|
498
|
+
Dictionary mapping filenames to CSV contents.
|
|
499
|
+
|
|
500
|
+
Raises
|
|
501
|
+
------
|
|
502
|
+
ValueError
|
|
503
|
+
If the path is not a directory or the default directory doesn't exist.
|
|
281
504
|
"""
|
|
282
505
|
|
|
283
506
|
dir_path = "input"
|
|
@@ -312,32 +535,14 @@ def load_local(
|
|
|
312
535
|
csv_configurations: Optional[dict[str, Any]] = None,
|
|
313
536
|
) -> Input:
|
|
314
537
|
"""
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
538
|
+
!!! warning
|
|
539
|
+
`load_local` is deprecated, use `load` instead.
|
|
540
|
+
|
|
541
|
+
Load input data from local sources.
|
|
318
542
|
|
|
319
543
|
This is a convenience function for instantiating a `LocalInputLoader`
|
|
320
544
|
and calling its `load` method.
|
|
321
545
|
|
|
322
|
-
Load the input data. The input data can be in various formats. For
|
|
323
|
-
`InputFormat.JSON`, `InputFormat.TEXT`, and `InputFormat.CSV`, the data can
|
|
324
|
-
be streamed from stdin or read from a file. When the `path` argument is
|
|
325
|
-
provided (and valid), the input data is read from the file specified by
|
|
326
|
-
`path`, otherwise, it is streamed from stdin. For
|
|
327
|
-
`InputFormat.CSV_ARCHIVE`, the input data is read from the directory
|
|
328
|
-
specified by `path`. If the `path` is not provided, the default location
|
|
329
|
-
`input` is used. The directory should contain one or more files, where each
|
|
330
|
-
file in the directory is a CSV file.
|
|
331
|
-
|
|
332
|
-
The `Input` that is returned contains the `data` attribute. This data can
|
|
333
|
-
be of different types, depending on the provided `input_format`:
|
|
334
|
-
|
|
335
|
-
- `InputFormat.JSON`: the data is a `dict[str, Any]`.
|
|
336
|
-
- `InputFormat.TEXT`: the data is a `str`.
|
|
337
|
-
- `InputFormat.CSV`: the data is a `list[dict[str, Any]]`.
|
|
338
|
-
- `InputFormat.CSV_ARCHIVE`: the data is a `dict[str, list[dict[str, Any]]]`.
|
|
339
|
-
Each key is the name of the CSV file, minus the `.csv` extension.
|
|
340
|
-
|
|
341
546
|
Parameters
|
|
342
547
|
----------
|
|
343
548
|
input_format : InputFormat, optional
|
|
@@ -347,19 +552,22 @@ def load_local(
|
|
|
347
552
|
path : str, optional
|
|
348
553
|
Path to the input data.
|
|
349
554
|
csv_configurations : dict[str, Any], optional
|
|
350
|
-
Configurations for loading CSV files.
|
|
351
|
-
|
|
352
|
-
with custom kwargs for the `DictReader`.
|
|
555
|
+
Configurations for loading CSV files. Custom kwargs for
|
|
556
|
+
Python's `csv.DictReader`.
|
|
353
557
|
|
|
354
558
|
Returns
|
|
355
559
|
-------
|
|
356
560
|
Input
|
|
357
|
-
The input data.
|
|
561
|
+
The loaded input data in an Input object.
|
|
358
562
|
|
|
359
563
|
Raises
|
|
360
564
|
------
|
|
361
565
|
ValueError
|
|
362
|
-
If the path is
|
|
566
|
+
If the path is invalid or data format is incorrect.
|
|
567
|
+
|
|
568
|
+
See Also
|
|
569
|
+
--------
|
|
570
|
+
load : The recommended function to use instead.
|
|
363
571
|
"""
|
|
364
572
|
|
|
365
573
|
deprecated(
|
|
@@ -372,6 +580,7 @@ def load_local(
|
|
|
372
580
|
|
|
373
581
|
|
|
374
582
|
_LOCAL_INPUT_LOADER = LocalInputLoader()
|
|
583
|
+
"""Default instance of LocalInputLoader used by the load function."""
|
|
375
584
|
|
|
376
585
|
|
|
377
586
|
def load(
|
|
@@ -382,54 +591,63 @@ def load(
|
|
|
382
591
|
loader: Optional[InputLoader] = _LOCAL_INPUT_LOADER,
|
|
383
592
|
) -> Input:
|
|
384
593
|
"""
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
- `InputFormat.
|
|
403
|
-
- `InputFormat.TEXT`: the data is a `str`.
|
|
404
|
-
- `InputFormat.CSV`: the data is a `list[dict[str, Any]]`.
|
|
405
|
-
- `InputFormat.CSV_ARCHIVE`: the data is a `dict[str, list[dict[str, Any]]]`.
|
|
594
|
+
Load input data using the specified loader.
|
|
595
|
+
|
|
596
|
+
You can import the `load` function directly from `nextmv`:
|
|
597
|
+
|
|
598
|
+
```python
|
|
599
|
+
from nextmv import load
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
This is a convenience function for loading an `Input` object. By default,
|
|
603
|
+
it uses the `LocalInputLoader` to load data from local sources.
|
|
604
|
+
|
|
605
|
+
The input data can be in various formats and can be loaded from different
|
|
606
|
+
sources depending on the loader:
|
|
607
|
+
|
|
608
|
+
- `InputFormat.JSON`: the data is a `dict[str, Any]`
|
|
609
|
+
- `InputFormat.TEXT`: the data is a `str`
|
|
610
|
+
- `InputFormat.CSV`: the data is a `list[dict[str, Any]]`
|
|
611
|
+
- `InputFormat.CSV_ARCHIVE`: the data is a `dict[str, list[dict[str, Any]]]`
|
|
406
612
|
Each key is the name of the CSV file, minus the `.csv` extension.
|
|
407
613
|
|
|
408
614
|
Parameters
|
|
409
615
|
----------
|
|
410
|
-
input_format: InputFormat, optional
|
|
616
|
+
input_format : InputFormat, optional
|
|
411
617
|
Format of the input data. Default is `InputFormat.JSON`.
|
|
412
|
-
options: Options, optional
|
|
618
|
+
options : Options, optional
|
|
413
619
|
Options for loading the input data.
|
|
414
|
-
path: str, optional
|
|
415
|
-
Path to the input data.
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
620
|
+
path : str, optional
|
|
621
|
+
Path to the input data. For file-based loaders:
|
|
622
|
+
- If provided, reads from the specified file or directory
|
|
623
|
+
- If None, typically reads from stdin (for JSON, TEXT, CSV)
|
|
624
|
+
or uses a default directory (for CSV_ARCHIVE)
|
|
625
|
+
csv_configurations : dict[str, Any], optional
|
|
626
|
+
Configurations for loading CSV files. Custom kwargs for
|
|
627
|
+
Python's `csv.DictReader`.
|
|
628
|
+
loader : InputLoader, optional
|
|
629
|
+
The loader to use for loading the input data.
|
|
630
|
+
Default is an instance of `LocalInputLoader`.
|
|
423
631
|
|
|
424
632
|
Returns
|
|
425
633
|
-------
|
|
426
634
|
Input
|
|
427
|
-
The input data.
|
|
635
|
+
The loaded input data in an Input object.
|
|
428
636
|
|
|
429
637
|
Raises
|
|
430
638
|
------
|
|
431
639
|
ValueError
|
|
432
|
-
If the path is
|
|
640
|
+
If the path is invalid or data format is incorrect.
|
|
641
|
+
|
|
642
|
+
Examples
|
|
643
|
+
--------
|
|
644
|
+
>>> from nextmv.input import load, InputFormat
|
|
645
|
+
>>> # Load JSON from stdin
|
|
646
|
+
>>> input_obj = load(input_format=InputFormat.JSON)
|
|
647
|
+
>>> # Load CSV from a file
|
|
648
|
+
>>> input_obj = load(input_format=InputFormat.CSV, path="data.csv")
|
|
649
|
+
>>> # Load CSV archive from a directory
|
|
650
|
+
>>> input_obj = load(input_format=InputFormat.CSV_ARCHIVE, path="input_dir")
|
|
433
651
|
"""
|
|
434
652
|
|
|
435
653
|
return loader.load(input_format, options, path, csv_configurations)
|
nextmv/logger.py
CHANGED
|
@@ -1,14 +1,48 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Logger module that writes to stderr.
|
|
3
|
+
|
|
4
|
+
This module provides utilities for redirecting standard output to standard error
|
|
5
|
+
and for writing log messages directly to stderr.
|
|
6
|
+
|
|
7
|
+
Functions
|
|
8
|
+
---------
|
|
9
|
+
redirect_stdout
|
|
10
|
+
Redirect all messages written to stdout to stderr.
|
|
11
|
+
reset_stdout
|
|
12
|
+
Reset stdout to its original value.
|
|
13
|
+
log
|
|
14
|
+
Log a message to stderr.
|
|
15
|
+
"""
|
|
2
16
|
|
|
3
17
|
import sys
|
|
4
18
|
|
|
19
|
+
# Original stdout reference held when redirection is active
|
|
5
20
|
__original_stdout = None
|
|
21
|
+
# Flag to track if stdout has been redirected
|
|
6
22
|
__stdout_redirected = False
|
|
7
23
|
|
|
8
24
|
|
|
9
25
|
def redirect_stdout() -> None:
|
|
10
|
-
"""
|
|
11
|
-
to
|
|
26
|
+
"""
|
|
27
|
+
Redirect all messages written to stdout to stderr.
|
|
28
|
+
|
|
29
|
+
You can import the `redirect_stdout` function directly from `nextmv`:
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from nextmv import redirect_stdout
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This function captures the current sys.stdout and replaces it with sys.stderr.
|
|
36
|
+
When redirection is no longer needed, call `reset_stdout()` to restore the
|
|
37
|
+
original stdout.
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
--------
|
|
41
|
+
>>> redirect_stdout()
|
|
42
|
+
>>> print("This will go to stderr")
|
|
43
|
+
>>> reset_stdout()
|
|
44
|
+
>>> print("This will go to stdout")
|
|
45
|
+
"""
|
|
12
46
|
|
|
13
47
|
global __original_stdout, __stdout_redirected
|
|
14
48
|
if __stdout_redirected:
|
|
@@ -20,9 +54,26 @@ def redirect_stdout() -> None:
|
|
|
20
54
|
|
|
21
55
|
|
|
22
56
|
def reset_stdout() -> None:
|
|
23
|
-
"""
|
|
24
|
-
|
|
57
|
+
"""
|
|
58
|
+
Reset stdout to its original value.
|
|
59
|
+
|
|
60
|
+
You can import the `reset_stdout` function directly from `nextmv`:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from nextmv import reset_stdout
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
This function should always be called after `redirect_stdout()` to avoid
|
|
67
|
+
unexpected behavior. It restores the original stdout that was captured
|
|
68
|
+
during redirection.
|
|
25
69
|
|
|
70
|
+
Examples
|
|
71
|
+
--------
|
|
72
|
+
>>> redirect_stdout()
|
|
73
|
+
>>> print("This will go to stderr")
|
|
74
|
+
>>> reset_stdout()
|
|
75
|
+
>>> print("This will go to stdout")
|
|
76
|
+
"""
|
|
26
77
|
global __original_stdout, __stdout_redirected
|
|
27
78
|
if not __stdout_redirected:
|
|
28
79
|
return
|
|
@@ -40,8 +91,21 @@ def log(message: str) -> None:
|
|
|
40
91
|
"""
|
|
41
92
|
Log a message to stderr.
|
|
42
93
|
|
|
43
|
-
|
|
44
|
-
|
|
94
|
+
You can import the `log` function directly from `nextmv`:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from nextmv import log
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Parameters
|
|
101
|
+
----------
|
|
102
|
+
message : str
|
|
103
|
+
The message to log.
|
|
104
|
+
|
|
105
|
+
Examples
|
|
106
|
+
--------
|
|
107
|
+
>>> log("An error occurred")
|
|
108
|
+
An error occurred
|
|
45
109
|
"""
|
|
46
110
|
|
|
47
111
|
print(message, file=sys.stderr)
|