Python client for the Instructeer API
Project description
instructeer
Python client library for the Instructeer API.
Instructeer provides deterministic guardrails for LLM pipelines — no ML inference, no probabilistic scores. The same input always produces the same output.
- SQLGuard — AST-based SQL risk analysis. Blocks dangerous or expensive queries before they reach your database.
- PIIGuard — Regex and lexicon-based PII detection. Prevents sensitive data from leaking through prompts or logs.
Installation
pip install instructeer
Requires Python 3.11+.
Authentication
All requests require an API key. Get yours at instructeer.com.
Pass the key directly or set the INSTRUCTEER_API_KEY environment variable:
# macOS / Linux
export INSTRUCTEER_API_KEY=rg_...
# Windows (cmd)
set INSTRUCTEER_API_KEY=rg_...
# Windows (PowerShell)
$env:INSTRUCTEER_API_KEY="rg_..."
SQLGuard
from instructeer.guards import SQLGuard
# api_key = os.environ["INSTRUCTEER_API_KEY"]
sql = SQLGuard(api_key="rg_...")
result = sql.analyze("SELECT * FROM users WHERE id = 1")
print(result.allowed) # True
print(result.severity) # "low"
print(result.issues) # []
{ "allowed": true, "severity": "low", "issues": [] }
Block a query based on the result:
generated_sql = "DELETE FROM users"
result = sql.analyze(generated_sql)
# Block on high severity only (allowed is False)
if not result.allowed:
raise ValueError(f"Query blocked: {result.issues[0].message}")
# Block on medium and high severity
if result.severity in ("medium", "high"):
raise ValueError(f"Query blocked: {result.issues[0].message}")
{
"allowed": false,
"severity": "high",
"issues": [
{ "rule": "dml_no_where", "severity": "high", "message": "DELETE without WHERE clause would affect all rows" }
]
}
Dialects
Defaults to "postgres". Supported values:
postgres · mysql · bigquery · tsql · oracle · snowflake · databricks · sqlite · hive · mariadb
result = sql.analyze("SELECT TOP 10 * FROM users", dialect="tsql")
Response
| Field | Type | Description |
|---|---|---|
allowed |
bool |
False when a high-severity issue is detected |
severity |
str |
"low", "medium", or "high" |
issues |
list[Issue] |
Each issue has rule, message, and severity |
PIIGuard
from instructeer.guards import PIIGuard
# api_key = os.environ["INSTRUCTEER_API_KEY"]
pii = PIIGuard(api_key="rg_...")
result = pii.detect_all("Alice's SSN is 123-45-6789 and email is alice@example.com")
print(result.summary.total) # 2
print(result.summary.max_severity) # "high"
for d in result.detections:
print(d.entity_type, d.value, d.confidence)
{
"detections": [
{ "entity_type": "US_SSN", "value": "123-45-6789", "confidence": 1.0, "severity": "high" },
{ "entity_type": "EMAIL_ADDRESS", "value": "alice@example.com", "confidence": 1.0, "severity": "medium" }
],
"summary": {
"total": 2,
"max_severity": "high",
"by_type": { "US_SSN": 1, "EMAIL_ADDRESS": 1 },
"by_severity": { "high": 1, "medium": 1 }
}
}
Single detectors
result = pii.detect_email("Reach out at hello@example.com")
result = pii.detect_ssn("Patient SSN: 078-05-1120")
result = pii.detect_card("Charged to 4111 1111 1111 1111")
result = pii.detect_phone("Call 800-555-0199")
Available: detect_email · detect_phone · detect_ssn · detect_card · detect_bank · detect_iban · detect_ip · detect_url · detect_date · detect_dob · detect_dl · detect_passport · detect_address · detect_person
Filtering
result = pii.detect_all(
text,
detectors=["email", "ssn", "card"],
min_confidence=0.8,
confidence_thresholds={"US_ADDRESS": 0.7},
use_default_thresholds=True,
)
Response
DetectResponse
| Field | Type | Description |
|---|---|---|
detections |
list[Detection] |
All detected PII spans |
summary |
DetectionSummary |
Aggregate counts and severity roll-up |
Detection
| Field | Type | Description |
|---|---|---|
entity_type |
str |
e.g. "EMAIL_ADDRESS", "US_SSN", "CREDIT_CARD" |
value |
str |
The matched text |
start |
int |
Start character offset |
end |
int |
End character offset |
severity |
str |
"low", "medium", or "high" |
confidence |
float |
Detection confidence (0.0–1.0) |
extra |
dict | None |
Additional detector-specific metadata |
DetectionSummary
| Field | Type | Description |
|---|---|---|
total |
int |
Total number of detections |
max_severity |
str | None |
Highest severity with confidence ≥ 0.3 |
by_type |
dict[str, int] |
Count per entity type |
by_severity |
dict[str, int] |
Count per severity level |
Async
import asyncio
from instructeer.guards import AsyncSQLGuard, AsyncPIIGuard
async def main():
async with AsyncSQLGuard(api_key="rg_...") as sql:
result = await sql.analyze("DROP TABLE users")
async with AsyncPIIGuard(api_key="rg_...") as pii:
result = await pii.detect_all("SSN: 123-45-6789")
asyncio.run(main())
Error handling
from instructeer import (
AuthenticationError,
PermissionDeniedError,
RateLimitError,
UnprocessableEntityError,
APIConnectionError,
APITimeoutError,
APIError,
)
try:
result = sql.analyze(query)
except AuthenticationError:
...
except PermissionDeniedError:
...
except RateLimitError as e:
print(e.status_code) # 429
except UnprocessableEntityError:
...
except APITimeoutError:
...
except APIConnectionError:
...
except APIError as e:
print(e.status_code)
Configuration
| Parameter | Default | Description |
|---|---|---|
api_key |
env INSTRUCTEER_API_KEY |
Your Instructeer API key |
base_url |
https://api.instructeer.com |
Override for self-hosted deployments |
timeout |
30.0 |
Request timeout in seconds |
max_retries |
2 |
Retries on 429 and 5xx with exponential backoff |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file instructeer-1.0.0.tar.gz.
File metadata
- Download URL: instructeer-1.0.0.tar.gz
- Upload date:
- Size: 14.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a11b96ea77b6161cdfc1226e494e195e2fd5a1799f5a5382d31794e99f291a8
|
|
| MD5 |
c2afe6751bfd6399936bc4bcc5d4abe0
|
|
| BLAKE2b-256 |
3656c11597cb441552046ee9fc3499fc33e2661cbd0eb930aef0867ee40ee084
|
File details
Details for the file instructeer-1.0.0-py3-none-any.whl.
File metadata
- Download URL: instructeer-1.0.0-py3-none-any.whl
- Upload date:
- Size: 10.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c581701cad86bc5a2e5c337afab70e03e2f7c5d21d62430c4e42a53525f17d04
|
|
| MD5 |
240f8e3d6d5393ac312792f51e7447df
|
|
| BLAKE2b-256 |
2c47f192eaafaf45d848e86668e69ec9c19fca0ba05fb22252f8c7f147552498
|