prompture 0.0.29.dev8__py3-none-any.whl → 0.0.38.dev2__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.
Files changed (79) hide show
  1. prompture/__init__.py +264 -23
  2. prompture/_version.py +34 -0
  3. prompture/agent.py +924 -0
  4. prompture/agent_types.py +156 -0
  5. prompture/aio/__init__.py +74 -0
  6. prompture/async_agent.py +880 -0
  7. prompture/async_conversation.py +789 -0
  8. prompture/async_core.py +803 -0
  9. prompture/async_driver.py +193 -0
  10. prompture/async_groups.py +551 -0
  11. prompture/cache.py +469 -0
  12. prompture/callbacks.py +55 -0
  13. prompture/cli.py +63 -4
  14. prompture/conversation.py +826 -0
  15. prompture/core.py +894 -263
  16. prompture/cost_mixin.py +51 -0
  17. prompture/discovery.py +187 -0
  18. prompture/driver.py +206 -5
  19. prompture/drivers/__init__.py +175 -67
  20. prompture/drivers/airllm_driver.py +109 -0
  21. prompture/drivers/async_airllm_driver.py +26 -0
  22. prompture/drivers/async_azure_driver.py +123 -0
  23. prompture/drivers/async_claude_driver.py +113 -0
  24. prompture/drivers/async_google_driver.py +316 -0
  25. prompture/drivers/async_grok_driver.py +97 -0
  26. prompture/drivers/async_groq_driver.py +90 -0
  27. prompture/drivers/async_hugging_driver.py +61 -0
  28. prompture/drivers/async_lmstudio_driver.py +148 -0
  29. prompture/drivers/async_local_http_driver.py +44 -0
  30. prompture/drivers/async_ollama_driver.py +135 -0
  31. prompture/drivers/async_openai_driver.py +102 -0
  32. prompture/drivers/async_openrouter_driver.py +102 -0
  33. prompture/drivers/async_registry.py +133 -0
  34. prompture/drivers/azure_driver.py +42 -9
  35. prompture/drivers/claude_driver.py +257 -34
  36. prompture/drivers/google_driver.py +295 -42
  37. prompture/drivers/grok_driver.py +35 -32
  38. prompture/drivers/groq_driver.py +33 -26
  39. prompture/drivers/hugging_driver.py +6 -6
  40. prompture/drivers/lmstudio_driver.py +97 -19
  41. prompture/drivers/local_http_driver.py +6 -6
  42. prompture/drivers/ollama_driver.py +168 -23
  43. prompture/drivers/openai_driver.py +184 -9
  44. prompture/drivers/openrouter_driver.py +37 -25
  45. prompture/drivers/registry.py +306 -0
  46. prompture/drivers/vision_helpers.py +153 -0
  47. prompture/field_definitions.py +106 -96
  48. prompture/group_types.py +147 -0
  49. prompture/groups.py +530 -0
  50. prompture/image.py +180 -0
  51. prompture/logging.py +80 -0
  52. prompture/model_rates.py +217 -0
  53. prompture/persistence.py +254 -0
  54. prompture/persona.py +482 -0
  55. prompture/runner.py +49 -47
  56. prompture/scaffold/__init__.py +1 -0
  57. prompture/scaffold/generator.py +84 -0
  58. prompture/scaffold/templates/Dockerfile.j2 +12 -0
  59. prompture/scaffold/templates/README.md.j2 +41 -0
  60. prompture/scaffold/templates/config.py.j2 +21 -0
  61. prompture/scaffold/templates/env.example.j2 +8 -0
  62. prompture/scaffold/templates/main.py.j2 +86 -0
  63. prompture/scaffold/templates/models.py.j2 +40 -0
  64. prompture/scaffold/templates/requirements.txt.j2 +5 -0
  65. prompture/serialization.py +218 -0
  66. prompture/server.py +183 -0
  67. prompture/session.py +117 -0
  68. prompture/settings.py +19 -1
  69. prompture/tools.py +219 -267
  70. prompture/tools_schema.py +254 -0
  71. prompture/validator.py +3 -3
  72. prompture-0.0.38.dev2.dist-info/METADATA +369 -0
  73. prompture-0.0.38.dev2.dist-info/RECORD +77 -0
  74. {prompture-0.0.29.dev8.dist-info → prompture-0.0.38.dev2.dist-info}/WHEEL +1 -1
  75. prompture-0.0.29.dev8.dist-info/METADATA +0 -368
  76. prompture-0.0.29.dev8.dist-info/RECORD +0 -27
  77. {prompture-0.0.29.dev8.dist-info → prompture-0.0.38.dev2.dist-info}/entry_points.txt +0 -0
  78. {prompture-0.0.29.dev8.dist-info → prompture-0.0.38.dev2.dist-info}/licenses/LICENSE +0 -0
  79. {prompture-0.0.29.dev8.dist-info → prompture-0.0.38.dev2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,77 @@
1
+ prompture/__init__.py,sha256=RrpHZlLPpzntUOp2tL2II2DdVxQRoCxY6JBF_b4k3s0,7213
2
+ prompture/_version.py,sha256=bWLaHigPR3CFjLRNxPpiOJ7bfcPJjU-AII8xRG2CiZQ,719
3
+ prompture/agent.py,sha256=xe_yFHGDzTxaU4tmaLt5AQnzrN0I72hBGwGVrCxg2D0,34704
4
+ prompture/agent_types.py,sha256=Icl16PQI-ThGLMFCU43adtQA6cqETbsPn4KssKBI4xc,4664
5
+ prompture/async_agent.py,sha256=nOLOQCNkg0sKKTpryIiidmIcAAlA3FR2NfnZwrNBuCg,33066
6
+ prompture/async_conversation.py,sha256=7NOkXdT5LnUNPVzTammtHeiOV2vB6IfZGuysbtNfcHQ,30861
7
+ prompture/async_core.py,sha256=s8G0nGUGR1Bf_BQG9_FcQRpveSnJKkEwcWNfbAJaSkg,29208
8
+ prompture/async_driver.py,sha256=99WZNlfEpPH9kVykRH6Qa2ZooeVw6pXa23_UUQj0Tag,7179
9
+ prompture/async_groups.py,sha256=8B383EF_qI9NzcG9zljLKjIZ_37bpNivvsmfJQoOGRk,19894
10
+ prompture/cache.py,sha256=4dfQDMsEZ9JMQDXLOkiugPmmMJQIfKVE8rTAKDH4oL8,14401
11
+ prompture/callbacks.py,sha256=JPDqWGzPIzv44l54ocmezlYVBnbKPDEEXRrLdluWGAo,1731
12
+ prompture/cli.py,sha256=tNiIddRmgC1BomjY5O1VVVAwvqHVzF8IHmQrM-cG2wQ,2902
13
+ prompture/conversation.py,sha256=jPwp5m5ZYqLHvD3zYVWJEnegnGPgexVZanZeGVOWrjE,32462
14
+ prompture/core.py,sha256=ZCKhqXI7msI-r4zy_Y_Lx8Sz--OJ6qb4b6jchdb5Boo,56671
15
+ prompture/cost_mixin.py,sha256=_spz84i8Qsplh6V3GkWyXXSUE4EwGy2IsbcsU2LEBxs,1918
16
+ prompture/discovery.py,sha256=T0GbiTSrCnvAEMzQiLj6ZI-sYBOQgcnLtwtlLSkIb3Q,8228
17
+ prompture/driver.py,sha256=2yVGw8vE5xko7HQlP6HfJKFyJLfc8cffdXwmdp5o3Uo,9008
18
+ prompture/field_definitions.py,sha256=PLvxq2ot-ngJ8JbWkkZ-XLtM1wvjUQ3TL01vSEo-a6E,21368
19
+ prompture/group_types.py,sha256=BxeFV1tI4PTH3xPOie7q3-35ivkTdB9lJUPLH0kPH7A,4731
20
+ prompture/groups.py,sha256=q9lpD57VWw6iQgK9S0nLVidItJZmusJkmpblM4EX9Sc,18349
21
+ prompture/image.py,sha256=3uBxC6blXRNyY5KAJ5MkG6ow8KGAslX8WxM8Is8S8cw,5620
22
+ prompture/logging.py,sha256=SkFO26_56Zai05vW8kTq3jvJudfLG2ipI5qNHaXKH3g,2574
23
+ prompture/model_rates.py,sha256=qtZUjsCVskA9LyG73JklG_kjKJHABA6ldBmBX0UzlSQ,6415
24
+ prompture/persistence.py,sha256=stcsH9Onth3BlK0QTWDKtXFp3FBmwUS5PI5R1glsIQc,9293
25
+ prompture/persona.py,sha256=SpLW-XPdG0avvJx8uGqJvMRZy65OjzfmJck7qbd28gc,17526
26
+ prompture/runner.py,sha256=lHe2L2jqY1pDXoKNPJALN9lAm-Q8QOY8C8gw-vM9VrM,4213
27
+ prompture/serialization.py,sha256=m4cdAQJspitMcfwRgecElkY2SBt3BjEwubbhS3W-0s0,7433
28
+ prompture/server.py,sha256=W6Kn6Et8nG5twXjD2wKn_N9yplGjz5Z-2naeI_UPd1Y,6198
29
+ prompture/session.py,sha256=FldK3cKq_jO0-beukVOhIiwsYWb6U_lLBlAERx95aaM,3821
30
+ prompture/settings.py,sha256=ADtYS8N5XYILI4TXrYTDOQo3pkDNSEVgn9ab4oMHkO4,2019
31
+ prompture/tools.py,sha256=PmFbGHTWYWahpJOG6BLlM0Y-EG6S37IFW57C-8GdsXo,36449
32
+ prompture/tools_schema.py,sha256=JVc0dxC4aIHIUlgE8yFCcn1gPzJ3unTMVmZ8Ec04aD0,7764
33
+ prompture/validator.py,sha256=FY_VjIVEbjG2nwzh-r6l23Kt3UzaLyCis8_pZMNGHBA,993
34
+ prompture/aio/__init__.py,sha256=bKqTu4Jxld16aP_7SP9wU5au45UBIb041ORo4E4HzVo,1810
35
+ prompture/drivers/__init__.py,sha256=VuEBZPqaQzXLl_Lvn_c5mRlJJrrlObZCLeHaR8n2eJ4,7050
36
+ prompture/drivers/airllm_driver.py,sha256=SaTh7e7Plvuct_TfRqQvsJsKHvvM_3iVqhBtlciM-Kw,3858
37
+ prompture/drivers/async_airllm_driver.py,sha256=1hIWLXfyyIg9tXaOE22tLJvFyNwHnOi1M5BIKnV8ysk,908
38
+ prompture/drivers/async_azure_driver.py,sha256=Rqq_5Utgr-lvxMHwlU0B5lwCTtqDhuUW212G9k8P0fQ,4463
39
+ prompture/drivers/async_claude_driver.py,sha256=yB5QLbXD7Uqs4j45yulj73QSJJx1-IyIo84YGA1xjkw,4092
40
+ prompture/drivers/async_google_driver.py,sha256=MIemYcE0ppSWfvVaxv4V-Tqjmy6BKO7sRG6UfZqtdV8,13349
41
+ prompture/drivers/async_grok_driver.py,sha256=bblcUY5c5NJ_IeuFQ-jHRapGi_WywVgH6SSWWWbUMzo,3546
42
+ prompture/drivers/async_groq_driver.py,sha256=gHvVe4M5VaRcyvonK9FQMLmCuL7i7HV9hwWcRgASUSg,3075
43
+ prompture/drivers/async_hugging_driver.py,sha256=IblxqU6TpNUiigZ0BCgNkAgzpUr2FtPHJOZnOZMnHF0,2152
44
+ prompture/drivers/async_lmstudio_driver.py,sha256=rPn2qVPm6UE2APzAn7ZHYTELUwr0dQMi8XHv6gAhyH8,5782
45
+ prompture/drivers/async_local_http_driver.py,sha256=qoigIf-w3_c2dbVdM6m1e2RMAWP4Gk4VzVs5hM3lPvQ,1609
46
+ prompture/drivers/async_ollama_driver.py,sha256=FaSXtFXrgeVHIe0b90Vg6rGeSTWLpPnjaThh9Ai7qQo,5042
47
+ prompture/drivers/async_openai_driver.py,sha256=eLdVYQ8BUErQzVr4Ek1BZ75riMbHMz3ZPm6VQSTNFxk,3572
48
+ prompture/drivers/async_openrouter_driver.py,sha256=VcSYOeBhbzRbzorYh_7K58yWCXB4UO0d6MmpBLf-7lQ,3783
49
+ prompture/drivers/async_registry.py,sha256=syervbb7THneJ-NUVSuxy4cnxGW6VuNzKv-Aqqn2ysU,4329
50
+ prompture/drivers/azure_driver.py,sha256=QZr7HEvgSKT9LOTCtCjuBdHl57yvrnWmeTHtmewuJQY,5727
51
+ prompture/drivers/claude_driver.py,sha256=8XnCBHtk6N_PzHStwxIUlcvekdPN896BqOLShmgxU9k,11536
52
+ prompture/drivers/google_driver.py,sha256=8bnAcve1xtgpUXrCdVzWpU_yAqwaeuiBWk8-PbG1cmM,15956
53
+ prompture/drivers/grok_driver.py,sha256=AIwuzNAQyOhmVDA07ISWt2e-rsv5aYk3I5AM4HkLM7o,5294
54
+ prompture/drivers/groq_driver.py,sha256=9cZI21RsgYJTjnrtX2fVA0AadDL-VklhY4ugjDCutwM,4195
55
+ prompture/drivers/hugging_driver.py,sha256=gZir3XnM77VfYIdnu3S1pRftlZJM6G3L8bgGn5esg-Q,2346
56
+ prompture/drivers/lmstudio_driver.py,sha256=9ZnJ1l5LuWAjkH2WKfFjZprNMVIXoSC7qXDNDTxm-tA,6748
57
+ prompture/drivers/local_http_driver.py,sha256=QJgEf9kAmy8YZ5fb8FHnWuhoDoZYNd8at4jegzNVJH0,1658
58
+ prompture/drivers/ollama_driver.py,sha256=k9xeUwFp91OrDbjkbYI-F8CDFy5ew-zQ0btXqwbXXWM,10220
59
+ prompture/drivers/openai_driver.py,sha256=BykJ3Z16BaWREVnAGaTYFwK2ZCI2aGOjo2YdsR8m_6w,10164
60
+ prompture/drivers/openrouter_driver.py,sha256=OAVmvCQ1ZW1ApJHsXJa8i1Dst9EUsZAt6uEDqF9aIQw,5408
61
+ prompture/drivers/registry.py,sha256=Dg_5w9alnIPKhOnsR9Xspuf5T7roBGu0r_L2Cf-UhXs,9926
62
+ prompture/drivers/vision_helpers.py,sha256=l5iYXHJLR_vLFvqDPPPK1QqK7YPKh5GwocpbSyt0R04,5403
63
+ prompture/scaffold/__init__.py,sha256=aitUxBV0MpjC7Od3iG8WUzcC7tGPXSt3oMzUBX8UDwQ,60
64
+ prompture/scaffold/generator.py,sha256=5QTHdWEXB7ADqOttfU7NgoxuaofNQnObzzI7NIPWFgo,2387
65
+ prompture/scaffold/templates/Dockerfile.j2,sha256=ukox6eVzQMVw-hAaFmNRL5HTrXw2Z0RB6g-vvbMVeu8,207
66
+ prompture/scaffold/templates/README.md.j2,sha256=xFgKnEP_JmLiiwD1QahNWdyKC85smyhOiIBCmN2U3y0,935
67
+ prompture/scaffold/templates/config.py.j2,sha256=q1LOnLlGzgJHPQz5geZ2AvrB-DskkLzay_CSj26hthE,529
68
+ prompture/scaffold/templates/env.example.j2,sha256=eESKr1KWgyrczO6d-nwAhQwSpf_G-T6P9gmHMhR9Sqc,246
69
+ prompture/scaffold/templates/main.py.j2,sha256=TEgc5OvsZOEX0JthkSW1NI_yLwgoeVN_x97Ibg-vyWY,2632
70
+ prompture/scaffold/templates/models.py.j2,sha256=JrZ99GCVK6TKWapskVRSwCssGrTu5cGZ_r46fOhY2GE,858
71
+ prompture/scaffold/templates/requirements.txt.j2,sha256=m3S5fi1hq9KG9l_9j317rjwWww0a43WMKd8VnUWv2A4,102
72
+ prompture-0.0.38.dev2.dist-info/licenses/LICENSE,sha256=0HgDepH7aaHNFhHF-iXuW6_GqDfYPnVkjtiCAZ4yS8I,1060
73
+ prompture-0.0.38.dev2.dist-info/METADATA,sha256=i1eCc1nlA9if0421sJ044TcnFKcmOi3GAcBb2HuKZMc,10842
74
+ prompture-0.0.38.dev2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
75
+ prompture-0.0.38.dev2.dist-info/entry_points.txt,sha256=AFPG3lJR86g4IJMoWQUW5Ph7G6MLNWG3A2u2Tp9zkp8,48
76
+ prompture-0.0.38.dev2.dist-info/top_level.txt,sha256=to86zq_kjfdoLeAxQNr420UWqT0WzkKoZ509J7Qr2t4,10
77
+ prompture-0.0.38.dev2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,368 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: prompture
3
- Version: 0.0.29.dev8
4
- Summary: Ask LLMs to return structured JSON and run cross-model tests. API-first.
5
- Home-page: https://github.com/jhd3197/prompture
6
- Author: Juan Denis
7
- Author-email: juan@vene.co
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.9
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Requires-Dist: anthropic>=0.8.0
15
- Requires-Dist: click>=8.0
16
- Requires-Dist: google-generativeai>=0.3.0
17
- Requires-Dist: groq>=0.4.0
18
- Requires-Dist: httpx>=0.25.0
19
- Requires-Dist: jsonschema>=4.0
20
- Requires-Dist: openai>=1.0.0
21
- Requires-Dist: pydantic>=1.10
22
- Requires-Dist: pydantic-settings>=2.0
23
- Requires-Dist: python-dotenv>=0.19.0
24
- Requires-Dist: requests>=2.28
25
- Requires-Dist: python-dateutil>=2.9.0
26
- Requires-Dist: tukuy>=0.0.6
27
- Requires-Dist: pyyaml>=6.0
28
- Provides-Extra: test
29
- Requires-Dist: pytest>=7.0; extra == "test"
30
- Dynamic: author
31
- Dynamic: author-email
32
- Dynamic: classifier
33
- Dynamic: description
34
- Dynamic: description-content-type
35
- Dynamic: home-page
36
- Dynamic: license-file
37
- Dynamic: provides-extra
38
- Dynamic: requires-dist
39
- Dynamic: requires-python
40
- Dynamic: summary
41
-
42
- # Prompture
43
-
44
- [![PyPI version](https://badge.fury.io/py/prompture.svg)](https://badge.fury.io/py/prompture)
45
- [![Python Versions](https://img.shields.io/pypi/pyversions/prompture.svg)](https://pypi.org/project/prompture/)
46
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
47
- [![Downloads](https://static.pepy.tech/badge/prompture)](https://pepy.tech/project/prompture)
48
- ![GitHub Repo stars](https://img.shields.io/github/stars/jhd3197/prompture?style=social)
49
-
50
-
51
- **Prompture** is an API-first library for getting **structured JSON** (or any structure) from LLMs, validating it, and benchmarking multiple models with one spec.
52
-
53
- ## ✨ Features
54
-
55
- - ✅ **Structured output** → JSON schema enforcement, or direct **Pydantic** instances
56
- - ✅ **Stepwise extraction** → Per-field prompts, with smart type conversion (incl. shorthand numbers)
57
- - ✅ **Multi-driver** → OpenAI, Azure, Claude, Ollama, LM Studio, Google, Groq, OpenRouter, Grok, HTTP, Mock, HuggingFace (via `get_driver()`)
58
- - ✅ **Usage & cost** → Token + $ tracking on every call (`usage` from driver meta)
59
- - ✅ **AI cleanup** → Optional LLM pass to fix malformed JSON
60
- - ✅ **Batch testing** → Define suites and compare models (spec-driven)
61
-
62
- <br>
63
-
64
- > [!TIP]
65
- > Starring this repo helps more developers discover Prompture ✨
66
- >
67
- >![prompture_no_forks](https://github.com/user-attachments/assets/720f888e-a885-4eb3-970c-ba5809fe2ce7)
68
- >
69
- > 🔥 Also check out my other project [RepoGif](https://github.com/jhd3197/RepoGif) – the tool I used to generate the GIF above!
70
- <br>
71
-
72
-
73
- ---
74
-
75
- ## Installation
76
-
77
- ```bash
78
- pip install prompture
79
- ````
80
-
81
- ---
82
-
83
- ## Configure a Provider
84
-
85
- Model names now support provider prefixes (e.g., "ollama/llama3.1:8b"). The `get_driver_for_model()` function automatically selects the appropriate driver based on the provider prefix.
86
-
87
- You can configure providers either through environment variables or by using provider-prefixed model names:
88
-
89
- ```bash
90
- # Environment variable approach:
91
- export AI_PROVIDER=ollama # One of: ollama | openai | azure | claude | google | groq | openrouter | grok | lmstudio | http | huggingface
92
-
93
- # Only if the provider needs them:
94
- export OPENAI_API_KEY=...
95
- export AZURE_OPENAI_ENDPOINT=...
96
- export AZURE_OPENAI_API_KEY=...
97
- export ANTHROPIC_API_KEY=...
98
- export GOOGLE_API_KEY=...
99
- export GROQ_API_KEY=...
100
- export OPENROUTER_API_KEY=...
101
- export GROK_API_KEY=...
102
- export LMSTUDIO_ENDPOINT=...
103
- ```
104
-
105
- | Provider | Example models | Cost calc |
106
- | -------- | ------------------------------------- | --------------- |
107
- | `ollama` | `ollama/llama3.1:8b`, `ollama/qwen2.5:3b` | `$0.00` (local) |
108
- | `openai` | `openai/gpt-4`, `openai/gpt-3.5-turbo` | Automatic |
109
- | `azure` | `azure/deployed-name` | Automatic |
110
- | `claude` | `claude/claude-3` | Automatic |
111
- | `google` | `google/gemini-1.5-pro`, `google/gemini-1.5-flash` | Automatic |
112
- | `groq` | `groq/llama2-70b-4096`, `groq/mixtral-8x7b-32768` | Automatic |
113
- | `openrouter` | `openrouter/openai/gpt-3.5-turbo`, `openrouter/anthropic/claude-2` | Automatic |
114
- | `grok` | `grok/grok-4-fast-reasoning`, `grok/grok-3-mini` | Automatic |
115
- | `lmstudio` | `lmstudio/local-model` | `$0.00` (local) |
116
- | `huggingface` | `hf/local-or-endpoint` | `$0.00` (local) |
117
- | `http` | `http/self-hosted` | `$0.00` |
118
-
119
- ---
120
-
121
- ## Quickstart: Pydantic in one line (auto driver)
122
-
123
- Use `extract_with_model` for a single LLM call that fills your Pydantic model.
124
-
125
- ```python
126
- from typing import List, Optional
127
- from pydantic import BaseModel
128
- from prompture import extract_with_model
129
-
130
- class Person(BaseModel):
131
- name: str
132
- age: int
133
- profession: str
134
- city: str
135
- hobbies: List[str]
136
- education: Optional[str] = None
137
-
138
- text = "Maria is 32, a software developer in New York. She loves hiking and photography."
139
-
140
- # Uses get_driver_for_model() internally based on model name prefix
141
- person = extract_with_model(Person, text, model_name="ollama/gpt-oss:20b")
142
- print(person.dict())
143
- ```
144
-
145
- **Why start here?** It's fast (one call), cost-efficient, and returns a validated Pydantic instance.
146
-
147
- ---
148
-
149
- ## 📋 Field Definitions
150
-
151
- Prompture includes a powerful **field definitions system** that provides a centralized registry of structured data extraction fields. This system enables consistent, reusable field configurations across your data extraction workflows with built-in fields for common use cases like personal info, contact details, professional data, and more.
152
-
153
- **Key benefits:**
154
- - 🎯 Pre-configured fields with descriptions and extraction instructions
155
- - 🔄 Template variables like `{{current_year}}`, `{{current_date}}`, `{{current_datetime}}`
156
- - 🔌 Seamless Pydantic integration via `field_from_registry()`
157
- - ⚙️ Easy custom field registration
158
-
159
- ### Using Built-in Fields
160
-
161
- ```python
162
- from pydantic import BaseModel
163
- from prompture import field_from_registry, stepwise_extract_with_model
164
-
165
- class Person(BaseModel):
166
- name: str = field_from_registry("name")
167
- age: int = field_from_registry("age")
168
- email: str = field_from_registry("email")
169
- occupation: str = field_from_registry("occupation")
170
- company: str = field_from_registry("company")
171
-
172
- # Built-in fields include: name, age, email, phone, address, city, country,
173
- # occupation, company, education_level, salary, and many more!
174
-
175
- result = stepwise_extract_with_model(
176
- Person,
177
- "John Smith is 25 years old, software engineer at TechCorp, john@example.com",
178
- model_name="openai/gpt-4"
179
- )
180
- ```
181
-
182
- ### Registering Custom Fields
183
-
184
- ```python
185
- from prompture import register_field, field_from_registry
186
-
187
- # Register a custom field with template variables
188
- register_field("document_date", {
189
- "type": "str",
190
- "description": "Document creation or processing date",
191
- "instructions": "Use {{current_date}} if not specified in document",
192
- "default": "{{current_date}}",
193
- "nullable": False
194
- })
195
-
196
- # Use custom field in your model
197
- class Document(BaseModel):
198
- title: str = field_from_registry("name")
199
- created_date: str = field_from_registry("document_date")
200
- ```
201
-
202
- 📚 **[View Full Field Definitions Reference →](https://prompture.readthedocs.io/en/latest/field_definitions_reference.html)**
203
-
204
- ---
205
-
206
- ## JSON-first (low-level primitives)
207
-
208
- When you want raw JSON with a schema and full control, use `ask_for_json` or `extract_and_jsonify`.
209
-
210
- ```python
211
- from prompture.drivers import get_driver
212
- from prompture import ask_for_json, extract_and_jsonify
213
-
214
- schema = {
215
- "type": "object",
216
- "required": ["name", "age"],
217
- "properties": {
218
- "name": {"type": "string"},
219
- "age": {"type": "integer"}
220
- }
221
- }
222
-
223
- # 1) ask_for_json: you provide the full content prompt
224
- resp1 = ask_for_json(
225
- content_prompt="Extract the person's info from: John is 28 and lives in Miami.",
226
- json_schema=schema,
227
- model_name="google/gemini-1.5-pro"
228
- )
229
- print(resp1["json_object"], resp1["usage"])
230
-
231
- # 2) extract_and_jsonify: you provide text & an instruction template; it builds the prompt
232
- resp2 = extract_and_jsonify(
233
- text="John is 28 and lives in Miami.",
234
- json_schema=schema,
235
- model_name="groq/mixtral-8x7b-32768",
236
- instruction_template="Extract the person's information:"
237
- )
238
- print(resp2["json_object"], resp2["usage"])
239
- ```
240
-
241
- ### Return shape (JSON helpers)
242
-
243
- ```python
244
- {
245
- "json_string": str,
246
- "json_object": dict,
247
- "usage": {
248
- "prompt_tokens": int,
249
- "completion_tokens": int,
250
- "total_tokens": int,
251
- "cost": float,
252
- "model_name": str
253
- }
254
- }
255
- ```
256
-
257
- > If the model returns malformed JSON and `ai_cleanup=True`, a second LLM pass tries to fix it.
258
-
259
- ---
260
-
261
- ## Pydantic: one-shot vs stepwise
262
-
263
- Prompture supports two Pydantic extraction modes:
264
-
265
- * **`extract_with_model`** → Single call; global context; best cost/latency; coherent fields
266
- * **`stepwise_extract_with_model`** → One call per field; higher per-field accuracy; resilient
267
-
268
- | Aspect | `extract_with_model` (one-shot) | `stepwise_extract_with_model` (per-field) |
269
- | -------------- | -------------------------------------- | ----------------------------------------- |
270
- | LLM calls | 1 | N (one per field) |
271
- | Speed & cost | **Faster / cheaper** | Slower / higher |
272
- | Accuracy | Good global coherence | **Higher per-field accuracy** |
273
- | Error handling | All-or-nothing | **Per-field recovery** |
274
- | Best when | Fields are related; throughput matters | Correctness per field is critical |
275
-
276
- ### Examples
277
-
278
- ```python
279
- from prompture import extract_with_model, stepwise_extract_with_model
280
-
281
- person1 = extract_with_model(Person, text, model_name="openrouter/anthropic/claude-2")
282
- print(person1.dict())
283
-
284
- res = stepwise_extract_with_model(Person, text, model_name="grok/grok-4-fast-reasoning")
285
- print(res["model"].dict())
286
- print(res["usage"]) # includes per-field usage and totals
287
- ```
288
-
289
- **Stepwise extras:** internally uses `tools.create_field_schema` + `tools.convert_value` (with `allow_shorthand=True`) so values like `"3.4m"`, `"2k"`, `"1.2b"` can be converted to typed fields where appropriate.
290
-
291
- ---
292
-
293
- ## Manual control with logging
294
-
295
- `manual_extract_and_jsonify` is like `extract_and_jsonify` but adds structured debug logging.
296
-
297
- ```python
298
- from prompture import manual_extract_and_jsonify
299
- from prompture.drivers import get_driver
300
- from prompture.tools import LogLevel
301
-
302
- driver = get_driver("ollama")
303
- res = manual_extract_and_jsonify(
304
- driver=driver,
305
- text="Maria works as a software developer in New York.",
306
- json_schema={
307
- "type": "object",
308
- "required": ["city", "profession"],
309
- "properties": {"city": {"type": "string"}, "profession": {"type": "string"}}
310
- },
311
- model_name="llama3.1:8b",
312
- options={"temperature": 0.2},
313
- verbose_level=LogLevel.DEBUG # TRACE for full prompts/results
314
- )
315
- print(res["json_object"])
316
- ```
317
-
318
- ---
319
-
320
-
321
- **Example output (Ollama comparison)** — see `examples/ollama_models_comparison.py` for a richer comparison table.
322
-
323
- ---
324
-
325
-
326
- ## Ollama Model Comparison Example
327
-
328
- This example demonstrates how to compare different Ollama models using a specific script located at `examples/ollama_models_comparison.py`.
329
-
330
- | Model | Success | Prompt | Completion | Total | Fields | Validation | Name | Price | Variants | Screen Size | Warranty | Is New |
331
- |------------------|---------|--------|------------|-------|--------|------------|---------------------|----------|----------|-------------|----------|--------|
332
- | gpt-oss:20b | True | 801 | 945 | 1746 | 8 | ✓ | GalaxyFold Ultra | 1299.99 | 9 | 6.9 | 3 | True |
333
- | deepseek-r1:latest | True | 757 | 679 | 1436 | 8 | ✗ | GalaxyFold Ultra | 1299.99 | 3 | 6.9 | None | True |
334
- | llama3.1:8b | True | 746 | 256 | 1002 | 8 | ✓ | GalaxyFold Ultra | 1299.99 | 3 | 6.9 | 3 | True |
335
- | gemma3:latest | True | 857 | 315 | 1172 | 8 | ✗ | GalaxyFold Ultra | 1299.99 | 3 | 6.9 | None | True |
336
- | qwen2.5:1.5b | True | 784 | 236 | 1020 | 8 | ✓ | GalaxyFold Ultra | 1299.99 | 3 | 6.9 | 3 | True |
337
- | qwen2.5:3b | True | 784 | 273 | 1057 | 9 | ✓ | GalaxyFold Ultra | 1299.99 | 3 | 6.9 | 3 | True |
338
- | mistral:latest | True | 928 | 337 | 1265 | 8 | ✓ | GalaxyFold Ultra | 1299.99 | 3 | 6.9 | 3 | True |
339
-
340
- > **Successful models (7):** gpt-oss:20b, deepseek-r1:latest, llama3.1:8b, gemma3:latest, qwen2.5:1.5b, qwen2.5:3b, mistral:latest
341
-
342
- You can run this comparison yourself with:
343
- `python examples/ollama_models_comparison.py`
344
-
345
- This example script compares multiple Ollama models on a complex task of extracting structured information from a smartphone description using a detailed JSON schema. The purpose of this example is to illustrate how `Prompture` can be used to test and compare different models on the same structured output task, showing their success rates, token usage, and validation results.
346
-
347
- ---
348
-
349
- ## Error handling notes
350
-
351
- * With `ai_cleanup=True`, a second LLM pass attempts to fix malformed JSON; on success, `usage` may be a minimal stub.
352
- * `extract_and_jsonify` will **skip tests** under `pytest` if there’s a local server connection error (e.g., Ollama), instead of failing the suite.
353
- * All functions raise `ValueError` for empty text.
354
-
355
- ---
356
-
357
- ## Tips & Best Practices
358
-
359
- * Add `description` to schema fields (or Pydantic field metadata) for better extractions.
360
- * Start with **one-shot Pydantic**; switch specific fields to **stepwise** if they’re noisy.
361
- * Track usage/cost before scaling; tweak `temperature` in `options` if consistency wobbles.
362
- * Use `verbose_level=TRACE` in dev to see prompts/results and tighten your specs.
363
-
364
- ---
365
-
366
- ## Contributing
367
-
368
- PRs welcome! Add tests and—if adding drivers or patterns—drop an example under `examples/`.
@@ -1,27 +0,0 @@
1
- prompture/__init__.py,sha256=bZb1qaYkFU8nDXwNsUTwXyawK55lUhbw2EteimolZuk,1870
2
- prompture/cli.py,sha256=vA86GNjtKSHz8eRMl5YDaT9HHIWuhkeJtfx8jqTaqtM,809
3
- prompture/core.py,sha256=aqhYIRlt39awsiDP16gg3cCS_Fua3JhW3eFqWOnWoVQ,35962
4
- prompture/driver.py,sha256=w8pdXHujImIGF3ee8rkG8f6-UD0h2jLHhucSPInRrYI,989
5
- prompture/field_definitions.py,sha256=6kDMYNedccTK5l2L_I8_NI3_av-iYHqGPwkKDy8214c,21731
6
- prompture/runner.py,sha256=5xwal3iBQQj4_q7l3Rjr0e3RrUMJPaPDLiEchO0mmHo,4192
7
- prompture/settings.py,sha256=vHRkBAZNP6yRsI2Sm4FMa_FCw0Zxy2VX97ooiVYWvks,1500
8
- prompture/tools.py,sha256=yULrVyhyE-rQF7Mvwe4zNFbB-hSDGGSOr7mCVxM0I60,38965
9
- prompture/validator.py,sha256=oLzVsNveHuF-N_uOd11_uDa9Q5rFyo0wrk_l1N4zqDk,996
10
- prompture/drivers/__init__.py,sha256=IQ7DsWC_FP45h2CprWRhQ7lKi3-9ZO6CgweNX6IxTUA,3896
11
- prompture/drivers/azure_driver.py,sha256=GROhK3hqMfMurnEgpAawa1DPS-FhOU0YQcgy9SNGTzM,4622
12
- prompture/drivers/claude_driver.py,sha256=ZEHQNqNThLZ0p-WmGVuKiNyiudGYGP07xIzbgZhLY1g,3293
13
- prompture/drivers/google_driver.py,sha256=SOo02nJuNJiOE_pcGCo-LAmz7DA9pOazSOqI29K99zo,4771
14
- prompture/drivers/grok_driver.py,sha256=Xp6L75oL3dN8St8_m46C_5bM8FcaIdNKUASAt9kZ39w,5003
15
- prompture/drivers/groq_driver.py,sha256=91WGXP8G5dO0beuFO8FehZszlDC_X9hv_yPzQRGmcqw,3920
16
- prompture/drivers/hugging_driver.py,sha256=rngz7hIR7l-9M_xe4EjWPaBqdyPFHdQsqnDDy9gm5So,2357
17
- prompture/drivers/lmstudio_driver.py,sha256=Umy1kT211TAxxSPyQrtZnIGIZgqFeSV87FLTiPFF0CY,3455
18
- prompture/drivers/local_http_driver.py,sha256=S2diikvtQOQHF7fB07zU2X0QWkej4Of__rJgaU2C6FI,1669
19
- prompture/drivers/ollama_driver.py,sha256=fq_eFgwmCT3SK1D-ICHjxLjcm_An0suwkFIWC38xsS0,4681
20
- prompture/drivers/openai_driver.py,sha256=9q9OjQslquRFvIl1Hd9JVmFFFVh6OBIWrFulw1mkYWg,3976
21
- prompture/drivers/openrouter_driver.py,sha256=GKvLOFDhsyopH-k3iaD3VWllm7xbGuopRSA02MfCKoM,5031
22
- prompture-0.0.29.dev8.dist-info/licenses/LICENSE,sha256=0HgDepH7aaHNFhHF-iXuW6_GqDfYPnVkjtiCAZ4yS8I,1060
23
- prompture-0.0.29.dev8.dist-info/METADATA,sha256=zb5atZWplRLdhVAKLHHv3Mt0BLPFRZn--q7qFv_TnMs,14432
24
- prompture-0.0.29.dev8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
- prompture-0.0.29.dev8.dist-info/entry_points.txt,sha256=AFPG3lJR86g4IJMoWQUW5Ph7G6MLNWG3A2u2Tp9zkp8,48
26
- prompture-0.0.29.dev8.dist-info/top_level.txt,sha256=to86zq_kjfdoLeAxQNr420UWqT0WzkKoZ509J7Qr2t4,10
27
- prompture-0.0.29.dev8.dist-info/RECORD,,