ostruct-cli 0.6.1__tar.gz → 0.6.2__tar.gz

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.
Files changed (45) hide show
  1. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/PKG-INFO +39 -177
  2. ostruct_cli-0.6.2/README.md +238 -0
  3. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/pyproject.toml +1 -1
  4. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/cli.py +116 -70
  5. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/errors.py +61 -54
  6. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/model_creation.py +67 -94
  7. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/security/errors.py +1 -1
  8. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/security/normalization.py +1 -1
  9. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/security/security_manager.py +48 -7
  10. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/template_extensions.py +32 -1
  11. ostruct_cli-0.6.2/src/ostruct/cli/template_utils.py +455 -0
  12. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/utils.py +3 -1
  13. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/validators.py +6 -2
  14. ostruct_cli-0.6.1/README.md +0 -376
  15. ostruct_cli-0.6.1/src/ostruct/cli/template_utils.py +0 -296
  16. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/LICENSE +0 -0
  17. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/__init__.py +0 -0
  18. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/__init__.py +0 -0
  19. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/base_errors.py +0 -0
  20. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/cache_manager.py +0 -0
  21. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/click_options.py +0 -0
  22. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/exit_codes.py +0 -0
  23. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/file_info.py +0 -0
  24. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/file_list.py +0 -0
  25. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/file_utils.py +0 -0
  26. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/path_utils.py +0 -0
  27. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/progress.py +0 -0
  28. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/schema_validation.py +0 -0
  29. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/security/__init__.py +0 -0
  30. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/security/allowed_checker.py +0 -0
  31. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/security/base.py +0 -0
  32. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/security/case_manager.py +0 -0
  33. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/security/safe_joiner.py +0 -0
  34. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/security/symlink_resolver.py +0 -0
  35. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/security/types.py +0 -0
  36. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/security/windows_paths.py +0 -0
  37. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/serialization.py +0 -0
  38. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/template_env.py +0 -0
  39. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/template_filters.py +0 -0
  40. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/template_io.py +0 -0
  41. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/template_rendering.py +0 -0
  42. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/template_schema.py +0 -0
  43. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/template_validation.py +0 -0
  44. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/cli/token_utils.py +0 -0
  45. {ostruct_cli-0.6.1 → ostruct_cli-0.6.2}/src/ostruct/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ostruct-cli
3
- Version: 0.6.1
3
+ Version: 0.6.2
4
4
  Summary: CLI for OpenAI Structured Output
5
5
  Author: Yaniv Golan
6
6
  Author-email: yaniv@golan.name
@@ -33,7 +33,9 @@ Description-Content-Type: text/markdown
33
33
  [![CI](https://github.com/yaniv-golan/ostruct/actions/workflows/ci.yml/badge.svg)](https://github.com/yaniv-golan/ostruct/actions/workflows/ci.yml)
34
34
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
35
35
 
36
- Command-line interface for working with OpenAI models and structured output, powered by the [openai-structured](https://github.com/yaniv-golan/openai-structured) library.
36
+ ostruct tranforms unstructured inputs into structured, usable JSON output using OpenAI APIs.
37
+
38
+ ostruct will process a set of plain text files (data, source code, CSV, etc), input variables, a dynamic prompt template, and a JSON schema specifying the desired output format, and will produce the result in JSON format.
37
39
 
38
40
  ## Features
39
41
 
@@ -43,6 +45,10 @@ Command-line interface for working with OpenAI models and structured output, pow
43
45
  - Streaming support for real-time output
44
46
  - Secure handling of sensitive data
45
47
 
48
+ ## Requirements
49
+
50
+ - Python 3.10 or higher
51
+
46
52
  ## Installation
47
53
 
48
54
  ### For Users
@@ -209,196 +215,52 @@ The command will output:
209
215
  }
210
216
  ```
211
217
 
212
- ### Example 3: Processing Multiple Files
218
+ ## System Prompt Handling
213
219
 
214
- 1. Create a template file `extract_from_profiles.j2`:
220
+ ostruct-cli provides three ways to specify a system prompt, with a clear precedence order:
215
221
 
216
- ```jinja
217
- Extract information about the people from this data:
222
+ 1. Command-line option (`--sys-prompt` or `--sys-file`):
218
223
 
219
- {% for profile in profiles %}
220
- == {{ profile.name }}
224
+ ```bash
225
+ # Direct string
226
+ ostruct run template.j2 schema.json --sys-prompt "You are an expert analyst"
221
227
 
222
- {{ profile.content }}
228
+ # From file
229
+ ostruct run template.j2 schema.json --sys-file system_prompt.txt
230
+ ```
223
231
 
224
- {% endfor %}
225
- ```
232
+ 2. Template frontmatter:
226
233
 
227
- 2. Use the same schema file `schema.json` as above, but updated for multiple people:
234
+ ```jinja
235
+ ---
236
+ system_prompt: You are an expert analyst
237
+ ---
238
+ Extract information from: {{ text }}
239
+ ```
228
240
 
229
- ```json
230
- {
231
- "type": "object",
232
- "properties": {
233
- "people": {
234
- "type": "array",
235
- "items": {
236
- "type": "object",
237
- "properties": {
238
- "name": {
239
- "type": "string",
240
- "description": "The person's full name"
241
- },
242
- "age": {
243
- "type": "integer",
244
- "description": "The person's age"
245
- },
246
- "occupation": {
247
- "type": "string",
248
- "description": "The person's job or profession"
249
- }
250
- },
251
- "required": ["name", "age", "occupation"],
252
- "additionalProperties": false
253
- }
254
- }
255
- },
256
- "required": ["people"],
257
- "additionalProperties": false
258
- }
259
- ```
241
+ 3. Default system prompt (built into the CLI)
260
242
 
261
- 3. Run the CLI:
243
+ ### Precedence Rules
262
244
 
263
- ```bash
264
- # Basic usage
265
- ostruct run extract_from_profiles.j2 schema.json -p profiles "profiles/*.txt"
245
+ When multiple system prompts are provided, they are resolved in this order:
266
246
 
267
- # With advanced options
268
- ostruct run extract_from_profiles.j2 schema.json \
269
- -p profiles "profiles/*.txt" \
270
- --model gpt-4o \
271
- --sys-prompt "Extract precise information about the person" \
272
- --temperature 0.5
273
- ```
247
+ 1. Command-line options take highest precedence:
248
+ - If both `--sys-prompt` and `--sys-file` are provided, `--sys-prompt` wins
249
+ - Use `--ignore-task-sysprompt` to ignore template frontmatter
274
250
 
275
- The command will output:
251
+ 2. Template frontmatter is used if:
252
+ - No command-line options are provided
253
+ - `--ignore-task-sysprompt` is not set
276
254
 
277
- ```json
278
- {
279
- "people": [
280
- {
281
- "name": "John Smith",
282
- "age": 35,
283
- "occupation": "software engineer"
284
- },
285
- {
286
- "name": "Jane Doe",
287
- "age": 28,
288
- "occupation": "data scientist"
289
- }
290
- ]
291
- }
292
- ```
293
-
294
- ### About Template Files
295
-
296
- Template files use the `.j2` extension to indicate they contain Jinja2 template syntax. This convention:
297
-
298
- - Enables proper syntax highlighting in most editors
299
- - Makes it clear the file contains template logic
300
- - Follows industry standards for Jinja2 templates
255
+ 3. Default system prompt is used only if no other prompts are provided
301
256
 
302
- ## CLI Options
303
-
304
- The CLI revolves around a single subcommand called `run`. Basic usage:
257
+ Example combining multiple sources:
305
258
 
306
259
  ```bash
307
- ostruct run <TASK_TEMPLATE> <SCHEMA_FILE> [OPTIONS]
308
- ```
309
-
310
- Common options include:
311
-
312
- - File & Directory Inputs:
313
- - `-f <NAME> <PATH>`: Map a single file to a variable name
314
- - `-d <NAME> <DIR>`: Map a directory to a variable name
315
- - `-p <NAME> <PATTERN>`: Map files matching a glob pattern to a variable name
316
- - `-R, --recursive`: Enable recursive directory/pattern scanning
260
+ # Command-line prompt will override template frontmatter
261
+ ostruct run template.j2 schema.json --sys-prompt "Override prompt"
317
262
 
318
- - Variables:
319
- - `-V name=value`: Define a simple string variable
320
- - `-J name='{"key":"value"}'`: Define a JSON variable
321
-
322
- - Model Parameters:
323
- - `-m, --model MODEL`: Select the OpenAI model (supported: gpt-4o, o1, o3-mini)
324
- - `--temperature FLOAT`: Set sampling temperature (0.0-2.0)
325
- - `--max-output-tokens INT`: Set maximum output tokens
326
- - `--top-p FLOAT`: Set top-p sampling parameter (0.0-1.0)
327
- - `--frequency-penalty FLOAT`: Adjust frequency penalty (-2.0-2.0)
328
- - `--presence-penalty FLOAT`: Adjust presence penalty (-2.0-2.0)
329
- - `--reasoning-effort [low|medium|high]`: Control model reasoning effort
330
-
331
- - System Prompt:
332
- - `--sys-prompt TEXT`: Provide system prompt directly
333
- - `--sys-file FILE`: Load system prompt from file
334
- - `--ignore-task-sysprompt`: Ignore system prompt in template frontmatter
335
-
336
- - API Configuration:
337
- - `--api-key KEY`: OpenAI API key (defaults to OPENAI_API_KEY env var)
338
- - `--timeout FLOAT`: API timeout in seconds (default: 60.0)
339
-
340
- ## Debug Options
341
-
342
- - `--debug-validation`: Show detailed schema validation debugging
343
- - `--debug-openai-stream`: Enable low-level debug output for OpenAI streaming
344
- - `--progress-level {none,basic,detailed}`: Set progress reporting level
345
- - `none`: No progress indicators
346
- - `basic`: Show key operation steps (default)
347
- - `detailed`: Show all steps with additional info
348
- - `--show-model-schema`: Display the generated Pydantic model schema
349
- - `--verbose`: Enable verbose logging
350
- - `--dry-run`: Validate and render template without making API calls
351
- - `--no-progress`: Disable all progress indicators
352
-
353
- All debug and error logs are written to:
354
-
355
- - `~/.ostruct/logs/ostruct.log`: General application logs
356
- - `~/.ostruct/logs/openai_stream.log`: OpenAI streaming operations logs
357
-
358
- For more detailed documentation and examples, visit our [documentation](https://ostruct.readthedocs.io/).
359
-
360
- ## Development
361
-
362
- To contribute or report issues, please visit our [GitHub repository](https://github.com/yaniv-golan/ostruct).
363
-
364
- ## Development Setup
365
-
366
- 1. Clone the repository:
367
-
368
- ```bash
369
- git clone https://github.com/yanivgolan/ostruct.git
370
- cd ostruct
371
- ```
372
-
373
- 2. Install Poetry if you haven't already:
374
-
375
- ```bash
376
- curl -sSL https://install.python-poetry.org | python3 -
377
- ```
378
-
379
- 3. Install dependencies:
380
-
381
- ```bash
382
- poetry install
383
- ```
384
-
385
- 4. Install openai-structured in editable mode:
386
-
387
- ```bash
388
- poetry add --editable ../openai-structured # Adjust path as needed
263
+ # Ignore template frontmatter and use default
264
+ ostruct run template.j2 schema.json --ignore-task-sysprompt
389
265
  ```
390
266
 
391
- 5. Run tests:
392
-
393
- ```bash
394
- poetry run pytest
395
- ```
396
-
397
- ## Contributing
398
-
399
- Contributions are welcome! Please feel free to submit a Pull Request.
400
-
401
- ## License
402
-
403
- This project is licensed under the MIT License - see the LICENSE file for details.
404
-
@@ -0,0 +1,238 @@
1
+ # ostruct-cli
2
+
3
+ [![PyPI version](https://badge.fury.io/py/ostruct-cli.svg)](https://badge.fury.io/py/ostruct-cli)
4
+ [![Python Versions](https://img.shields.io/pypi/pyversions/ostruct-cli.svg)](https://pypi.org/project/ostruct-cli)
5
+ [![Documentation Status](https://readthedocs.org/projects/ostruct/badge/?version=latest)](https://ostruct.readthedocs.io/en/latest/?badge=latest)
6
+ [![CI](https://github.com/yaniv-golan/ostruct/actions/workflows/ci.yml/badge.svg)](https://github.com/yaniv-golan/ostruct/actions/workflows/ci.yml)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ ostruct tranforms unstructured inputs into structured, usable JSON output using OpenAI APIs.
10
+
11
+ ostruct will process a set of plain text files (data, source code, CSV, etc), input variables, a dynamic prompt template, and a JSON schema specifying the desired output format, and will produce the result in JSON format.
12
+
13
+ ## Features
14
+
15
+ - Generate structured JSON output from natural language using OpenAI models and a JSON schema
16
+ - Rich template system for defining prompts (Jinja2-based)
17
+ - Automatic token counting and context window management
18
+ - Streaming support for real-time output
19
+ - Secure handling of sensitive data
20
+
21
+ ## Requirements
22
+
23
+ - Python 3.10 or higher
24
+
25
+ ## Installation
26
+
27
+ ### For Users
28
+
29
+ To install the latest stable version from PyPI:
30
+
31
+ ```bash
32
+ pip install ostruct-cli
33
+ ```
34
+
35
+ ### For Developers
36
+
37
+ If you plan to contribute to the project, see the [Development Setup](#development-setup) section below for instructions on setting up the development environment with Poetry.
38
+
39
+ ## Shell Completion
40
+
41
+ ostruct-cli supports shell completion for Bash, Zsh, and Fish shells. To enable it:
42
+
43
+ ### Bash
44
+
45
+ Add this to your `~/.bashrc`:
46
+
47
+ ```bash
48
+ eval "$(_OSTRUCT_COMPLETE=bash_source ostruct)"
49
+ ```
50
+
51
+ ### Zsh
52
+
53
+ Add this to your `~/.zshrc`:
54
+
55
+ ```bash
56
+ eval "$(_OSTRUCT_COMPLETE=zsh_source ostruct)"
57
+ ```
58
+
59
+ ### Fish
60
+
61
+ Add this to your `~/.config/fish/completions/ostruct.fish`:
62
+
63
+ ```fish
64
+ eval (env _OSTRUCT_COMPLETE=fish_source ostruct)
65
+ ```
66
+
67
+ After adding the appropriate line, restart your shell or source the configuration file.
68
+ Shell completion will help you with:
69
+
70
+ - Command options and their arguments
71
+ - File paths for template and schema files
72
+ - Directory paths for `-d` and `--base-dir` options
73
+ - And more!
74
+
75
+ ## Quick Start
76
+
77
+ 1. Set your OpenAI API key:
78
+
79
+ ```bash
80
+ export OPENAI_API_KEY=your-api-key
81
+ ```
82
+
83
+ ### Example 1: Using stdin (Simplest)
84
+
85
+ 1. Create a template file `extract_person.j2`:
86
+
87
+ ```jinja
88
+ Extract information about the person from this text: {{ stdin }}
89
+ ```
90
+
91
+ 2. Create a schema file `schema.json`:
92
+
93
+ ```json
94
+ {
95
+ "type": "object",
96
+ "properties": {
97
+ "person": {
98
+ "type": "object",
99
+ "properties": {
100
+ "name": {
101
+ "type": "string",
102
+ "description": "The person's full name"
103
+ },
104
+ "age": {
105
+ "type": "integer",
106
+ "description": "The person's age"
107
+ },
108
+ "occupation": {
109
+ "type": "string",
110
+ "description": "The person's job or profession"
111
+ }
112
+ },
113
+ "required": ["name", "age", "occupation"],
114
+ "additionalProperties": false
115
+ }
116
+ },
117
+ "required": ["person"],
118
+ "additionalProperties": false
119
+ }
120
+ ```
121
+
122
+ 3. Run the CLI:
123
+
124
+ ```bash
125
+ # Basic usage
126
+ echo "John Smith is a 35-year-old software engineer" | ostruct run extract_person.j2 schema.json
127
+
128
+ # For longer text using heredoc
129
+ cat << EOF | ostruct run extract_person.j2 schema.json
130
+ John Smith is a 35-year-old software engineer
131
+ working at Tech Corp. He has been programming
132
+ for over 10 years.
133
+ EOF
134
+
135
+ # With advanced options
136
+ echo "John Smith is a 35-year-old software engineer" | \
137
+ ostruct run extract_person.j2 schema.json \
138
+ --model gpt-4o \
139
+ --sys-prompt "Extract precise information about the person" \
140
+ --temperature 0.7
141
+ ```
142
+
143
+ The command will output:
144
+
145
+ ```json
146
+ {
147
+ "person": {
148
+ "name": "John Smith",
149
+ "age": 35,
150
+ "occupation": "software engineer"
151
+ }
152
+ }
153
+ ```
154
+
155
+ ### Example 2: Processing a Single File
156
+
157
+ 1. Create a template file `extract_from_file.j2`:
158
+
159
+ ```jinja
160
+ Extract information about the person from this text: {{ text.content }}
161
+ ```
162
+
163
+ 2. Use the same schema file `schema.json` as above.
164
+
165
+ 3. Run the CLI:
166
+
167
+ ```bash
168
+ # Basic usage
169
+ ostruct run extract_from_file.j2 schema.json -f text input.txt
170
+
171
+ # With advanced options
172
+ ostruct run extract_from_file.j2 schema.json \
173
+ -f text input.txt \
174
+ --model gpt-4o \
175
+ --max-output-tokens 1000 \
176
+ --temperature 0.7
177
+ ```
178
+
179
+ The command will output:
180
+
181
+ ```json
182
+ {
183
+ "person": {
184
+ "name": "John Smith",
185
+ "age": 35,
186
+ "occupation": "software engineer"
187
+ }
188
+ }
189
+ ```
190
+
191
+ ## System Prompt Handling
192
+
193
+ ostruct-cli provides three ways to specify a system prompt, with a clear precedence order:
194
+
195
+ 1. Command-line option (`--sys-prompt` or `--sys-file`):
196
+
197
+ ```bash
198
+ # Direct string
199
+ ostruct run template.j2 schema.json --sys-prompt "You are an expert analyst"
200
+
201
+ # From file
202
+ ostruct run template.j2 schema.json --sys-file system_prompt.txt
203
+ ```
204
+
205
+ 2. Template frontmatter:
206
+
207
+ ```jinja
208
+ ---
209
+ system_prompt: You are an expert analyst
210
+ ---
211
+ Extract information from: {{ text }}
212
+ ```
213
+
214
+ 3. Default system prompt (built into the CLI)
215
+
216
+ ### Precedence Rules
217
+
218
+ When multiple system prompts are provided, they are resolved in this order:
219
+
220
+ 1. Command-line options take highest precedence:
221
+ - If both `--sys-prompt` and `--sys-file` are provided, `--sys-prompt` wins
222
+ - Use `--ignore-task-sysprompt` to ignore template frontmatter
223
+
224
+ 2. Template frontmatter is used if:
225
+ - No command-line options are provided
226
+ - `--ignore-task-sysprompt` is not set
227
+
228
+ 3. Default system prompt is used only if no other prompts are provided
229
+
230
+ Example combining multiple sources:
231
+
232
+ ```bash
233
+ # Command-line prompt will override template frontmatter
234
+ ostruct run template.j2 schema.json --sys-prompt "Override prompt"
235
+
236
+ # Ignore template frontmatter and use default
237
+ ostruct run template.j2 schema.json --ignore-task-sysprompt
238
+ ```
@@ -4,7 +4,7 @@
4
4
 
5
5
  [tool.poetry]
6
6
  name = "ostruct-cli"
7
- version = "0.6.1"
7
+ version = "0.6.2"
8
8
  description = "CLI for OpenAI Structured Output"
9
9
  authors = ["Yaniv Golan <yaniv@golan.name>"]
10
10
  readme = "README.md"