ostruct-cli 0.8.8__py3-none-any.whl → 1.0.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.
- ostruct/cli/__init__.py +3 -15
- ostruct/cli/attachment_processor.py +455 -0
- ostruct/cli/attachment_template_bridge.py +973 -0
- ostruct/cli/cli.py +187 -33
- ostruct/cli/click_options.py +775 -692
- ostruct/cli/code_interpreter.py +195 -12
- ostruct/cli/commands/__init__.py +0 -3
- ostruct/cli/commands/run.py +289 -62
- ostruct/cli/config.py +23 -22
- ostruct/cli/constants.py +89 -0
- ostruct/cli/errors.py +191 -6
- ostruct/cli/explicit_file_processor.py +0 -15
- ostruct/cli/file_info.py +118 -14
- ostruct/cli/file_list.py +82 -1
- ostruct/cli/file_search.py +68 -2
- ostruct/cli/help_json.py +235 -0
- ostruct/cli/mcp_integration.py +13 -16
- ostruct/cli/params.py +217 -0
- ostruct/cli/plan_assembly.py +335 -0
- ostruct/cli/plan_printing.py +385 -0
- ostruct/cli/progress_reporting.py +8 -56
- ostruct/cli/quick_ref_help.py +128 -0
- ostruct/cli/rich_config.py +299 -0
- ostruct/cli/runner.py +397 -190
- ostruct/cli/security/__init__.py +2 -0
- ostruct/cli/security/allowed_checker.py +41 -0
- ostruct/cli/security/normalization.py +13 -9
- ostruct/cli/security/security_manager.py +558 -17
- ostruct/cli/security/types.py +15 -0
- ostruct/cli/template_debug.py +283 -261
- ostruct/cli/template_debug_help.py +233 -142
- ostruct/cli/template_env.py +46 -5
- ostruct/cli/template_filters.py +415 -8
- ostruct/cli/template_processor.py +240 -619
- ostruct/cli/template_rendering.py +49 -73
- ostruct/cli/template_validation.py +2 -1
- ostruct/cli/token_validation.py +35 -15
- ostruct/cli/types.py +15 -19
- ostruct/cli/unicode_compat.py +283 -0
- ostruct/cli/upload_manager.py +448 -0
- ostruct/cli/utils.py +30 -0
- ostruct/cli/validators.py +272 -54
- {ostruct_cli-0.8.8.dist-info → ostruct_cli-1.0.0.dist-info}/METADATA +292 -126
- ostruct_cli-1.0.0.dist-info/RECORD +80 -0
- ostruct/cli/commands/quick_ref.py +0 -54
- ostruct/cli/template_optimizer.py +0 -478
- ostruct_cli-0.8.8.dist-info/RECORD +0 -71
- {ostruct_cli-0.8.8.dist-info → ostruct_cli-1.0.0.dist-info}/LICENSE +0 -0
- {ostruct_cli-0.8.8.dist-info → ostruct_cli-1.0.0.dist-info}/WHEEL +0 -0
- {ostruct_cli-0.8.8.dist-info → ostruct_cli-1.0.0.dist-info}/entry_points.txt +0 -0
ostruct/cli/cli.py
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""Main CLI module for ostruct."""
|
2
3
|
|
4
|
+
import os
|
3
5
|
import sys
|
4
6
|
from typing import Optional
|
5
7
|
|
6
|
-
import click
|
8
|
+
import rich_click as click
|
7
9
|
from dotenv import load_dotenv
|
8
10
|
|
9
11
|
from .. import __version__
|
@@ -17,50 +19,119 @@ from .errors import (
|
|
17
19
|
handle_error,
|
18
20
|
)
|
19
21
|
from .exit_codes import ExitCode
|
22
|
+
from .help_json import print_full_cli_help_json as print_full_help_json
|
20
23
|
from .registry_updates import get_update_notification
|
21
24
|
|
25
|
+
# Import rich-click configuration
|
26
|
+
from .rich_config import * # noqa: F401,F403
|
27
|
+
from .unicode_compat import safe_emoji
|
28
|
+
from .utils import fix_surrogate_escapes
|
29
|
+
|
30
|
+
# Load environment variables from .env file
|
31
|
+
load_dotenv()
|
32
|
+
|
33
|
+
|
34
|
+
def _handle_quick_ref(
|
35
|
+
ctx: click.Context, param: click.Parameter, value: bool
|
36
|
+
) -> None:
|
37
|
+
"""Handle --quick-ref flag by showing quick reference help and exiting."""
|
38
|
+
if not value or ctx.resilient_parsing:
|
39
|
+
return
|
40
|
+
|
41
|
+
from .quick_ref_help import show_quick_ref_help
|
42
|
+
|
43
|
+
show_quick_ref_help()
|
44
|
+
ctx.exit()
|
45
|
+
|
46
|
+
|
47
|
+
def _handle_version(
|
48
|
+
ctx: click.Context, param: click.Parameter, value: bool
|
49
|
+
) -> None:
|
50
|
+
"""Handle --version flag by showing version and exiting."""
|
51
|
+
if not value or ctx.resilient_parsing:
|
52
|
+
return
|
53
|
+
click.echo(f"ostruct, version {__version__}")
|
54
|
+
ctx.exit()
|
55
|
+
|
56
|
+
|
57
|
+
def fix_argv_encoding() -> None:
|
58
|
+
"""Fix UTF-8 encoding issues in sys.argv.
|
59
|
+
|
60
|
+
This function addresses the surrogate escape issue where Python's sys.argv
|
61
|
+
contains surrogate characters (e.g., a backslash followed by 'udce2')
|
62
|
+
when processing command line arguments with non-ASCII characters. This
|
63
|
+
commonly happens with filenames containing characters like en dash (–) or
|
64
|
+
other Unicode characters.
|
65
|
+
|
66
|
+
The fix detects arguments containing surrogate escapes and converts them
|
67
|
+
back to proper UTF-8 strings.
|
68
|
+
"""
|
69
|
+
try:
|
70
|
+
fixed_argv = []
|
71
|
+
for arg in sys.argv:
|
72
|
+
fixed_argv.append(fix_surrogate_escapes(arg))
|
73
|
+
|
74
|
+
# Replace sys.argv with the fixed version
|
75
|
+
sys.argv = fixed_argv
|
76
|
+
|
77
|
+
except Exception:
|
78
|
+
# If anything goes wrong with the encoding fix, continue with original argv
|
79
|
+
# This ensures the CLI doesn't break even if the fix fails
|
80
|
+
pass
|
81
|
+
|
22
82
|
|
23
83
|
def create_cli_group() -> click.Group:
|
24
84
|
"""Create the main CLI group with all commands."""
|
25
85
|
|
26
|
-
@click.group()
|
27
|
-
@click.
|
86
|
+
@click.group(cls=click.RichGroup)
|
87
|
+
@click.option(
|
88
|
+
"--version",
|
89
|
+
"-V",
|
90
|
+
is_flag=True,
|
91
|
+
expose_value=False,
|
92
|
+
is_eager=True,
|
93
|
+
callback=_handle_version,
|
94
|
+
help="Show the version and exit.",
|
95
|
+
)
|
28
96
|
@click.option(
|
29
97
|
"--config",
|
30
98
|
type=click.Path(exists=True),
|
31
99
|
help="Configuration file path (default: ostruct.yaml)",
|
32
100
|
)
|
101
|
+
@click.option(
|
102
|
+
"--quick-ref",
|
103
|
+
is_flag=True,
|
104
|
+
callback=_handle_quick_ref,
|
105
|
+
expose_value=False,
|
106
|
+
is_eager=True,
|
107
|
+
help=f"{safe_emoji('📖')} Show concise usage examples and patterns",
|
108
|
+
)
|
109
|
+
@click.option(
|
110
|
+
"--help-json",
|
111
|
+
is_flag=True,
|
112
|
+
callback=print_full_help_json,
|
113
|
+
expose_value=False,
|
114
|
+
is_eager=True,
|
115
|
+
hidden=True, # Hide from help output - feature not ready for release
|
116
|
+
help=f"{safe_emoji('📖')} Output comprehensive help for all commands in JSON format",
|
117
|
+
)
|
118
|
+
@click.option(
|
119
|
+
"--unicode/--no-unicode",
|
120
|
+
default=None,
|
121
|
+
help="Force enable/disable Unicode emoji display (overrides auto-detection)",
|
122
|
+
envvar="OSTRUCT_UNICODE",
|
123
|
+
)
|
33
124
|
@click.pass_context
|
34
|
-
def cli_group(
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
📁 FILE ROUTING (explicit tool assignment):
|
45
|
-
-ft/--file-for-template Template access only
|
46
|
-
-fc/--file-for-code-interpreter Code execution & analysis
|
47
|
-
-fs/--file-for-file-search Document search & retrieval
|
48
|
-
|
49
|
-
⚡ EXAMPLES:
|
50
|
-
# Basic usage (unchanged)
|
51
|
-
ostruct run template.j2 schema.json -f config.yaml
|
52
|
-
|
53
|
-
# Multi-tool explicit routing
|
54
|
-
ostruct run analysis.j2 schema.json -fc data.csv -fs docs.pdf -ft config.yaml
|
55
|
-
|
56
|
-
# Advanced routing with --file-for
|
57
|
-
ostruct run task.j2 schema.json --file-for code-interpreter shared.json --file-for file-search shared.json
|
125
|
+
def cli_group(
|
126
|
+
ctx: click.Context,
|
127
|
+
config: Optional[str] = None,
|
128
|
+
unicode: Optional[bool] = None,
|
129
|
+
) -> None:
|
130
|
+
"""ostruct - AI-powered structured output with multi-tool integration."""
|
131
|
+
# Handle Unicode preference
|
132
|
+
if unicode is not None:
|
133
|
+
os.environ["OSTRUCT_UNICODE"] = "1" if unicode else "0"
|
58
134
|
|
59
|
-
# MCP server integration
|
60
|
-
ostruct run template.j2 schema.json --mcp-server deepwiki@https://mcp.deepwiki.com/sse
|
61
|
-
|
62
|
-
📖 For detailed documentation: https://ostruct.readthedocs.io
|
63
|
-
"""
|
64
135
|
# Load configuration
|
65
136
|
try:
|
66
137
|
app_config = OstructConfig.load(config)
|
@@ -85,6 +156,86 @@ def create_cli_group() -> click.Group:
|
|
85
156
|
# Ensure any errors don't affect normal operation
|
86
157
|
pass
|
87
158
|
|
159
|
+
# Set the docstring dynamically with emoji compatibility
|
160
|
+
rocket = safe_emoji("🚀")
|
161
|
+
folder = safe_emoji("📁")
|
162
|
+
target = safe_emoji("🎯")
|
163
|
+
book = safe_emoji("📖")
|
164
|
+
lightning = safe_emoji("⚡")
|
165
|
+
wrench = safe_emoji("🔧")
|
166
|
+
|
167
|
+
cli_group.__doc__ = f"""ostruct - AI-powered structured output with multi-tool integration.
|
168
|
+
|
169
|
+
Transform unstructured inputs into structured JSON using OpenAI APIs, Jinja2 templates, and powerful tool integrations.
|
170
|
+
|
171
|
+
{rocket} **QUICK START**
|
172
|
+
|
173
|
+
ostruct run template.j2 schema.json --var name=value
|
174
|
+
|
175
|
+
{folder} **FILE ATTACHMENT SYSTEM**
|
176
|
+
|
177
|
+
--file [targets:]alias path Attach file with optional target routing
|
178
|
+
|
179
|
+
--dir [targets:]alias path Attach directory with optional target routing
|
180
|
+
|
181
|
+
{target} **TARGETS**
|
182
|
+
|
183
|
+
prompt (default) Template access only
|
184
|
+
|
185
|
+
code-interpreter, ci Code execution & analysis
|
186
|
+
|
187
|
+
file-search, fs Document search & retrieval
|
188
|
+
|
189
|
+
{book} **GETTING HELP**
|
190
|
+
|
191
|
+
ostruct --help Command overview
|
192
|
+
|
193
|
+
ostruct --quick-ref Usage examples and patterns
|
194
|
+
|
195
|
+
ostruct run --help Detailed options reference
|
196
|
+
|
197
|
+
ostruct run --help-debug Troubleshooting guide
|
198
|
+
|
199
|
+
{book} Documentation: https://ostruct.readthedocs.io
|
200
|
+
|
201
|
+
{lightning} **EXAMPLES**
|
202
|
+
|
203
|
+
# Basic usage
|
204
|
+
ostruct run template.j2 schema.json --file data file.txt
|
205
|
+
|
206
|
+
# Multi-tool routing
|
207
|
+
ostruct run analysis.j2 schema.json --file ci:data data.csv --file fs:docs manual.pdf
|
208
|
+
|
209
|
+
# Combined targets
|
210
|
+
ostruct run task.j2 schema.json --file ci,fs:shared data.json
|
211
|
+
|
212
|
+
# MCP server integration
|
213
|
+
ostruct run template.j2 schema.json --mcp-server deepwiki@https://mcp.deepwiki.com/sse
|
214
|
+
|
215
|
+
{wrench} **ENVIRONMENT VARIABLES**
|
216
|
+
|
217
|
+
```text
|
218
|
+
Core API Configuration:
|
219
|
+
OPENAI_API_KEY OpenAI API authentication key
|
220
|
+
OPENAI_API_BASE Custom OpenAI API base URL
|
221
|
+
|
222
|
+
Template Processing Limits:
|
223
|
+
OSTRUCT_TEMPLATE_FILE_LIMIT Max individual file size (default: 64KB)
|
224
|
+
OSTRUCT_TEMPLATE_TOTAL_LIMIT Max total files size (default: 1MB)
|
225
|
+
OSTRUCT_TEMPLATE_PREVIEW_LIMIT Template preview size limit (default: 4096)
|
226
|
+
|
227
|
+
System Behavior:
|
228
|
+
OSTRUCT_DISABLE_REGISTRY_UPDATE_CHECKS Disable model registry updates
|
229
|
+
OSTRUCT_MCP_URL_<name> Custom MCP server URLs
|
230
|
+
|
231
|
+
Unicode Display Control:
|
232
|
+
OSTRUCT_UNICODE=auto Auto-detect terminal capabilities (default)
|
233
|
+
OSTRUCT_UNICODE=1/true/yes Force emoji display (override detection)
|
234
|
+
OSTRUCT_UNICODE=0/false/no Force plain text (override detection)
|
235
|
+
OSTRUCT_UNICODE=debug Show detection details and auto-detect
|
236
|
+
```
|
237
|
+
"""
|
238
|
+
|
88
239
|
# Add all commands from the command module
|
89
240
|
command_group = create_command_group()
|
90
241
|
for command in command_group.commands.values():
|
@@ -108,6 +259,9 @@ def create_cli() -> click.Command:
|
|
108
259
|
|
109
260
|
def main() -> None:
|
110
261
|
"""Main entry point for the CLI."""
|
262
|
+
# Fix UTF-8 encoding issues in command line arguments before processing
|
263
|
+
fix_argv_encoding()
|
264
|
+
|
111
265
|
# Load environment variables from .env file
|
112
266
|
load_dotenv()
|
113
267
|
|