StruAI Drawing Analysis SDK - AI-powered construction drawing analysis
Project description
StruAI Python SDK
Official Python SDK for the StruAI Drawing Analysis API.
Installation
pip install struai
Quick Start
Get an API key from stru.ai and set it as an environment variable:
export STRUAI_API_KEY="YOUR_API_KEY"
import os
from struai import StruAI
client = StruAI(api_key=os.environ["STRUAI_API_KEY"])
# Optional: override base URL (http://localhost:8000 or http://localhost:8000/v1)
client = StruAI(api_key=os.environ["STRUAI_API_KEY"], base_url="http://localhost:8000")
Tier 1: Raw Detection ($0.02/page)
Fast geometric detection. Returns annotations in ~1-2 seconds.
# Analyze a PDF page
result = client.drawings.analyze("structural.pdf", page=4)
# Or reuse cached PDFs by hash (skips upload)
file_hash = client.drawings.compute_file_hash("structural.pdf")
result = client.drawings.analyze(page=4, file_hash=file_hash)
print(f"Processed in {result.processing_ms}ms")
print(f"Page size: {result.dimensions.width}x{result.dimensions.height}")
# Access detected annotations
for leader in result.annotations.leaders:
texts = [t.text for t in leader.texts_inside]
print(f"Leader at {leader.arrow_tip}: {', '.join(texts)}")
for tag in result.annotations.section_tags:
label = tag.texts_inside[0].text
print(f"Section {label}, direction: {tag.direction}")
# Retrieve/delete previous results
drawing = client.drawings.get("drw_7f8a9b2c")
client.drawings.delete("drw_7f8a9b2c")
HTTP Endpoints (Reference)
All endpoints are under /v1. Use Authorization: Bearer <API_KEY>.
Tier 1 (raw detection):
POST /v1/drawings— multipart form withfile(PDF) orfile_hash, pluspage(1-indexed)GET /v1/drawings/{id}DELETE /v1/drawings/{id}
Tier 2 (graph + search):
POST /v1/projectsGET /v1/projectsGET /v1/projects/{id}DELETE /v1/projects/{id}POST /v1/projects/{project_id}/sheets— multipart form withfile+pageGET /v1/projects/{project_id}/jobs/{job_id}GET /v1/projects/{project_id}/sheetsGET /v1/projects/{project_id}/sheets/{sheet_id}DELETE /v1/projects/{project_id}/sheets/{sheet_id}POST /v1/projects/{project_id}/searchPOST /v1/projects/{project_id}/queryGET /v1/projects/{project_id}/entitiesGET /v1/projects/{project_id}/entities/{entity_id}GET /v1/projects/{project_id}/relationships
Example (raw detection):
curl -X POST "https://api.stru.ai/v1/drawings" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@structural.pdf" \
-F "page=4"
curl -X POST "https://api.stru.ai/v1/drawings" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file_hash=abc123def4567890" \
-F "page=4"
Example (project sheet ingestion):
curl -X POST "https://api.stru.ai/v1/projects/{project_id}/sheets" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@structural.pdf" \
-F "page=4"
Tier 2: Graph + Search ($0.15/page)
Full pipeline: detection → LLM enrichment → knowledge graph → semantic search.
# Create a project
project = client.projects.create(
name="Building A Structural",
description="96-page structural drawing set"
)
# Add sheets (async processing)
job = project.sheets.add("structural.pdf", page=4)
result = job.wait(timeout=120) # Blocks until complete
print(f"Created {result.entities_created} entities")
# Semantic search
results = project.search(
query="W12x26 beam connections at grid A",
limit=10,
include_graph_context=True
)
for hit in results.results:
print(f"{hit.entity.label}: {hit.score:.2f}")
if hit.graph_context:
for rel in hit.graph_context.relationships:
print(f" - {rel.type}: {rel.fact}")
# Natural language query
answer = project.query("What beams connect to column C3?")
print(answer.answer)
print(f"Confidence: {answer.confidence:.0%}")
# Browse entities
entities = project.entities.list(type="Component", limit=50)
entity = project.entities.get("ent_abc123")
Async Support
import os
from struai import AsyncStruAI
async with AsyncStruAI(api_key=os.environ["STRUAI_API_KEY"]) as client:
# Tier 1
result = await client.drawings.analyze("structural.pdf", page=4)
# Tier 2
project = await client.projects.create(name="Building A")
job = await project.sheets.add("structural.pdf", page=4)
result = await job.wait(timeout=120)
results = await project.search("W12x26 beam connections")
Error Handling
from struai import StruAI, AuthenticationError, RateLimitError, NotFoundError
try:
result = client.drawings.analyze("plans.pdf", page=99)
except AuthenticationError:
print("Invalid API key")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
except NotFoundError:
print("Resource not found")
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 struai-1.1.1.tar.gz.
File metadata
- Download URL: struai-1.1.1.tar.gz
- Upload date:
- Size: 20.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed3246c116ce2fbf49eb1159e428fb4fe87bbe096b9ad6a2703eaf03ea5c1023
|
|
| MD5 |
786737d6ef57b0d21cdee48150fd7b68
|
|
| BLAKE2b-256 |
c675924976a37e7abba1f71c6cfa5fab34787daf04807b599cda0bba014ee676
|
Provenance
The following attestation bundles were made for struai-1.1.1.tar.gz:
Publisher:
release.yml on bhoshaga/struai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
struai-1.1.1.tar.gz -
Subject digest:
ed3246c116ce2fbf49eb1159e428fb4fe87bbe096b9ad6a2703eaf03ea5c1023 - Sigstore transparency entry: 910328736
- Sigstore integration time:
-
Permalink:
bhoshaga/struai@a2132e8b8923d24973f33351b785db1b7d3bb7f7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/bhoshaga
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a2132e8b8923d24973f33351b785db1b7d3bb7f7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file struai-1.1.1-py3-none-any.whl.
File metadata
- Download URL: struai-1.1.1-py3-none-any.whl
- Upload date:
- Size: 17.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0eeea0195526151ea0d81635a412a8949f6c83229ec0a03dfd6cd2efc5856c85
|
|
| MD5 |
82ff1922ccfc303afd3c3a55573acedd
|
|
| BLAKE2b-256 |
4696dc38824162a665acef76f579be1ee8948bb2bb296c0e12dfc8f9e10d49b1
|
Provenance
The following attestation bundles were made for struai-1.1.1-py3-none-any.whl:
Publisher:
release.yml on bhoshaga/struai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
struai-1.1.1-py3-none-any.whl -
Subject digest:
0eeea0195526151ea0d81635a412a8949f6c83229ec0a03dfd6cd2efc5856c85 - Sigstore transparency entry: 910328740
- Sigstore integration time:
-
Permalink:
bhoshaga/struai@a2132e8b8923d24973f33351b785db1b7d3bb7f7 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/bhoshaga
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a2132e8b8923d24973f33351b785db1b7d3bb7f7 -
Trigger Event:
push
-
Statement type: