instructor-ainative 0.1.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.
- instructor_ainative/__init__.py +30 -0
- instructor_ainative/client.py +118 -0
- instructor_ainative/models.py +55 -0
- instructor_ainative/provision.py +174 -0
- instructor_ainative-0.1.0.dist-info/METADATA +189 -0
- instructor_ainative-0.1.0.dist-info/RECORD +9 -0
- instructor_ainative-0.1.0.dist-info/WHEEL +5 -0
- instructor_ainative-0.1.0.dist-info/licenses/LICENSE +21 -0
- instructor_ainative-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""
|
|
2
|
+
instructor-ainative — Structured output extraction via AINative's free LLM API.
|
|
3
|
+
|
|
4
|
+
Pre-configured instructor client that connects to AINative's OpenAI-compatible
|
|
5
|
+
endpoint. Supports Llama, Qwen, and DeepSeek models with auto-provisioning.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
from instructor_ainative import get_client
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
|
|
11
|
+
class User(BaseModel):
|
|
12
|
+
name: str
|
|
13
|
+
age: int
|
|
14
|
+
|
|
15
|
+
client = get_client()
|
|
16
|
+
user = client.chat.completions.create(
|
|
17
|
+
model="meta-llama/Llama-3.3-70B-Instruct",
|
|
18
|
+
response_model=User,
|
|
19
|
+
messages=[{"role": "user", "content": "Extract: John is 30"}],
|
|
20
|
+
)
|
|
21
|
+
print(user) # User(name='John', age=30)
|
|
22
|
+
|
|
23
|
+
Refs #3950
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from instructor_ainative.client import get_client, get_async_client
|
|
27
|
+
from instructor_ainative.models import MODELS, get_model
|
|
28
|
+
|
|
29
|
+
__all__ = ["get_client", "get_async_client", "MODELS", "get_model"]
|
|
30
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""
|
|
2
|
+
instructor-ainative — Client Factory
|
|
3
|
+
|
|
4
|
+
Creates pre-configured instructor clients that connect to AINative's
|
|
5
|
+
OpenAI-compatible API for structured output extraction.
|
|
6
|
+
|
|
7
|
+
Refs #3950
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Optional
|
|
11
|
+
|
|
12
|
+
import instructor
|
|
13
|
+
from openai import OpenAI, AsyncOpenAI
|
|
14
|
+
|
|
15
|
+
from instructor_ainative.provision import resolve_api_key
|
|
16
|
+
|
|
17
|
+
BASE_URL = "https://api.ainative.studio/api/v1"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_client(
|
|
21
|
+
api_key: Optional[str] = None,
|
|
22
|
+
base_url: Optional[str] = None,
|
|
23
|
+
mode: instructor.Mode = instructor.Mode.JSON,
|
|
24
|
+
**kwargs,
|
|
25
|
+
) -> instructor.Instructor:
|
|
26
|
+
"""
|
|
27
|
+
Create a pre-configured instructor client for structured output extraction.
|
|
28
|
+
|
|
29
|
+
Uses AINative's free OpenAI-compatible API. If no API key is provided,
|
|
30
|
+
auto-provisions a free account.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
api_key: Explicit API key. Falls back to env vars, credentials file,
|
|
34
|
+
or auto-provisioning.
|
|
35
|
+
base_url: Override the API base URL. Defaults to AINative's endpoint.
|
|
36
|
+
mode: instructor mode for structured output. Defaults to JSON mode
|
|
37
|
+
which works best with open-source models.
|
|
38
|
+
**kwargs: Additional arguments passed to instructor.from_openai().
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
An instructor-patched OpenAI client ready for structured output.
|
|
42
|
+
|
|
43
|
+
Example:
|
|
44
|
+
from instructor_ainative import get_client
|
|
45
|
+
from pydantic import BaseModel
|
|
46
|
+
|
|
47
|
+
class User(BaseModel):
|
|
48
|
+
name: str
|
|
49
|
+
age: int
|
|
50
|
+
|
|
51
|
+
client = get_client()
|
|
52
|
+
user = client.chat.completions.create(
|
|
53
|
+
model="meta-llama/Llama-3.3-70B-Instruct",
|
|
54
|
+
response_model=User,
|
|
55
|
+
messages=[{"role": "user", "content": "Extract: John is 30"}],
|
|
56
|
+
)
|
|
57
|
+
"""
|
|
58
|
+
key = resolve_api_key(api_key)
|
|
59
|
+
base = base_url or BASE_URL
|
|
60
|
+
|
|
61
|
+
base_client = OpenAI(
|
|
62
|
+
api_key=key,
|
|
63
|
+
base_url=base,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
return instructor.from_openai(base_client, mode=mode, **kwargs)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_async_client(
|
|
70
|
+
api_key: Optional[str] = None,
|
|
71
|
+
base_url: Optional[str] = None,
|
|
72
|
+
mode: instructor.Mode = instructor.Mode.JSON,
|
|
73
|
+
**kwargs,
|
|
74
|
+
) -> instructor.AsyncInstructor:
|
|
75
|
+
"""
|
|
76
|
+
Create a pre-configured async instructor client for structured output extraction.
|
|
77
|
+
|
|
78
|
+
Same as get_client() but uses AsyncOpenAI for async/await usage.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
api_key: Explicit API key. Falls back to env vars, credentials file,
|
|
82
|
+
or auto-provisioning.
|
|
83
|
+
base_url: Override the API base URL. Defaults to AINative's endpoint.
|
|
84
|
+
mode: instructor mode for structured output. Defaults to JSON mode.
|
|
85
|
+
**kwargs: Additional arguments passed to instructor.from_openai().
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
An async instructor-patched OpenAI client.
|
|
89
|
+
|
|
90
|
+
Example:
|
|
91
|
+
import asyncio
|
|
92
|
+
from instructor_ainative import get_async_client
|
|
93
|
+
from pydantic import BaseModel
|
|
94
|
+
|
|
95
|
+
class User(BaseModel):
|
|
96
|
+
name: str
|
|
97
|
+
age: int
|
|
98
|
+
|
|
99
|
+
async def main():
|
|
100
|
+
client = get_async_client()
|
|
101
|
+
user = await client.chat.completions.create(
|
|
102
|
+
model="meta-llama/Llama-3.3-70B-Instruct",
|
|
103
|
+
response_model=User,
|
|
104
|
+
messages=[{"role": "user", "content": "Extract: John is 30"}],
|
|
105
|
+
)
|
|
106
|
+
print(user)
|
|
107
|
+
|
|
108
|
+
asyncio.run(main())
|
|
109
|
+
"""
|
|
110
|
+
key = resolve_api_key(api_key)
|
|
111
|
+
base = base_url or BASE_URL
|
|
112
|
+
|
|
113
|
+
base_client = AsyncOpenAI(
|
|
114
|
+
api_key=key,
|
|
115
|
+
base_url=base,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
return instructor.from_openai(base_client, mode=mode, **kwargs)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""
|
|
2
|
+
instructor-ainative — Supported Models
|
|
3
|
+
|
|
4
|
+
Model aliases and catalog for AINative's OpenAI-compatible endpoint.
|
|
5
|
+
All models support structured output extraction via instructor.
|
|
6
|
+
|
|
7
|
+
Refs #3950
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Optional
|
|
11
|
+
|
|
12
|
+
# Model aliases -> full model identifiers
|
|
13
|
+
MODELS = {
|
|
14
|
+
# Meta Llama
|
|
15
|
+
"llama": "meta-llama/Llama-3.3-70B-Instruct",
|
|
16
|
+
"llama-70b": "meta-llama/Llama-3.3-70B-Instruct",
|
|
17
|
+
"llama-8b": "meta-llama/Llama-3.1-8B-Instruct",
|
|
18
|
+
# Qwen
|
|
19
|
+
"qwen": "qwen3-coder-flash",
|
|
20
|
+
"qwen-coder": "qwen3-coder-flash",
|
|
21
|
+
# DeepSeek
|
|
22
|
+
"deepseek": "deepseek-4-flash",
|
|
23
|
+
"deepseek-flash": "deepseek-4-flash",
|
|
24
|
+
# Kimi
|
|
25
|
+
"kimi": "kimi-k2",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# Default model for get_client()
|
|
29
|
+
DEFAULT_MODEL = "meta-llama/Llama-3.3-70B-Instruct"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_model(alias: str) -> str:
|
|
33
|
+
"""
|
|
34
|
+
Resolve a model alias to its full identifier.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
alias: Short alias (e.g. "llama", "qwen") or full model ID.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Full model identifier string.
|
|
41
|
+
|
|
42
|
+
Examples:
|
|
43
|
+
>>> get_model("llama")
|
|
44
|
+
'meta-llama/Llama-3.3-70B-Instruct'
|
|
45
|
+
>>> get_model("qwen")
|
|
46
|
+
'qwen3-coder-flash'
|
|
47
|
+
>>> get_model("meta-llama/Llama-3.3-70B-Instruct")
|
|
48
|
+
'meta-llama/Llama-3.3-70B-Instruct'
|
|
49
|
+
"""
|
|
50
|
+
return MODELS.get(alias, alias)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def list_models() -> dict:
|
|
54
|
+
"""Return all available model aliases and their full identifiers."""
|
|
55
|
+
return dict(MODELS)
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"""
|
|
2
|
+
instructor-ainative — Auto-Provisioning
|
|
3
|
+
|
|
4
|
+
Zero-friction provisioning for instructor users.
|
|
5
|
+
On first use, if no API key is found, automatically provisions
|
|
6
|
+
a free AINative account (72-hour TTL) that can be claimed later.
|
|
7
|
+
|
|
8
|
+
Credential resolution order:
|
|
9
|
+
1. Explicit api_key parameter
|
|
10
|
+
2. AINATIVE_API_KEY environment variable
|
|
11
|
+
3. ZERODB_API_KEY environment variable (shared with zerodb ecosystem)
|
|
12
|
+
4. ~/.zerodb/credentials.json (shared credential store)
|
|
13
|
+
5. Auto-provision via /api/v1/public/instant-db
|
|
14
|
+
|
|
15
|
+
Refs #3950
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import os
|
|
20
|
+
import sys
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import Optional
|
|
24
|
+
|
|
25
|
+
import requests
|
|
26
|
+
|
|
27
|
+
ZERODB_DIR = Path.home() / ".zerodb"
|
|
28
|
+
CREDS_PATH = ZERODB_DIR / "credentials.json"
|
|
29
|
+
CONFIG_PATH = ZERODB_DIR / "config.json"
|
|
30
|
+
CLOUD_API_URL = "https://api.ainative.studio"
|
|
31
|
+
PROVISION_ENDPOINT = "/api/v1/public/instant-db"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def resolve_api_key(explicit_key: Optional[str] = None) -> str:
|
|
35
|
+
"""
|
|
36
|
+
Resolve an API key from all available sources.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
explicit_key: Key passed directly by the user.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
A valid API key string.
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
RuntimeError: If auto-provisioning fails and no key is available.
|
|
46
|
+
"""
|
|
47
|
+
# 1. Explicit parameter
|
|
48
|
+
if explicit_key:
|
|
49
|
+
return explicit_key
|
|
50
|
+
|
|
51
|
+
# 2. Environment variables
|
|
52
|
+
env_key = (
|
|
53
|
+
os.environ.get("AINATIVE_API_KEY")
|
|
54
|
+
or os.environ.get("ZERODB_API_KEY")
|
|
55
|
+
)
|
|
56
|
+
if env_key:
|
|
57
|
+
return env_key
|
|
58
|
+
|
|
59
|
+
# 3. Credentials file (shared with zerodb ecosystem)
|
|
60
|
+
creds = _load_credentials()
|
|
61
|
+
if creds:
|
|
62
|
+
return creds
|
|
63
|
+
|
|
64
|
+
# 4. Auto-provision
|
|
65
|
+
return _auto_provision()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _load_credentials() -> Optional[str]:
|
|
69
|
+
"""Load API key from ~/.zerodb/credentials.json."""
|
|
70
|
+
if CREDS_PATH.exists():
|
|
71
|
+
try:
|
|
72
|
+
data = json.loads(CREDS_PATH.read_text())
|
|
73
|
+
key = data.get("api_key")
|
|
74
|
+
if key:
|
|
75
|
+
return key
|
|
76
|
+
except (json.JSONDecodeError, KeyError):
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
if CONFIG_PATH.exists():
|
|
80
|
+
try:
|
|
81
|
+
data = json.loads(CONFIG_PATH.read_text())
|
|
82
|
+
key = data.get("api_key") or data.get("cloud_api_key")
|
|
83
|
+
if key:
|
|
84
|
+
return key
|
|
85
|
+
except (json.JSONDecodeError, KeyError):
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _auto_provision() -> str:
|
|
92
|
+
"""
|
|
93
|
+
Auto-provision a free AINative account for structured output extraction.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
API key string.
|
|
97
|
+
|
|
98
|
+
Raises:
|
|
99
|
+
RuntimeError: If provisioning fails.
|
|
100
|
+
"""
|
|
101
|
+
print(
|
|
102
|
+
"\n No API key found — provisioning a free AINative account for structured outputs...",
|
|
103
|
+
file=sys.stderr,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
resp = requests.post(
|
|
108
|
+
f"{CLOUD_API_URL}{PROVISION_ENDPOINT}",
|
|
109
|
+
json={"agree_terms": True, "source": "instructor-ainative"},
|
|
110
|
+
timeout=15,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
if resp.status_code == 429:
|
|
114
|
+
raise RuntimeError(
|
|
115
|
+
"Rate limited — too many provisions from this IP. "
|
|
116
|
+
"Sign up at https://ainative.studio/signup and set AINATIVE_API_KEY."
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
if resp.status_code not in (200, 201):
|
|
120
|
+
raise RuntimeError(
|
|
121
|
+
f"Provisioning failed (HTTP {resp.status_code}). "
|
|
122
|
+
"Sign up at https://ainative.studio/signup and set AINATIVE_API_KEY."
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
data = resp.json()
|
|
126
|
+
api_key = data.get("api_key", "")
|
|
127
|
+
if not api_key:
|
|
128
|
+
raise RuntimeError("Provisioning returned empty API key.")
|
|
129
|
+
|
|
130
|
+
_save_credentials(data)
|
|
131
|
+
_print_success(data)
|
|
132
|
+
return api_key
|
|
133
|
+
|
|
134
|
+
except requests.RequestException as exc:
|
|
135
|
+
raise RuntimeError(
|
|
136
|
+
f"Network error during provisioning: {exc}. "
|
|
137
|
+
"Set AINATIVE_API_KEY manually or sign up at https://ainative.studio/signup"
|
|
138
|
+
) from exc
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _save_credentials(data: dict) -> None:
|
|
142
|
+
"""Save provisioned credentials to ~/.zerodb/ for ecosystem sharing."""
|
|
143
|
+
ZERODB_DIR.mkdir(parents=True, exist_ok=True)
|
|
144
|
+
|
|
145
|
+
creds = {
|
|
146
|
+
"api_key": data.get("api_key", ""),
|
|
147
|
+
"project_id": data.get("project_id", ""),
|
|
148
|
+
"base_url": data.get("base_url", CLOUD_API_URL),
|
|
149
|
+
"expires_at": data.get("expires_at", ""),
|
|
150
|
+
"claim_url": data.get("claim_url", ""),
|
|
151
|
+
"provisioned_at": datetime.now(tz=None).isoformat(),
|
|
152
|
+
"source": "instructor-ainative",
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
CREDS_PATH.write_text(json.dumps(creds, indent=2) + "\n")
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def _print_success(data: dict) -> None:
|
|
159
|
+
"""Print success message with claim URL."""
|
|
160
|
+
expires = data.get("expires_at", "72 hours")
|
|
161
|
+
claim_url = data.get("claim_url", "https://ainative.studio/signup")
|
|
162
|
+
api_key = data.get("api_key", "")
|
|
163
|
+
|
|
164
|
+
print(
|
|
165
|
+
f"\n Auto-provisioned! Free structured output API ready.\n"
|
|
166
|
+
f"\n"
|
|
167
|
+
f" API Key: {api_key[:12]}...\n"
|
|
168
|
+
f" Expires: {expires}\n"
|
|
169
|
+
f" Saved to: ~/.zerodb/credentials.json\n"
|
|
170
|
+
f"\n"
|
|
171
|
+
f" To keep access permanently, claim your account:\n"
|
|
172
|
+
f" {claim_url}\n",
|
|
173
|
+
file=sys.stderr,
|
|
174
|
+
)
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: instructor-ainative
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Pre-configured instructor client for structured output extraction via AINative's free LLM API
|
|
5
|
+
Author-email: AINative Studio <dev@ainative.studio>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/AINative-Studio/instructor-ainative
|
|
8
|
+
Project-URL: Documentation, https://docs.ainative.studio/instructor
|
|
9
|
+
Project-URL: Repository, https://github.com/AINative-Studio/instructor-ainative
|
|
10
|
+
Project-URL: Issues, https://github.com/AINative-Studio/instructor-ainative/issues
|
|
11
|
+
Keywords: instructor,instructor-plugin,structured-output,pydantic,json-extraction,free-llm,ainative,zerodb,openai-compatible,llama,qwen,deepseek,auto-provisioning,claude,cursor,function-calling,schema-extraction,data-extraction,llm-structured,json-mode
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: instructor>=1.0.0
|
|
27
|
+
Requires-Dist: openai>=1.0.0
|
|
28
|
+
Requires-Dist: requests>=2.28
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
32
|
+
Requires-Dist: responses>=0.23; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# instructor-ainative
|
|
36
|
+
|
|
37
|
+
Pre-configured [instructor](https://github.com/jxnl/instructor) client for structured output extraction using AINative's free LLM API.
|
|
38
|
+
|
|
39
|
+
**Zero setup.** Works with Llama 3.3 70B, Qwen3, DeepSeek 4, and Kimi K2 — all free.
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install instructor-ainative
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Quick Start
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from instructor_ainative import get_client
|
|
51
|
+
from pydantic import BaseModel
|
|
52
|
+
|
|
53
|
+
class User(BaseModel):
|
|
54
|
+
name: str
|
|
55
|
+
age: int
|
|
56
|
+
|
|
57
|
+
client = get_client() # Auto-provisions free API key
|
|
58
|
+
user = client.chat.completions.create(
|
|
59
|
+
model="meta-llama/Llama-3.3-70B-Instruct",
|
|
60
|
+
response_model=User,
|
|
61
|
+
messages=[{"role": "user", "content": "Extract: John is 30"}],
|
|
62
|
+
)
|
|
63
|
+
print(user) # User(name='John', age=30)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## How It Works
|
|
67
|
+
|
|
68
|
+
`instructor-ainative` wraps [instructor](https://python.useinstructor.com/) with a pre-configured OpenAI client pointing at AINative's free, OpenAI-compatible API. You get structured Pydantic output extraction from open-source models without any API key setup.
|
|
69
|
+
|
|
70
|
+
On first use, the package auto-provisions a free API key (72-hour TTL). Claim your account at [ainative.studio/signup](https://ainative.studio/signup) for permanent access.
|
|
71
|
+
|
|
72
|
+
## Available Models
|
|
73
|
+
|
|
74
|
+
Use aliases or full model IDs:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from instructor_ainative import get_model, MODELS
|
|
78
|
+
|
|
79
|
+
# Aliases
|
|
80
|
+
get_model("llama") # meta-llama/Llama-3.3-70B-Instruct
|
|
81
|
+
get_model("qwen") # qwen3-coder-flash
|
|
82
|
+
get_model("deepseek") # deepseek-4-flash
|
|
83
|
+
get_model("kimi") # kimi-k2
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Async Support
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
import asyncio
|
|
90
|
+
from instructor_ainative import get_async_client
|
|
91
|
+
from pydantic import BaseModel
|
|
92
|
+
|
|
93
|
+
class User(BaseModel):
|
|
94
|
+
name: str
|
|
95
|
+
age: int
|
|
96
|
+
|
|
97
|
+
async def main():
|
|
98
|
+
client = get_async_client()
|
|
99
|
+
user = await client.chat.completions.create(
|
|
100
|
+
model="meta-llama/Llama-3.3-70B-Instruct",
|
|
101
|
+
response_model=User,
|
|
102
|
+
messages=[{"role": "user", "content": "Extract: John is 30"}],
|
|
103
|
+
)
|
|
104
|
+
print(user)
|
|
105
|
+
|
|
106
|
+
asyncio.run(main())
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Configuration
|
|
110
|
+
|
|
111
|
+
### API Key Resolution Order
|
|
112
|
+
|
|
113
|
+
1. Explicit `api_key` parameter
|
|
114
|
+
2. `AINATIVE_API_KEY` environment variable
|
|
115
|
+
3. `ZERODB_API_KEY` environment variable
|
|
116
|
+
4. `~/.zerodb/credentials.json` (shared with ZeroDB ecosystem)
|
|
117
|
+
5. Auto-provision (free, 72-hour TTL)
|
|
118
|
+
|
|
119
|
+
### Bring Your Own Key
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
export AINATIVE_API_KEY=your-key-here
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
# Or pass directly
|
|
127
|
+
client = get_client(api_key="your-key-here")
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Custom Base URL
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
client = get_client(base_url="https://your-proxy.example.com/v1")
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Instructor Mode
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
import instructor
|
|
140
|
+
client = get_client(mode=instructor.Mode.TOOLS) # Default is JSON mode
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Complex Extraction
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from instructor_ainative import get_client
|
|
147
|
+
from pydantic import BaseModel, Field
|
|
148
|
+
from typing import List
|
|
149
|
+
|
|
150
|
+
class Address(BaseModel):
|
|
151
|
+
street: str
|
|
152
|
+
city: str
|
|
153
|
+
state: str
|
|
154
|
+
zip_code: str = Field(description="5-digit ZIP code")
|
|
155
|
+
|
|
156
|
+
class Contact(BaseModel):
|
|
157
|
+
name: str
|
|
158
|
+
email: str
|
|
159
|
+
phone: str
|
|
160
|
+
addresses: List[Address]
|
|
161
|
+
|
|
162
|
+
client = get_client()
|
|
163
|
+
contact = client.chat.completions.create(
|
|
164
|
+
model="meta-llama/Llama-3.3-70B-Instruct",
|
|
165
|
+
response_model=Contact,
|
|
166
|
+
messages=[{
|
|
167
|
+
"role": "user",
|
|
168
|
+
"content": """
|
|
169
|
+
Extract contact info: Jane Smith, jane@example.com, 555-0123.
|
|
170
|
+
Lives at 123 Main St, Austin TX 78701 and
|
|
171
|
+
456 Oak Ave, Denver CO 80202.
|
|
172
|
+
"""
|
|
173
|
+
}],
|
|
174
|
+
)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Why instructor-ainative?
|
|
178
|
+
|
|
179
|
+
| Feature | instructor + OpenAI | instructor-ainative |
|
|
180
|
+
|---------|-------------------|-------------------|
|
|
181
|
+
| Setup | Get API key, set env var | `pip install` and go |
|
|
182
|
+
| Cost | Pay per token | Free |
|
|
183
|
+
| Models | GPT-4o, etc. | Llama 70B, Qwen, DeepSeek |
|
|
184
|
+
| Structured output | Yes | Yes |
|
|
185
|
+
| Auto-provisioning | No | Yes |
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
MIT
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
instructor_ainative/__init__.py,sha256=pqAVIQ_TuZrjkA50XFgSZFN2PKgP9nPmn3Sbuf7YOLY,900
|
|
2
|
+
instructor_ainative/client.py,sha256=aAV_eaNT9yjhSrXXDFGhA0KBp1Ywg_U7p-oiU_myWpg,3487
|
|
3
|
+
instructor_ainative/models.py,sha256=nmFSZSXfH5cd157pJVJp9RKCtXgZYpn2-VJ3MvH14KA,1395
|
|
4
|
+
instructor_ainative/provision.py,sha256=IEFBECQLAWvL8W2gyAQlvQyho6MMS_z0MuJL2ki5dhs,5033
|
|
5
|
+
instructor_ainative-0.1.0.dist-info/licenses/LICENSE,sha256=-3M2h1U80S6mPyiuvRG25A0l1xZGpa7eO43lysBIzBY,1072
|
|
6
|
+
instructor_ainative-0.1.0.dist-info/METADATA,sha256=soP4c5jCSqinvCickbLIbF2G89jvwkNllntKaekmgJI,5473
|
|
7
|
+
instructor_ainative-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
8
|
+
instructor_ainative-0.1.0.dist-info/top_level.txt,sha256=oUoo5v8osWDBUpBhmdPON63zWVdZYnPhIDLgG84gkik,20
|
|
9
|
+
instructor_ainative-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AINative Studio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
instructor_ainative
|