ostruct-cli 0.8.2__py3-none-any.whl → 0.8.4__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.
@@ -50,6 +50,7 @@ Notes:
50
50
  """
51
51
 
52
52
  import logging
53
+ import re
53
54
  from typing import (
54
55
  Any,
55
56
  Callable,
@@ -150,6 +151,45 @@ def find_loop_vars(nodes: List[Node]) -> Set[str]:
150
151
  return loop_vars
151
152
 
152
153
 
154
+ def _extract_variable_name_from_jinja_error(error_message: str) -> str:
155
+ """Extract the actual variable name from a Jinja2 UndefinedError message.
156
+
157
+ Handles various Jinja2 error message formats:
158
+ - "'variable_name' is undefined"
159
+ - "'object_description' has no attribute 'property_name'"
160
+ - Other formats
161
+
162
+ Args:
163
+ error_message: The string representation of the Jinja2 UndefinedError
164
+
165
+ Returns:
166
+ The extracted variable name, or a sanitized version if parsing fails
167
+ """
168
+ # Pattern 1: Standard undefined variable: "'variable_name' is undefined"
169
+ match = re.match(r"'([^']+)' is undefined", error_message)
170
+ if match:
171
+ return match.group(1)
172
+
173
+ # Pattern 2: Attribute access on object: "'object' has no attribute 'property'"
174
+ # In this case, we want to extract just the property name, not the object description
175
+ match = re.match(r"'[^']+' has no attribute '([^']+)'", error_message)
176
+ if match:
177
+ property_name = match.group(1)
178
+ return property_name
179
+
180
+ # Pattern 3: Try to find any quoted identifier that looks like a variable name
181
+ # Look for quoted strings that contain only valid Python identifier characters
182
+ quoted_parts: List[str] = re.findall(r"'([^']+)'", error_message)
183
+ for part in quoted_parts:
184
+ # Check if this looks like a variable name (not a class name or description)
185
+ if re.match(r"^[a-zA-Z_][a-zA-Z0-9_]*$", part) and "." not in part:
186
+ return part
187
+
188
+ # Fallback: If we can't parse it properly, return a generic message
189
+ # This avoids exposing internal class names to users
190
+ return "unknown_variable"
191
+
192
+
153
193
  def validate_template_placeholders(
154
194
  template: str, template_context: Optional[Dict[str, Any]] = None
155
195
  ) -> None:
@@ -343,9 +383,7 @@ def validate_template_placeholders(
343
383
  env.from_string(template).render(validation_context)
344
384
  except jinja2.UndefinedError as e:
345
385
  # Convert Jinja2 undefined errors to TaskTemplateVariableError with helpful message
346
- var_name = str(e).split("'")[
347
- 1
348
- ] # Extract variable name from error message
386
+ var_name = _extract_variable_name_from_jinja_error(str(e))
349
387
  error_msg = (
350
388
  f"Missing required template variable: {var_name}\n"
351
389
  f"Available variables: {', '.join(sorted(available_vars))}\n"
ostruct/cli/types.py CHANGED
@@ -35,7 +35,6 @@ class CLIParams(TypedDict, total=False):
35
35
  no_progress: bool
36
36
  api_key: Optional[str]
37
37
  verbose: bool
38
- debug_openai_stream: bool
39
38
  show_model_schema: bool
40
39
  debug_validation: bool
41
40
  temperature: Optional[float]
@@ -76,3 +75,17 @@ class CLIParams(TypedDict, total=False):
76
75
  tool_files: List[
77
76
  Tuple[str, str]
78
77
  ] # List of (tool, path) tuples from --file-for
78
+ web_search: bool
79
+ debug: bool
80
+ show_templates: bool
81
+ debug_templates: bool
82
+ show_context: bool
83
+ show_context_detailed: bool
84
+ show_pre_optimization: bool
85
+ show_optimization_diff: bool
86
+ no_optimization: bool
87
+ show_optimization_steps: bool
88
+ optimization_step_detail: str
89
+ help_debug: bool
90
+ enabled_features: List[str] # List of feature names to enable
91
+ disabled_features: List[str] # List of feature names to disable
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ostruct-cli
3
- Version: 0.8.2
3
+ Version: 0.8.4
4
4
  Summary: CLI for OpenAI Structured Output with Multi-Tool Integration
5
5
  Author: Yaniv Golan
6
6
  Author-email: yaniv@golan.name
@@ -22,6 +22,7 @@ Requires-Dist: chardet (>=5.0.0,<6.0)
22
22
  Requires-Dist: click (>=8.1.7,<9.0)
23
23
  Requires-Dist: flake8 (>=6.0,<7.0) ; extra == "dev"
24
24
  Requires-Dist: flake8-pyproject (>=1.2.3,<2.0) ; extra == "dev"
25
+ Requires-Dist: hypothesis (>=6.0.0,<7.0) ; extra == "dev"
25
26
  Requires-Dist: ijson (>=3.2.3,<4.0)
26
27
  Requires-Dist: jinja2 (>=3.1.2,<4.0)
27
28
  Requires-Dist: jsonschema (>=4.23.0,<5.0)
@@ -37,6 +38,8 @@ Requires-Dist: pygments (>=2.15.0,<3.0)
37
38
  Requires-Dist: pytest (>=8.3.4,<9.0) ; extra == "dev"
38
39
  Requires-Dist: pytest-asyncio (>=0.25.2,<1.0) ; extra == "dev"
39
40
  Requires-Dist: pytest-mock (>=3.14.0,<4.0) ; extra == "dev"
41
+ Requires-Dist: pytest-rerunfailures (>=12.0,<13.0) ; extra == "dev"
42
+ Requires-Dist: python-dotenv (>=1.0.1,<2.0)
40
43
  Requires-Dist: python-dotenv (>=1.0.1,<2.0) ; extra == "dev"
41
44
  Requires-Dist: pyyaml (>=6.0.2,<7.0)
42
45
  Requires-Dist: sphinx (>=7.0,<8.0) ; extra == "dev"
@@ -46,6 +49,7 @@ Requires-Dist: sphinx-rtd-theme (>=1.0,<2.0) ; extra == "docs"
46
49
  Requires-Dist: tenacity (>=8.2.3,<9.0) ; extra == "examples"
47
50
  Requires-Dist: tiktoken (==0.9.0)
48
51
  Requires-Dist: tomli (>=2.0.1,<3.0) ; (python_version < "3.11") and (extra == "docs")
52
+ Requires-Dist: tomli (>=2.0.1,<3.0) ; extra == "dev"
49
53
  Requires-Dist: tomli (>=2.0.1,<3.0) ; python_version < "3.11"
50
54
  Requires-Dist: twine (>=6.0.1,<7.0) ; extra == "dev"
51
55
  Requires-Dist: types-cachetools (>=5.5.0.20240820) ; extra == "dev"
@@ -235,6 +239,8 @@ ostruct-cli respects the following environment variables:
235
239
  - `OSTRUCT_DISABLE_REGISTRY_UPDATE_CHECKS`: Set to "1", "true", or "yes" to disable automatic registry update checks
236
240
  - `MCP_<NAME>_URL`: Custom MCP server URLs (e.g., `MCP_STRIPE_URL=https://mcp.stripe.com`)
237
241
 
242
+ **💡 Tip**: ostruct automatically loads `.env` files from the current directory. Environment variables take precedence over `.env` file values.
243
+
238
244
  <details>
239
245
  <summary><strong>Shell Completion Setup</strong> (Click to expand)</summary>
240
246
 
@@ -302,7 +308,7 @@ ostruct run analysis.j2 schema.json -fc data.csv
302
308
  ostruct run search.j2 schema.json -fs documentation.pdf
303
309
 
304
310
  # Web Search (real-time information)
305
- ostruct run research.j2 schema.json --web-search -V topic="latest AI developments"
311
+ ostruct run research.j2 schema.json --enable-tool web-search -V topic="latest AI developments"
306
312
 
307
313
  # Multiple tools with one file
308
314
  ostruct run template.j2 schema.json --file-for code-interpreter shared.json --file-for file-search shared.json
@@ -370,6 +376,7 @@ tools:
370
376
  code_interpreter:
371
377
  auto_download: true
372
378
  output_directory: "./output"
379
+ download_strategy: "two_pass_sentinel" # Enable reliable file downloads
373
380
 
374
381
  mcp:
375
382
  custom_server: "https://my-mcp-server.com"
@@ -384,6 +391,35 @@ Load custom configuration:
384
391
  ostruct --config my-config.yaml run template.j2 schema.json
385
392
  ```
386
393
 
394
+ ### Code Interpreter File Downloads
395
+
396
+ **Important**: If you're using Code Interpreter with structured output (JSON schemas), you may need to enable the two-pass download strategy to ensure files are downloaded reliably.
397
+
398
+ #### Option 1: CLI Flags (Recommended for one-off usage)
399
+
400
+ ```bash
401
+ # Enable reliable file downloads for this run
402
+ ostruct run template.j2 schema.json -fc data.csv --enable-feature ci-download-hack
403
+
404
+ # Force single-pass mode (override config)
405
+ ostruct run template.j2 schema.json -fc data.csv --disable-feature ci-download-hack
406
+ ```
407
+
408
+ #### Option 2: Configuration File (Recommended for persistent settings)
409
+
410
+ ```yaml
411
+ # ostruct.yaml
412
+ tools:
413
+ code_interpreter:
414
+ download_strategy: "two_pass_sentinel" # Enables reliable file downloads
415
+ auto_download: true
416
+ output_directory: "./downloads"
417
+ ```
418
+
419
+ **Why this is needed**: OpenAI's structured output mode can prevent file download annotations from being generated. The two-pass strategy works around this by making two API calls: one to generate files (without structured output), then another to ensure schema compliance. For detailed technical information, see [docs/known-issues/2025-06-responses-ci-file-output.md](docs/known-issues/2025-06-responses-ci-file-output.md).
420
+
421
+ **Performance**: The two-pass strategy approximately doubles token usage but ensures reliable file downloads when using structured output with Code Interpreter.
422
+
387
423
  ## Get Started Quickly
388
424
 
389
425
  🚀 **New to ostruct?** Follow our [step-by-step quickstart guide](https://ostruct.readthedocs.io/en/latest/user-guide/quickstart.html) featuring Juno the beagle for a hands-on introduction.
@@ -395,7 +431,11 @@ ostruct --config my-config.yaml run template.j2 schema.json
395
431
  1. Set your OpenAI API key:
396
432
 
397
433
  ```bash
434
+ # Environment variable
398
435
  export OPENAI_API_KEY=your-api-key
436
+
437
+ # Or create a .env file
438
+ echo 'OPENAI_API_KEY=your-api-key' > .env
399
439
  ```
400
440
 
401
441
  ### Example 1: Basic Text Extraction (Simplest)
@@ -628,6 +668,60 @@ The registry file is stored at `~/.openai_structured/config/models.yml` and is a
628
668
 
629
669
  The update command uses HTTP conditional requests (If-Modified-Since headers) to check if the remote registry has changed before downloading, ensuring efficient updates.
630
670
 
671
+ # Testing
672
+
673
+ ## Running Tests
674
+
675
+ The test suite is divided into two categories:
676
+
677
+ ### Regular Tests (Default)
678
+
679
+ ```bash
680
+ # Run all tests (skips live tests by default)
681
+ pytest
682
+
683
+ # Run specific test file
684
+ pytest tests/test_config.py
685
+
686
+ # Run with verbose output
687
+ pytest -v
688
+ ```
689
+
690
+ ### Live Tests
691
+
692
+ Live tests make real API calls to OpenAI and require a valid API key. They are skipped by default.
693
+
694
+ ```bash
695
+ # Run only live tests (requires OPENAI_API_KEY)
696
+ pytest -m live
697
+
698
+ # Run all tests including live tests
699
+ pytest -m "live or not live"
700
+
701
+ # Run specific live test
702
+ pytest tests/test_responses_annotations.py -m live
703
+ ```
704
+
705
+ **Live tests include:**
706
+
707
+ - Tests that make actual OpenAI API calls
708
+ - Tests that run `ostruct` commands via subprocess
709
+ - Tests that verify real API behavior and file downloads
710
+
711
+ **Requirements for live tests:**
712
+
713
+ - Valid `OPENAI_API_KEY` environment variable
714
+ - Internet connection
715
+ - May incur API costs
716
+
717
+ ## Test Markers
718
+
719
+ - `@pytest.mark.live` - Tests that make real API calls or run actual commands
720
+ - `@pytest.mark.no_fs` - Tests that need real filesystem (not pyfakefs)
721
+ - `@pytest.mark.slow` - Performance/stress tests
722
+ - `@pytest.mark.flaky` - Tests that may need reruns
723
+ - `@pytest.mark.mock_openai` - Tests using mocked OpenAI client
724
+
631
725
  <!--
632
726
  MAINTAINER NOTE: After editing this README, please test GitHub rendering by:
633
727
  1. Creating a draft PR or pushing to a test branch
@@ -2,32 +2,33 @@ ostruct/__init__.py,sha256=X6zo6V7ZNMv731Wi388aTVQngD1410ExGwGx4J6lpyo,187
2
2
  ostruct/cli/__init__.py,sha256=e-DtWRviCr3fIAJH4cB4UAvles3-rqnhJaTOlBn9TKs,871
3
3
  ostruct/cli/base_errors.py,sha256=o-877bJJA8yJWISRPy0KyL6wDu1-_avddmQIfVePuFM,5989
4
4
  ostruct/cli/cache_manager.py,sha256=ej3KrRfkKKZ_lEp2JswjbJ5bW2ncsvna9NeJu81cqqs,5192
5
- ostruct/cli/cli.py,sha256=ZUkQ-iwk4KCKeetPMlvSDwxfXIe4h1-yP80SfJgvi_o,4098
6
- ostruct/cli/click_options.py,sha256=f2a6XTidy-RJgL64WAgTqRYpMPokY0O8Bb6aQgwMOtk,28298
7
- ostruct/cli/code_interpreter.py,sha256=sEq-zi0CfotRqEseA9pWTm-UU1fZTH_06WGvWPNwct8,7786
5
+ ostruct/cli/cli.py,sha256=pzOzKMvWQMRS1I9w4raAUi-O7IN6OKViNTcOeJGEqhI,4196
6
+ ostruct/cli/click_options.py,sha256=UWLBIkfVMXcIMXInJFWNYNO9Ieg8YrJEzRfkKungy48,31730
7
+ ostruct/cli/code_interpreter.py,sha256=lnnyEvUh2pGObN9ENpr-X4p0C0oIWiyG1CFQWW4akBQ,16726
8
8
  ostruct/cli/commands/__init__.py,sha256=3NHz-WZ9XqrnWWMksoV2MpYpHnjA-EO9lsrBOYeHcjY,723
9
9
  ostruct/cli/commands/list_models.py,sha256=yeuQpUGAmRr4uOHS7teuVHkC9dkqN0yKDOEw_n-ehi0,4662
10
10
  ostruct/cli/commands/quick_ref.py,sha256=zpD7kI3sfrcc9CiRkzWdASTNX5jAk3HFB7MilzlCsag,2004
11
- ostruct/cli/commands/run.py,sha256=1M5KYhXPLJLFVbfGJHRp88kO25CSN6TP1A0cVex1-7A,4370
11
+ ostruct/cli/commands/run.py,sha256=Cm9Yuf0DLt5CqKfgAYubhQRcvLdK1vqIIuz_ynjfhQ4,6640
12
12
  ostruct/cli/commands/update_registry.py,sha256=7DQrPlCJScPVgE2HbFAM7UMap-EdYu58AQWfpI-H7Gw,2483
13
- ostruct/cli/config.py,sha256=keX5mUiyZ9_CrVHZFpxr7loBAetORRW-ZjNUoQFa_k8,9030
13
+ ostruct/cli/config.py,sha256=7tKI1gWLpTISn5OorGWIx66N1J7XW2aq30hPNISZzQ0,9958
14
14
  ostruct/cli/cost_estimation.py,sha256=08hyE-kM5QYzj7y-KB3lMD_RxCMoM_Ve3-IQlSpJAo4,4483
15
- ostruct/cli/errors.py,sha256=WUa_LwwBMynrP9WVgS199ovir1XJFLZIRw5QoPRLVwY,25145
15
+ ostruct/cli/errors.py,sha256=sVOM_ZKvrtnmT8_WR-DfX2crs6HmvmwrbNQlxm-5_Ew,24669
16
16
  ostruct/cli/exit_codes.py,sha256=gdvB1dpu0LalEUZrofpk5K6aTQ24n5AfkAK5umludHU,365
17
17
  ostruct/cli/explicit_file_processor.py,sha256=B6yUPbyn6MVd81GcyMVpORFwyaHFFESLwFixp2B6M5w,19767
18
18
  ostruct/cli/field_utils.py,sha256=bcRi1qQ0Ac2UCfrKSQ677_yu-VzaShm_zN7QLf98qc0,1939
19
- ostruct/cli/file_info.py,sha256=Vgx-unid2ODSYbJxzgC2ndEeh-DS6eADsrqG34_C820,16182
19
+ ostruct/cli/file_info.py,sha256=s8AHPtyU3__2LRJCCIEPuODYM43is4Y2Q_VDhBOl3XU,17395
20
20
  ostruct/cli/file_list.py,sha256=alRAguq4tj1zH0_qlWaRoyHo1G1Xmxqu9Xd4QP-zYP0,20268
21
21
  ostruct/cli/file_search.py,sha256=N12mkji2ttvItLVPyAWE3KEfhTv8hV5IXPrQME2UFdE,15313
22
- ostruct/cli/file_utils.py,sha256=kLZKiZadkIiYvs3B_gngqf_PwMRMYIWw49i8GTGVbkk,23607
22
+ ostruct/cli/file_utils.py,sha256=JZprQ-1LHQzI3eBfeCIS6VmxTa2fGUZHygGC8gcwpJM,24367
23
+ ostruct/cli/json_extract.py,sha256=ZleIxat8g-JnA9VVqWgJaKxN7QzL25itQ8aP0Gb5e4Q,2650
23
24
  ostruct/cli/mcp_integration.py,sha256=EXIz_KbYC4srWZxuKVkINeaHgHvEYB9l1uhptpLNn5I,18774
24
- ostruct/cli/model_creation.py,sha256=l-FHxCaAmZ2akKszoRg8gf1KgJxeT10Pt8YX39bXeT4,23261
25
+ ostruct/cli/model_creation.py,sha256=HGo8Qv7eBF8Co463IR7RcbTCQcaOvd_cBGuRodRCAa4,23261
25
26
  ostruct/cli/model_validation.py,sha256=j2az3q88-Ljm2cMMgZ8p_-gcp1vKQnWCknnw0y0YlAw,6675
26
27
  ostruct/cli/path_utils.py,sha256=j44q1OoLkqMErgK-qEuhuIZ1VyzqRIvNgxR1et9PoXA,4813
27
28
  ostruct/cli/progress.py,sha256=rj9nVEco5UeZORMbzd7mFJpFGJjbH9KbBFh5oTE5Anw,3415
28
29
  ostruct/cli/progress_reporting.py,sha256=MBjALM4pmPd_d9YuXqH162-tkC6DDKYmz-pJPSGLTfk,13669
29
30
  ostruct/cli/registry_updates.py,sha256=ohiHdlfrocvThpR_ZjMyqulDKFjRM1hIFKOlNzpaqHg,5138
30
- ostruct/cli/runner.py,sha256=pNw0TzdpDElzaUYxb8R-rzSPqa1MOzUM-hPaOvpETI4,54045
31
+ ostruct/cli/runner.py,sha256=GzCsPiwhxiaoXvCv-ykFO8KucMvGRyIOPuaNMCVF1pw,65107
31
32
  ostruct/cli/schema_utils.py,sha256=9LnsjxEKg6RIfXQB3nS3pyDggm5n-4-thXf92897gJU,3590
32
33
  ostruct/cli/schema_validation.py,sha256=ohEuxJ0KF93qphj0JSZDnrxDn0C2ZU37g-U2JY03onM,8154
33
34
  ostruct/cli/security/__init__.py,sha256=CQpkCgTFYlA1p6atpQeNgIKtE4LZGUKt4EbytbGKpCs,846
@@ -41,6 +42,7 @@ ostruct/cli/security/security_manager.py,sha256=HFCqJ5kAhaZlFnPTEs6MKNM8JeE2q79d
41
42
  ostruct/cli/security/symlink_resolver.py,sha256=wtZdJ_T_0FOy6B1P5ty1odEXQk9vr8BzlWeAFD4huJE,16744
42
43
  ostruct/cli/security/types.py,sha256=15yuG_T4CXyAFFFdSWLjVS7ACmDGIPXhQpZ8awcDwCQ,2991
43
44
  ostruct/cli/security/windows_paths.py,sha256=qxC2H2kLwtmQ7YePYde3UrmOJcGnsLEebDLh242sUaI,13453
45
+ ostruct/cli/sentinel.py,sha256=69faYPrhVJmEpYNLsCtf1HF96aan3APqXZdIjxBNZYo,798
44
46
  ostruct/cli/serialization.py,sha256=ec0UswDE2onwtZVUoZaMCsGv6zW_tSKdBng2qVo6Ucs,704
45
47
  ostruct/cli/services.py,sha256=nLYUbF3DDNuilh7j9q_atUOjTAWta7bxTS3G-zkveaA,21621
46
48
  ostruct/cli/template_debug.py,sha256=1tP3pTdvQwHcMneYnpWnS2Jr5EQijjyCSQDh5DPXvDE,24698
@@ -49,21 +51,21 @@ ostruct/cli/template_env.py,sha256=7ZcGKyqlkV-ZS2sSUvzyaLsnlvPmfCKUG0epIV8TD6o,1
49
51
  ostruct/cli/template_extensions.py,sha256=_lomtDGMGxMfpw05v_-daJ0JbhRm_r_-uEJlPAjbpkI,2699
50
52
  ostruct/cli/template_filters.py,sha256=S9ad8she0lXRr0PDQVkNrPWbZg7GnybptEXUMkQKOyo,20657
51
53
  ostruct/cli/template_io.py,sha256=yUWO-8rZnSdX97DTMSEX8fG9CP1ISsOhm2NZN3Fab9A,8821
52
- ostruct/cli/template_optimizer.py,sha256=_eQbHQP6fH5tbWLwXtLSLDYlGQ8hLpZKVgXsbcWF2xY,16394
53
- ostruct/cli/template_processor.py,sha256=AWtWEpJvCCFB1PzoDp6EovV4RaIMbY316cb-Iq5o48c,41726
54
- ostruct/cli/template_rendering.py,sha256=5i7gtFjW2QKVW3e_xK0Llrurn0I4e_gG0gzn2p9IFTc,15030
54
+ ostruct/cli/template_optimizer.py,sha256=gwngZ5XrIkU5BrjFibWT0VRf9WrH6NS4SAlrUzme1C8,16684
55
+ ostruct/cli/template_processor.py,sha256=hp9_ZQmVdN6JwCSQJoHB1mVq_p0sTZSojb7c4Y4Vjvs,47301
56
+ ostruct/cli/template_rendering.py,sha256=41f6An7cpI04z2qyesmnXgPVMD1je3ePA6Xz8uuA06U,16705
55
57
  ostruct/cli/template_schema.py,sha256=ckH4rUZnEgfm_BHS9LnMGr8LtDxRmZ0C6UBVrSp8KTc,19604
56
58
  ostruct/cli/template_utils.py,sha256=MZdXXjL-x-IXX-5Y8GWopGNBkDE2ItLdCuCl0QWFR_U,14968
57
- ostruct/cli/template_validation.py,sha256=AXa2zmsws1j-0CTFlp7fMiZR43iNLnj4h467up2JdgU,12693
59
+ ostruct/cli/template_validation.py,sha256=9L1JgM87NIV8JZUoDUT4dRjSDfBl9L8Yl2aVL_ahkmA,14294
58
60
  ostruct/cli/token_utils.py,sha256=r4KPEO3Sec18Q6mU0aClK6XGShvusgUggXEQgEPPlaA,1369
59
61
  ostruct/cli/token_validation.py,sha256=gmyPJ7B2gC_jSx_1wKZq87DEoFulj23X1XnVpO_aRNA,9930
60
- ostruct/cli/types.py,sha256=vCZFBUkeL1QUBM5tTSjEWf_5BUttlyC40kFfpNfTrrY,2474
62
+ ostruct/cli/types.py,sha256=6nARJ4MF5HIank0t6KGU-PPHC0VpFh3R8fNJZBXwgbA,2903
61
63
  ostruct/cli/unattended_operation.py,sha256=kI95SSVJC_taxORXQYrce_qLEnuKc6edwn9tMOye-qs,9383
62
64
  ostruct/cli/utils.py,sha256=uY7c0NaINHWfnl77FcPE3TmYUXv3RqEeUTjrCMDij9A,922
63
65
  ostruct/cli/validators.py,sha256=lbxAUUVS5TPJ7HdYZ5yB7gUjJqfcClZCuh0oktoq0E0,15291
64
66
  ostruct/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
- ostruct_cli-0.8.2.dist-info/LICENSE,sha256=DmGAkaYzhrdzTB9Y2Rvfzd3mJiF9ZrTOhxN8t6wrfHA,1098
66
- ostruct_cli-0.8.2.dist-info/METADATA,sha256=-DJtx83jOezthaQNrOBZpoL_NEH9jbdgCIP1YXOSkGw,21976
67
- ostruct_cli-0.8.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
68
- ostruct_cli-0.8.2.dist-info/entry_points.txt,sha256=NFq9IuqHVTem0j9zKjV8C1si_zGcP1RL6Wbvt9fUDXw,48
69
- ostruct_cli-0.8.2.dist-info/RECORD,,
67
+ ostruct_cli-0.8.4.dist-info/LICENSE,sha256=DmGAkaYzhrdzTB9Y2Rvfzd3mJiF9ZrTOhxN8t6wrfHA,1098
68
+ ostruct_cli-0.8.4.dist-info/METADATA,sha256=4B4H-EqZAyVZOTzeWH_BZbaDqshFZ8YZvvPpVzzaBx0,25161
69
+ ostruct_cli-0.8.4.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
70
+ ostruct_cli-0.8.4.dist-info/entry_points.txt,sha256=NFq9IuqHVTem0j9zKjV8C1si_zGcP1RL6Wbvt9fUDXw,48
71
+ ostruct_cli-0.8.4.dist-info/RECORD,,