ostruct-cli 0.4.0__tar.gz → 0.6.0__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 (47) hide show
  1. ostruct_cli-0.6.0/PKG-INFO +404 -0
  2. ostruct_cli-0.6.0/README.md +376 -0
  3. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/pyproject.toml +25 -19
  4. ostruct_cli-0.6.0/src/ostruct/cli/base_errors.py +183 -0
  5. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/cli.py +879 -592
  6. ostruct_cli-0.6.0/src/ostruct/cli/click_options.py +375 -0
  7. ostruct_cli-0.6.0/src/ostruct/cli/errors.py +519 -0
  8. ostruct_cli-0.6.0/src/ostruct/cli/exit_codes.py +18 -0
  9. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/file_info.py +30 -14
  10. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/file_list.py +4 -10
  11. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/file_utils.py +43 -35
  12. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/path_utils.py +32 -4
  13. ostruct_cli-0.6.0/src/ostruct/cli/schema_validation.py +213 -0
  14. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/security/allowed_checker.py +8 -0
  15. ostruct_cli-0.6.0/src/ostruct/cli/security/base.py +46 -0
  16. ostruct_cli-0.6.0/src/ostruct/cli/security/errors.py +164 -0
  17. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/security/security_manager.py +22 -9
  18. ostruct_cli-0.6.0/src/ostruct/cli/serialization.py +25 -0
  19. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/template_filters.py +5 -3
  20. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/template_rendering.py +46 -22
  21. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/template_utils.py +12 -4
  22. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/template_validation.py +26 -8
  23. ostruct_cli-0.6.0/src/ostruct/cli/token_utils.py +43 -0
  24. ostruct_cli-0.6.0/src/ostruct/cli/validators.py +109 -0
  25. ostruct_cli-0.4.0/PKG-INFO +0 -186
  26. ostruct_cli-0.4.0/README.md +0 -157
  27. ostruct_cli-0.4.0/src/ostruct/cli/click_options.py +0 -257
  28. ostruct_cli-0.4.0/src/ostruct/cli/errors.py +0 -380
  29. ostruct_cli-0.4.0/src/ostruct/cli/security/errors.py +0 -184
  30. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/LICENSE +0 -0
  31. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/__init__.py +0 -0
  32. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/__init__.py +0 -0
  33. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/cache_manager.py +0 -0
  34. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/progress.py +0 -0
  35. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/security/__init__.py +0 -0
  36. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/security/case_manager.py +0 -0
  37. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/security/normalization.py +0 -0
  38. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/security/safe_joiner.py +0 -0
  39. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/security/symlink_resolver.py +0 -0
  40. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/security/types.py +0 -0
  41. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/security/windows_paths.py +0 -0
  42. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/template_env.py +0 -0
  43. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/template_extensions.py +0 -0
  44. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/template_io.py +0 -0
  45. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/template_schema.py +0 -0
  46. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/cli/utils.py +0 -0
  47. {ostruct_cli-0.4.0 → ostruct_cli-0.6.0}/src/ostruct/py.typed +0 -0
@@ -0,0 +1,404 @@
1
+ Metadata-Version: 2.3
2
+ Name: ostruct-cli
3
+ Version: 0.6.0
4
+ Summary: CLI for OpenAI Structured Output
5
+ Author: Yaniv Golan
6
+ Author-email: yaniv@golan.name
7
+ Requires-Python: >=3.10,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Requires-Dist: cachetools (>=5.3.2,<6.0.0)
14
+ Requires-Dist: chardet (>=5.0.0,<6.0.0)
15
+ Requires-Dist: click (>=8.1.7,<9.0.0)
16
+ Requires-Dist: ijson (>=3.2.3,<4.0.0)
17
+ Requires-Dist: jsonschema (>=4.23.0,<5.0.0)
18
+ Requires-Dist: openai (>=1.0.0,<2.0.0)
19
+ Requires-Dist: openai-structured (>=2.0.0,<3.0.0)
20
+ Requires-Dist: pydantic (>=2.6.3,<3.0.0)
21
+ Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
22
+ Requires-Dist: tiktoken (==0.9.0)
23
+ Requires-Dist: tomli (>=2.0.1,<3.0.0) ; python_version < "3.11"
24
+ Requires-Dist: typing-extensions (>=4.9.0,<5.0.0)
25
+ Requires-Dist: werkzeug (>=3.1.3,<4.0.0)
26
+ Description-Content-Type: text/markdown
27
+
28
+ # ostruct-cli
29
+
30
+ [![PyPI version](https://badge.fury.io/py/ostruct-cli.svg)](https://badge.fury.io/py/ostruct-cli)
31
+ [![Python Versions](https://img.shields.io/pypi/pyversions/ostruct-cli.svg)](https://pypi.org/project/ostruct-cli)
32
+ [![Documentation Status](https://readthedocs.org/projects/ostruct/badge/?version=latest)](https://ostruct.readthedocs.io/en/latest/?badge=latest)
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
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
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.
37
+
38
+ ## Features
39
+
40
+ - Generate structured JSON output from natural language using OpenAI models and a JSON schema
41
+ - Rich template system for defining prompts (Jinja2-based)
42
+ - Automatic token counting and context window management
43
+ - Streaming support for real-time output
44
+ - Secure handling of sensitive data
45
+
46
+ ## Installation
47
+
48
+ ### For Users
49
+
50
+ To install the latest stable version from PyPI:
51
+
52
+ ```bash
53
+ pip install ostruct-cli
54
+ ```
55
+
56
+ ### For Developers
57
+
58
+ 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.
59
+
60
+ ## Shell Completion
61
+
62
+ ostruct-cli supports shell completion for Bash, Zsh, and Fish shells. To enable it:
63
+
64
+ ### Bash
65
+
66
+ Add this to your `~/.bashrc`:
67
+
68
+ ```bash
69
+ eval "$(_OSTRUCT_COMPLETE=bash_source ostruct)"
70
+ ```
71
+
72
+ ### Zsh
73
+
74
+ Add this to your `~/.zshrc`:
75
+
76
+ ```bash
77
+ eval "$(_OSTRUCT_COMPLETE=zsh_source ostruct)"
78
+ ```
79
+
80
+ ### Fish
81
+
82
+ Add this to your `~/.config/fish/completions/ostruct.fish`:
83
+
84
+ ```fish
85
+ eval (env _OSTRUCT_COMPLETE=fish_source ostruct)
86
+ ```
87
+
88
+ After adding the appropriate line, restart your shell or source the configuration file.
89
+ Shell completion will help you with:
90
+
91
+ - Command options and their arguments
92
+ - File paths for template and schema files
93
+ - Directory paths for `-d` and `--base-dir` options
94
+ - And more!
95
+
96
+ ## Quick Start
97
+
98
+ 1. Set your OpenAI API key:
99
+
100
+ ```bash
101
+ export OPENAI_API_KEY=your-api-key
102
+ ```
103
+
104
+ ### Example 1: Using stdin (Simplest)
105
+
106
+ 1. Create a template file `extract_person.j2`:
107
+
108
+ ```jinja
109
+ Extract information about the person from this text: {{ stdin }}
110
+ ```
111
+
112
+ 2. Create a schema file `schema.json`:
113
+
114
+ ```json
115
+ {
116
+ "type": "object",
117
+ "properties": {
118
+ "person": {
119
+ "type": "object",
120
+ "properties": {
121
+ "name": {
122
+ "type": "string",
123
+ "description": "The person's full name"
124
+ },
125
+ "age": {
126
+ "type": "integer",
127
+ "description": "The person's age"
128
+ },
129
+ "occupation": {
130
+ "type": "string",
131
+ "description": "The person's job or profession"
132
+ }
133
+ },
134
+ "required": ["name", "age", "occupation"],
135
+ "additionalProperties": false
136
+ }
137
+ },
138
+ "required": ["person"],
139
+ "additionalProperties": false
140
+ }
141
+ ```
142
+
143
+ 3. Run the CLI:
144
+
145
+ ```bash
146
+ # Basic usage
147
+ echo "John Smith is a 35-year-old software engineer" | ostruct run extract_person.j2 schema.json
148
+
149
+ # For longer text using heredoc
150
+ cat << EOF | ostruct run extract_person.j2 schema.json
151
+ John Smith is a 35-year-old software engineer
152
+ working at Tech Corp. He has been programming
153
+ for over 10 years.
154
+ EOF
155
+
156
+ # With advanced options
157
+ echo "John Smith is a 35-year-old software engineer" | \
158
+ ostruct run extract_person.j2 schema.json \
159
+ --model gpt-4o \
160
+ --sys-prompt "Extract precise information about the person" \
161
+ --temperature 0.7
162
+ ```
163
+
164
+ The command will output:
165
+
166
+ ```json
167
+ {
168
+ "person": {
169
+ "name": "John Smith",
170
+ "age": 35,
171
+ "occupation": "software engineer"
172
+ }
173
+ }
174
+ ```
175
+
176
+ ### Example 2: Processing a Single File
177
+
178
+ 1. Create a template file `extract_from_file.j2`:
179
+
180
+ ```jinja
181
+ Extract information about the person from this text: {{ text.content }}
182
+ ```
183
+
184
+ 2. Use the same schema file `schema.json` as above.
185
+
186
+ 3. Run the CLI:
187
+
188
+ ```bash
189
+ # Basic usage
190
+ ostruct run extract_from_file.j2 schema.json -f text input.txt
191
+
192
+ # With advanced options
193
+ ostruct run extract_from_file.j2 schema.json \
194
+ -f text input.txt \
195
+ --model gpt-4o \
196
+ --max-output-tokens 1000 \
197
+ --temperature 0.7
198
+ ```
199
+
200
+ The command will output:
201
+
202
+ ```json
203
+ {
204
+ "person": {
205
+ "name": "John Smith",
206
+ "age": 35,
207
+ "occupation": "software engineer"
208
+ }
209
+ }
210
+ ```
211
+
212
+ ### Example 3: Processing Multiple Files
213
+
214
+ 1. Create a template file `extract_from_profiles.j2`:
215
+
216
+ ```jinja
217
+ Extract information about the people from this data:
218
+
219
+ {% for profile in profiles %}
220
+ == {{ profile.name }}
221
+
222
+ {{ profile.content }}
223
+
224
+ {% endfor %}
225
+ ```
226
+
227
+ 2. Use the same schema file `schema.json` as above, but updated for multiple people:
228
+
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
+ ```
260
+
261
+ 3. Run the CLI:
262
+
263
+ ```bash
264
+ # Basic usage
265
+ ostruct run extract_from_profiles.j2 schema.json -p profiles "profiles/*.txt"
266
+
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
+ ```
274
+
275
+ The command will output:
276
+
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
301
+
302
+ ## CLI Options
303
+
304
+ The CLI revolves around a single subcommand called `run`. Basic usage:
305
+
306
+ ```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
317
+
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
389
+ ```
390
+
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
+