struai 0.0.1__tar.gz → 0.1.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.
- struai-0.1.0/.github/workflows/ci.yml +58 -0
- struai-0.1.0/.github/workflows/publish-npm.yml +68 -0
- struai-0.1.0/.github/workflows/publish-python.yml +54 -0
- struai-0.1.0/.gitignore +43 -0
- struai-0.1.0/PKG-INFO +148 -0
- struai-0.1.0/README.md +116 -0
- struai-0.1.0/js/.gitignore +3 -0
- struai-0.1.0/js/README.md +66 -0
- struai-0.1.0/js/package.json +54 -0
- struai-0.1.0/js/src/index.ts +424 -0
- struai-0.1.0/js/tsconfig.json +13 -0
- struai-0.1.0/pyproject.toml +74 -0
- struai-0.1.0/src/struai/__init__.py +108 -0
- struai-0.1.0/src/struai/_base.py +346 -0
- struai-0.1.0/src/struai/_client.py +111 -0
- struai-0.1.0/src/struai/_exceptions.py +103 -0
- struai-0.1.0/src/struai/_version.py +2 -0
- struai-0.1.0/src/struai/models/__init__.py +60 -0
- struai-0.1.0/src/struai/models/common.py +36 -0
- struai-0.1.0/src/struai/models/drawings.py +81 -0
- struai-0.1.0/src/struai/models/entities.py +37 -0
- struai-0.1.0/src/struai/models/projects.py +83 -0
- struai-0.1.0/src/struai/models/search.py +70 -0
- struai-0.1.0/src/struai/py.typed +0 -0
- struai-0.1.0/src/struai/resources/__init__.py +5 -0
- struai-0.1.0/src/struai/resources/drawings.py +122 -0
- struai-0.1.0/src/struai/resources/projects.py +628 -0
- struai-0.0.1/PKG-INFO +0 -17
- struai-0.0.1/README.md +0 -3
- struai-0.0.1/pyproject.toml +0 -23
- struai-0.0.1/src/struai/__init__.py +0 -2
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test-python:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ['3.9', '3.10', '3.11', '3.12']
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: |
|
|
25
|
+
pip install -e ".[dev]"
|
|
26
|
+
|
|
27
|
+
- name: Lint
|
|
28
|
+
run: ruff check src/
|
|
29
|
+
|
|
30
|
+
- name: Type check
|
|
31
|
+
run: mypy src/struai/ --ignore-missing-imports
|
|
32
|
+
continue-on-error: true
|
|
33
|
+
|
|
34
|
+
test-node:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
defaults:
|
|
37
|
+
run:
|
|
38
|
+
working-directory: js
|
|
39
|
+
strategy:
|
|
40
|
+
matrix:
|
|
41
|
+
node-version: ['18', '20', '22']
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
|
|
45
|
+
- name: Set up Node.js ${{ matrix.node-version }}
|
|
46
|
+
uses: actions/setup-node@v4
|
|
47
|
+
with:
|
|
48
|
+
node-version: ${{ matrix.node-version }}
|
|
49
|
+
|
|
50
|
+
- name: Install dependencies
|
|
51
|
+
run: npm install
|
|
52
|
+
|
|
53
|
+
- name: Build
|
|
54
|
+
run: npm run build
|
|
55
|
+
|
|
56
|
+
- name: Test
|
|
57
|
+
run: npm test
|
|
58
|
+
continue-on-error: true # Tests not implemented yet
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: Publish npm Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
paths:
|
|
8
|
+
- 'js/**'
|
|
9
|
+
- '.github/workflows/publish-npm.yml'
|
|
10
|
+
release:
|
|
11
|
+
types: [published]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
defaults:
|
|
17
|
+
run:
|
|
18
|
+
working-directory: js
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Node.js
|
|
23
|
+
uses: actions/setup-node@v4
|
|
24
|
+
with:
|
|
25
|
+
node-version: '20'
|
|
26
|
+
registry-url: 'https://registry.npmjs.org'
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: npm install
|
|
30
|
+
|
|
31
|
+
- name: Build
|
|
32
|
+
run: npm run build
|
|
33
|
+
|
|
34
|
+
- name: Upload artifacts
|
|
35
|
+
uses: actions/upload-artifact@v4
|
|
36
|
+
with:
|
|
37
|
+
name: npm-dist
|
|
38
|
+
path: js/dist/
|
|
39
|
+
|
|
40
|
+
publish:
|
|
41
|
+
needs: build
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
if: github.event_name == 'release' || github.ref == 'refs/heads/main'
|
|
44
|
+
defaults:
|
|
45
|
+
run:
|
|
46
|
+
working-directory: js
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v4
|
|
49
|
+
|
|
50
|
+
- name: Set up Node.js
|
|
51
|
+
uses: actions/setup-node@v4
|
|
52
|
+
with:
|
|
53
|
+
node-version: '20'
|
|
54
|
+
registry-url: 'https://registry.npmjs.org'
|
|
55
|
+
|
|
56
|
+
- name: Install dependencies
|
|
57
|
+
run: npm install
|
|
58
|
+
|
|
59
|
+
- name: Download artifacts
|
|
60
|
+
uses: actions/download-artifact@v4
|
|
61
|
+
with:
|
|
62
|
+
name: npm-dist
|
|
63
|
+
path: js/dist/
|
|
64
|
+
|
|
65
|
+
- name: Publish to npm
|
|
66
|
+
run: npm publish --access public
|
|
67
|
+
env:
|
|
68
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Publish Python Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
paths:
|
|
8
|
+
- 'src/**'
|
|
9
|
+
- 'pyproject.toml'
|
|
10
|
+
- '.github/workflows/publish-python.yml'
|
|
11
|
+
release:
|
|
12
|
+
types: [published]
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: '3.11'
|
|
24
|
+
|
|
25
|
+
- name: Install build tools
|
|
26
|
+
run: pip install build twine
|
|
27
|
+
|
|
28
|
+
- name: Build package
|
|
29
|
+
run: python -m build
|
|
30
|
+
|
|
31
|
+
- name: Upload artifacts
|
|
32
|
+
uses: actions/upload-artifact@v4
|
|
33
|
+
with:
|
|
34
|
+
name: python-dist
|
|
35
|
+
path: dist/
|
|
36
|
+
|
|
37
|
+
publish:
|
|
38
|
+
needs: build
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
if: github.event_name == 'release' || github.ref == 'refs/heads/main'
|
|
41
|
+
environment: pypi
|
|
42
|
+
permissions:
|
|
43
|
+
id-token: write
|
|
44
|
+
steps:
|
|
45
|
+
- name: Download artifacts
|
|
46
|
+
uses: actions/download-artifact@v4
|
|
47
|
+
with:
|
|
48
|
+
name: python-dist
|
|
49
|
+
path: dist/
|
|
50
|
+
|
|
51
|
+
- name: Publish to PyPI
|
|
52
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
53
|
+
with:
|
|
54
|
+
skip-existing: true
|
struai-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
.pytest_cache/
|
|
23
|
+
.ruff_cache/
|
|
24
|
+
.mypy_cache/
|
|
25
|
+
.venv/
|
|
26
|
+
venv/
|
|
27
|
+
|
|
28
|
+
# JavaScript
|
|
29
|
+
js/node_modules/
|
|
30
|
+
js/dist/
|
|
31
|
+
js/*.tsbuildinfo
|
|
32
|
+
|
|
33
|
+
# IDE
|
|
34
|
+
.idea/
|
|
35
|
+
.vscode/
|
|
36
|
+
*.swp
|
|
37
|
+
*.swo
|
|
38
|
+
.DS_Store
|
|
39
|
+
|
|
40
|
+
# Environment
|
|
41
|
+
.env
|
|
42
|
+
.env.local
|
|
43
|
+
*.pem
|
struai-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: struai
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: StruAI Drawing Analysis SDK - AI-powered construction drawing analysis
|
|
5
|
+
Project-URL: Homepage, https://struai.com
|
|
6
|
+
Project-URL: Documentation, https://docs.struai.com/python
|
|
7
|
+
Project-URL: Repository, https://github.com/struai/struai-python
|
|
8
|
+
Project-URL: Issues, https://github.com/struai/struai-python/issues
|
|
9
|
+
Author-email: StruAI <support@struai.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
Keywords: ai,cad,construction drawings,drawing analysis,knowledge graph,pdf,struai,structural engineering
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Requires-Dist: httpx>=0.25.0
|
|
25
|
+
Requires-Dist: pydantic>=2.0.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: mypy>=1.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# StruAI Python SDK
|
|
34
|
+
|
|
35
|
+
Official Python SDK for the StruAI Drawing Analysis API.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install struai
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from struai import StruAI
|
|
47
|
+
|
|
48
|
+
client = StruAI(api_key="sk-xxx") # or set STRUAI_API_KEY env var
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Tier 1: Raw Detection ($0.02/page)
|
|
52
|
+
|
|
53
|
+
Fast geometric detection. Returns annotations in ~1-2 seconds.
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
# Analyze a PDF page
|
|
57
|
+
result = client.drawings.analyze("structural.pdf", page=4)
|
|
58
|
+
|
|
59
|
+
print(f"Processed in {result.processing_ms}ms")
|
|
60
|
+
print(f"Page size: {result.dimensions.width}x{result.dimensions.height}")
|
|
61
|
+
|
|
62
|
+
# Access detected annotations
|
|
63
|
+
for leader in result.annotations.leaders:
|
|
64
|
+
texts = [t.text for t in leader.texts_inside]
|
|
65
|
+
print(f"Leader at {leader.arrow_tip}: {', '.join(texts)}")
|
|
66
|
+
|
|
67
|
+
for tag in result.annotations.section_tags:
|
|
68
|
+
label = tag.texts_inside[0].text
|
|
69
|
+
print(f"Section {label}, direction: {tag.direction}")
|
|
70
|
+
|
|
71
|
+
# Retrieve/delete previous results
|
|
72
|
+
drawing = client.drawings.get("drw_7f8a9b2c")
|
|
73
|
+
client.drawings.delete("drw_7f8a9b2c")
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Tier 2: Graph + Search ($0.15/page)
|
|
77
|
+
|
|
78
|
+
Full pipeline: detection → LLM enrichment → knowledge graph → semantic search.
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
# Create a project
|
|
82
|
+
project = client.projects.create(
|
|
83
|
+
name="Building A Structural",
|
|
84
|
+
description="96-page structural drawing set"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Add sheets (async processing)
|
|
88
|
+
job = project.sheets.add("structural.pdf", page=4)
|
|
89
|
+
result = job.wait(timeout=120) # Blocks until complete
|
|
90
|
+
print(f"Created {result.entities_created} entities")
|
|
91
|
+
|
|
92
|
+
# Semantic search
|
|
93
|
+
results = project.search(
|
|
94
|
+
query="W12x26 beam connections at grid A",
|
|
95
|
+
limit=10,
|
|
96
|
+
include_graph_context=True
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
for hit in results.results:
|
|
100
|
+
print(f"{hit.entity.label}: {hit.score:.2f}")
|
|
101
|
+
if hit.graph_context:
|
|
102
|
+
for rel in hit.graph_context.relationships:
|
|
103
|
+
print(f" - {rel.type}: {rel.fact}")
|
|
104
|
+
|
|
105
|
+
# Natural language query
|
|
106
|
+
answer = project.query("What beams connect to column C3?")
|
|
107
|
+
print(answer.answer)
|
|
108
|
+
print(f"Confidence: {answer.confidence:.0%}")
|
|
109
|
+
|
|
110
|
+
# Browse entities
|
|
111
|
+
entities = project.entities.list(type="Component", limit=50)
|
|
112
|
+
entity = project.entities.get("ent_abc123")
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Async Support
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from struai import AsyncStruAI
|
|
119
|
+
|
|
120
|
+
async with AsyncStruAI(api_key="sk-xxx") as client:
|
|
121
|
+
# Tier 1
|
|
122
|
+
result = await client.drawings.analyze("structural.pdf", page=4)
|
|
123
|
+
|
|
124
|
+
# Tier 2
|
|
125
|
+
project = await client.projects.create(name="Building A")
|
|
126
|
+
job = await project.sheets.add("structural.pdf", page=4)
|
|
127
|
+
result = await job.wait(timeout=120)
|
|
128
|
+
results = await project.search("W12x26 beam connections")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Error Handling
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from struai import StruAI, AuthenticationError, RateLimitError, NotFoundError
|
|
135
|
+
|
|
136
|
+
try:
|
|
137
|
+
result = client.drawings.analyze("plans.pdf", page=99)
|
|
138
|
+
except AuthenticationError:
|
|
139
|
+
print("Invalid API key")
|
|
140
|
+
except RateLimitError as e:
|
|
141
|
+
print(f"Rate limited. Retry after {e.retry_after}s")
|
|
142
|
+
except NotFoundError:
|
|
143
|
+
print("Resource not found")
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|
struai-0.1.0/README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# StruAI Python SDK
|
|
2
|
+
|
|
3
|
+
Official Python SDK for the StruAI Drawing Analysis API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install struai
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from struai import StruAI
|
|
15
|
+
|
|
16
|
+
client = StruAI(api_key="sk-xxx") # or set STRUAI_API_KEY env var
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Tier 1: Raw Detection ($0.02/page)
|
|
20
|
+
|
|
21
|
+
Fast geometric detection. Returns annotations in ~1-2 seconds.
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
# Analyze a PDF page
|
|
25
|
+
result = client.drawings.analyze("structural.pdf", page=4)
|
|
26
|
+
|
|
27
|
+
print(f"Processed in {result.processing_ms}ms")
|
|
28
|
+
print(f"Page size: {result.dimensions.width}x{result.dimensions.height}")
|
|
29
|
+
|
|
30
|
+
# Access detected annotations
|
|
31
|
+
for leader in result.annotations.leaders:
|
|
32
|
+
texts = [t.text for t in leader.texts_inside]
|
|
33
|
+
print(f"Leader at {leader.arrow_tip}: {', '.join(texts)}")
|
|
34
|
+
|
|
35
|
+
for tag in result.annotations.section_tags:
|
|
36
|
+
label = tag.texts_inside[0].text
|
|
37
|
+
print(f"Section {label}, direction: {tag.direction}")
|
|
38
|
+
|
|
39
|
+
# Retrieve/delete previous results
|
|
40
|
+
drawing = client.drawings.get("drw_7f8a9b2c")
|
|
41
|
+
client.drawings.delete("drw_7f8a9b2c")
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Tier 2: Graph + Search ($0.15/page)
|
|
45
|
+
|
|
46
|
+
Full pipeline: detection → LLM enrichment → knowledge graph → semantic search.
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
# Create a project
|
|
50
|
+
project = client.projects.create(
|
|
51
|
+
name="Building A Structural",
|
|
52
|
+
description="96-page structural drawing set"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Add sheets (async processing)
|
|
56
|
+
job = project.sheets.add("structural.pdf", page=4)
|
|
57
|
+
result = job.wait(timeout=120) # Blocks until complete
|
|
58
|
+
print(f"Created {result.entities_created} entities")
|
|
59
|
+
|
|
60
|
+
# Semantic search
|
|
61
|
+
results = project.search(
|
|
62
|
+
query="W12x26 beam connections at grid A",
|
|
63
|
+
limit=10,
|
|
64
|
+
include_graph_context=True
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
for hit in results.results:
|
|
68
|
+
print(f"{hit.entity.label}: {hit.score:.2f}")
|
|
69
|
+
if hit.graph_context:
|
|
70
|
+
for rel in hit.graph_context.relationships:
|
|
71
|
+
print(f" - {rel.type}: {rel.fact}")
|
|
72
|
+
|
|
73
|
+
# Natural language query
|
|
74
|
+
answer = project.query("What beams connect to column C3?")
|
|
75
|
+
print(answer.answer)
|
|
76
|
+
print(f"Confidence: {answer.confidence:.0%}")
|
|
77
|
+
|
|
78
|
+
# Browse entities
|
|
79
|
+
entities = project.entities.list(type="Component", limit=50)
|
|
80
|
+
entity = project.entities.get("ent_abc123")
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Async Support
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from struai import AsyncStruAI
|
|
87
|
+
|
|
88
|
+
async with AsyncStruAI(api_key="sk-xxx") as client:
|
|
89
|
+
# Tier 1
|
|
90
|
+
result = await client.drawings.analyze("structural.pdf", page=4)
|
|
91
|
+
|
|
92
|
+
# Tier 2
|
|
93
|
+
project = await client.projects.create(name="Building A")
|
|
94
|
+
job = await project.sheets.add("structural.pdf", page=4)
|
|
95
|
+
result = await job.wait(timeout=120)
|
|
96
|
+
results = await project.search("W12x26 beam connections")
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Error Handling
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from struai import StruAI, AuthenticationError, RateLimitError, NotFoundError
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
result = client.drawings.analyze("plans.pdf", page=99)
|
|
106
|
+
except AuthenticationError:
|
|
107
|
+
print("Invalid API key")
|
|
108
|
+
except RateLimitError as e:
|
|
109
|
+
print(f"Rate limited. Retry after {e.retry_after}s")
|
|
110
|
+
except NotFoundError:
|
|
111
|
+
print("Resource not found")
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## License
|
|
115
|
+
|
|
116
|
+
MIT
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# StruAI JavaScript SDK
|
|
2
|
+
|
|
3
|
+
Official JavaScript/TypeScript SDK for the StruAI Drawing Analysis API.
|
|
4
|
+
|
|
5
|
+
See the [main README](../README.md) for Python examples.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install struai
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { StruAI } from 'struai';
|
|
17
|
+
|
|
18
|
+
const client = new StruAI({ apiKey: 'sk-xxx' });
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Tier 1: Raw Detection ($0.02/page)
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Analyze a PDF page
|
|
25
|
+
const result = await client.drawings.analyze(file, { page: 4 });
|
|
26
|
+
|
|
27
|
+
console.log(`Processed in ${result.processing_ms}ms`);
|
|
28
|
+
|
|
29
|
+
for (const leader of result.annotations.leaders) {
|
|
30
|
+
const texts = leader.texts_inside.map(t => t.text).join(', ');
|
|
31
|
+
console.log(`Leader: ${texts}`);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Tier 2: Graph + Search ($0.15/page)
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// Create project
|
|
39
|
+
const project = await client.projects.create({
|
|
40
|
+
name: 'Building A Structural',
|
|
41
|
+
description: '96-page structural drawing set'
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Add sheet (async processing)
|
|
45
|
+
const job = await project.sheets.add(file, { page: 4 });
|
|
46
|
+
const result = await job.wait({ timeout: 120000 });
|
|
47
|
+
console.log(`Created ${result.entities_created} entities`);
|
|
48
|
+
|
|
49
|
+
// Semantic search
|
|
50
|
+
const results = await project.search('W12x26 beam connections', {
|
|
51
|
+
limit: 10,
|
|
52
|
+
includeGraphContext: true
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
for (const hit of results.results) {
|
|
56
|
+
console.log(`${hit.entity.label}: ${hit.score}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Natural language query
|
|
60
|
+
const answer = await project.query('What beams connect to column C3?');
|
|
61
|
+
console.log(answer.answer);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
MIT
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "struai",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "StruAI Drawing Analysis SDK - AI-powered construction drawing analysis",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.mjs",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
20
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
21
|
+
"test": "vitest",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"struai",
|
|
26
|
+
"structural-engineering",
|
|
27
|
+
"construction-drawings",
|
|
28
|
+
"drawing-analysis",
|
|
29
|
+
"cad",
|
|
30
|
+
"pdf",
|
|
31
|
+
"ai",
|
|
32
|
+
"knowledge-graph"
|
|
33
|
+
],
|
|
34
|
+
"author": "StruAI <support@struai.com>",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/bhoshaga/struai.git",
|
|
39
|
+
"directory": "js"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://struai.com",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/bhoshaga/struai/issues"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^20.0.0",
|
|
47
|
+
"tsup": "^8.0.0",
|
|
48
|
+
"typescript": "^5.0.0",
|
|
49
|
+
"vitest": "^1.0.0"
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=18.0.0"
|
|
53
|
+
}
|
|
54
|
+
}
|