crewai-sibfly 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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Verifly
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,73 @@
1
+ Metadata-Version: 2.4
2
+ Name: crewai-sibfly
3
+ Version: 0.1.0
4
+ Summary: CrewAI tool for SibFly — measured ground motion (subsidence & uplift) per US address, from NASA Sentinel-1 InSAR
5
+ Author-email: SibFly <support@sibfly.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://sibfly.com
8
+ Project-URL: Documentation, https://sibfly.com/docs
9
+ Project-URL: Repository, https://github.com/james-sib/crewai-sibfly
10
+ Keywords: crewai,crewai-tools,sibfly,insar,ground-motion,subsidence,geospatial,nasa,agents,tools
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: GIS
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: crewai>=0.70
23
+ Requires-Dist: httpx>=0.27
24
+ Requires-Dist: pydantic>=2.0
25
+ Dynamic: license-file
26
+
27
+ # crewai-sibfly
28
+
29
+ A [CrewAI](https://github.com/crewAIInc/crewAI) tool for **[SibFly](https://sibfly.com)** — measured ground motion (subsidence & uplift) for any US address, in **mm/year**, from NASA OPERA Sentinel-1 satellite radar (InSAR). **Measured, not modeled.**
30
+
31
+ Negative mm/year = the ground is sinking. Give your agents ground truth about whether the land under an address is sinking, rising, or stable.
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ pip install -U crewai-sibfly
37
+ export SIBFLY_API_KEY="sf_live_..." # free key at https://sibfly.com (agents can self-register)
38
+ ```
39
+
40
+ ## Use
41
+
42
+ ```python
43
+ from crewai import Agent
44
+ from crewai_sibfly import SibflyGroundMotionTool
45
+
46
+ analyst = Agent(
47
+ role="Property risk analyst",
48
+ goal="Tell the user if the ground under an address is sinking",
49
+ tools=[SibflyGroundMotionTool()],
50
+ )
51
+ ```
52
+
53
+ Or call it directly:
54
+
55
+ ```python
56
+ from crewai_sibfly import SibflyGroundMotionTool
57
+
58
+ tool = SibflyGroundMotionTool() # reads SIBFLY_API_KEY
59
+ tool.run(address="1100 Congress Ave, Austin, TX")
60
+ tool.run(lat=36.098, lon=-119.56, dry_run=True) # FREE coverage + price check
61
+ ```
62
+
63
+ ## Pricing (agent-friendly)
64
+
65
+ - **$0.40 per covered report.** Out-of-coverage, no-data, too-stale, and low-confidence results are **free** (`cost_usd: 0`).
66
+ - Pass `dry_run=True` for a free coverage + price check before spending.
67
+ - Route logic on the stable `assessment_code` (`rapid_subsidence` / `notable_subsidence` / `stable` / `mild_uplift` / `strong_uplift`), not the human-readable string.
68
+
69
+ ## Also available
70
+
71
+ LangChain (`langchain-sibfly`), LlamaIndex (`llama-index-tools-sibfly`), n8n (`n8n-nodes-sibfly`), a hosted **MCP server** at `https://sibfly.com/mcp`, and a plain REST API. See <https://sibfly.com/docs>.
72
+
73
+ Data: NASA OPERA DISP-S1 (contains modified Copernicus Sentinel data). Screening estimate from satellite radar, not an engineering survey. MIT-licensed integration.
@@ -0,0 +1,47 @@
1
+ # crewai-sibfly
2
+
3
+ A [CrewAI](https://github.com/crewAIInc/crewAI) tool for **[SibFly](https://sibfly.com)** — measured ground motion (subsidence & uplift) for any US address, in **mm/year**, from NASA OPERA Sentinel-1 satellite radar (InSAR). **Measured, not modeled.**
4
+
5
+ Negative mm/year = the ground is sinking. Give your agents ground truth about whether the land under an address is sinking, rising, or stable.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install -U crewai-sibfly
11
+ export SIBFLY_API_KEY="sf_live_..." # free key at https://sibfly.com (agents can self-register)
12
+ ```
13
+
14
+ ## Use
15
+
16
+ ```python
17
+ from crewai import Agent
18
+ from crewai_sibfly import SibflyGroundMotionTool
19
+
20
+ analyst = Agent(
21
+ role="Property risk analyst",
22
+ goal="Tell the user if the ground under an address is sinking",
23
+ tools=[SibflyGroundMotionTool()],
24
+ )
25
+ ```
26
+
27
+ Or call it directly:
28
+
29
+ ```python
30
+ from crewai_sibfly import SibflyGroundMotionTool
31
+
32
+ tool = SibflyGroundMotionTool() # reads SIBFLY_API_KEY
33
+ tool.run(address="1100 Congress Ave, Austin, TX")
34
+ tool.run(lat=36.098, lon=-119.56, dry_run=True) # FREE coverage + price check
35
+ ```
36
+
37
+ ## Pricing (agent-friendly)
38
+
39
+ - **$0.40 per covered report.** Out-of-coverage, no-data, too-stale, and low-confidence results are **free** (`cost_usd: 0`).
40
+ - Pass `dry_run=True` for a free coverage + price check before spending.
41
+ - Route logic on the stable `assessment_code` (`rapid_subsidence` / `notable_subsidence` / `stable` / `mild_uplift` / `strong_uplift`), not the human-readable string.
42
+
43
+ ## Also available
44
+
45
+ LangChain (`langchain-sibfly`), LlamaIndex (`llama-index-tools-sibfly`), n8n (`n8n-nodes-sibfly`), a hosted **MCP server** at `https://sibfly.com/mcp`, and a plain REST API. See <https://sibfly.com/docs>.
46
+
47
+ Data: NASA OPERA DISP-S1 (contains modified Copernicus Sentinel data). Screening estimate from satellite radar, not an engineering survey. MIT-licensed integration.
@@ -0,0 +1,12 @@
1
+ """CrewAI integration for SibFly — measured ground motion (subsidence/uplift) per US address."""
2
+ from .client import SibflyClient
3
+
4
+ __all__ = ["SibflyClient", "SibflyGroundMotionTool"]
5
+ __version__ = "0.1.0"
6
+
7
+
8
+ def __getattr__(name): # lazy import so `SibflyClient` works even without crewai installed
9
+ if name == "SibflyGroundMotionTool":
10
+ from .tool import SibflyGroundMotionTool
11
+ return SibflyGroundMotionTool
12
+ raise AttributeError(name)
@@ -0,0 +1,83 @@
1
+ """Thin SibFly HTTP client (no crewai dependency, so it is easy to test)."""
2
+ from __future__ import annotations
3
+ import os
4
+ from typing import Any, Dict, Optional
5
+ import httpx
6
+
7
+ DEFAULT_BASE_URL = "https://sibfly.com"
8
+ _MOTION_PATH = "/api/v1/motion"
9
+ _COVERAGE_PATH = "/api/v1/coverage"
10
+ _DEFAULT_TIMEOUT = 60.0
11
+
12
+ _KEEP = (
13
+ "status", "velocity_vertical_mm_yr", "velocity_vertical_in_yr", "velocity_uncertainty_mm_yr",
14
+ "seasonal_amplitude_mm", "total_motion_mm", "trend", "assessment", "assessment_code",
15
+ "confidence", "near_threshold", "neighbor_consistent", "data_age_days", "data_freshness",
16
+ "frame", "pixel_id", "n_measurements", "last_observation", "data_coverage", "coverage",
17
+ "cost_usd", "credits_remaining_usd", "would_cost_usd", "message", "request_id",
18
+ )
19
+
20
+
21
+ def _shape(payload: Any) -> Dict[str, Any]:
22
+ if not isinstance(payload, dict):
23
+ return {"raw": payload}
24
+ out = {k: payload[k] for k in _KEEP if payload.get(k) is not None}
25
+ for k in ("error", "code", "top_up_url", "buy_credits_url", "retryable", "retry_after"):
26
+ if payload.get(k) is not None:
27
+ out[k] = payload[k]
28
+ q = payload.get("query")
29
+ if isinstance(q, dict):
30
+ out["query"] = {k: q[k] for k in ("address", "geocoded_address", "lat", "lon") if q.get(k) is not None}
31
+ return out
32
+
33
+
34
+ class SibflyClient:
35
+ """Minimal client for the SibFly ground-motion API.
36
+
37
+ Pricing is agent-friendly: $0.40 per covered report, and misses (out-of-coverage,
38
+ no-data, too-stale, low-confidence) return ``cost_usd: 0``. Use ``dry_run=True``
39
+ for a free coverage + price check first.
40
+ """
41
+
42
+ def __init__(self, api_key: Optional[str] = None, base_url: str = DEFAULT_BASE_URL,
43
+ timeout: float = _DEFAULT_TIMEOUT) -> None:
44
+ self.api_key = api_key or os.environ.get("SIBFLY_API_KEY")
45
+ self.base_url = base_url.rstrip("/")
46
+ self.timeout = timeout
47
+
48
+ def _headers(self) -> Dict[str, str]:
49
+ if not self.api_key:
50
+ raise ValueError(
51
+ "A SibFly API key is required. Pass api_key=... or set SIBFLY_API_KEY. "
52
+ "Get a free key at https://sibfly.com (agents: POST /api/v1/autonomous/register)."
53
+ )
54
+ return {"Authorization": f"Bearer {self.api_key}", "Accept": "application/json"}
55
+
56
+ @staticmethod
57
+ def _handle(resp: "httpx.Response") -> Dict[str, Any]:
58
+ try:
59
+ body = resp.json()
60
+ except ValueError:
61
+ body = None
62
+ if resp.status_code >= 400:
63
+ if isinstance(body, dict) and (body.get("error") or body.get("code")):
64
+ return _shape(body) # structured 402/429 etc. are actionable data
65
+ resp.raise_for_status()
66
+ return _shape(body)
67
+
68
+ def motion(self, address: Optional[str] = None, lat: Optional[float] = None,
69
+ lon: Optional[float] = None, dry_run: bool = False,
70
+ max_age_days: Optional[int] = None, min_confidence: Optional[float] = None) -> Dict[str, Any]:
71
+ if not address and (lat is None or lon is None):
72
+ raise ValueError("Provide an 'address' or both 'lat' and 'lon'.")
73
+ params: Dict[str, Any] = {}
74
+ if address:
75
+ params["address"] = address
76
+ else:
77
+ params["lat"] = lat; params["lon"] = lon
78
+ if dry_run: params["dry_run"] = 1
79
+ if max_age_days is not None: params["max_age_days"] = max_age_days
80
+ if min_confidence is not None: params["min_confidence"] = min_confidence
81
+ with httpx.Client() as c:
82
+ return self._handle(c.get(self.base_url + _MOTION_PATH, params=params,
83
+ headers=self._headers(), timeout=self.timeout))
File without changes
@@ -0,0 +1,55 @@
1
+ """SibFly ground-motion tool for CrewAI."""
2
+ from __future__ import annotations
3
+ from typing import Any, Dict, Optional, Type
4
+ from pydantic import BaseModel, Field
5
+ from crewai.tools import BaseTool
6
+ from .client import SibflyClient, DEFAULT_BASE_URL
7
+
8
+
9
+ class SibflyMotionInput(BaseModel):
10
+ address: Optional[str] = Field(
11
+ default=None, description="A US street address, e.g. '1100 Congress Ave, Austin, TX'. Provide this OR lat+lon.")
12
+ lat: Optional[float] = Field(default=None, description="Latitude (use with lon instead of address).")
13
+ lon: Optional[float] = Field(default=None, description="Longitude (use with lat instead of address).")
14
+ dry_run: bool = Field(default=False, description="If true, return a FREE preview (coverage + would_cost_usd), no charge.")
15
+ max_age_days: Optional[int] = Field(default=None, description="Return a free 'stale_data' result if the newest data is older than this.")
16
+ min_confidence: Optional[float] = Field(default=None, description="0-1. Return a free 'low_confidence' result below this pixel confidence.")
17
+
18
+
19
+ class SibflyGroundMotionTool(BaseTool):
20
+ """Measure how fast the ground is sinking or rising (mm/year) under any US address.
21
+
22
+ Uses the SibFly API (NASA OPERA Sentinel-1 InSAR — measured, not modeled). Negative
23
+ mm/year = sinking. Returns velocity, uncertainty, a stable ``assessment_code``
24
+ (rapid_subsidence / notable_subsidence / stable / mild_uplift / strong_uplift),
25
+ confidence, and data age. $0.40 per covered report; out-of-coverage and low-quality
26
+ results are FREE. Pass ``dry_run=True`` for a free coverage + price check first.
27
+
28
+ Setup::
29
+
30
+ pip install -U crewai-sibfly
31
+ export SIBFLY_API_KEY="sf_live_..." # free key at https://sibfly.com
32
+
33
+ from crewai_sibfly import SibflyGroundMotionTool
34
+ agent = Agent(role="Property risk analyst", tools=[SibflyGroundMotionTool()], ...)
35
+ """
36
+
37
+ name: str = "SibFly Ground Motion"
38
+ description: str = (
39
+ "Measure how fast the ground is sinking or rising (mm/year) under a US address, "
40
+ "from NASA satellite radar (InSAR). Input a US address OR lat/lon. Negative = sinking. "
41
+ "Returns velocity, uncertainty, a stable assessment_code (rapid_subsidence/"
42
+ "notable_subsidence/stable/mild_uplift/strong_uplift), confidence, and data age. "
43
+ "$0.40 per covered report; out-of-coverage and low-quality results are FREE. Pass "
44
+ "dry_run=true for a free coverage + price check first."
45
+ )
46
+ args_schema: Type[BaseModel] = SibflyMotionInput
47
+ api_key: Optional[str] = None
48
+ base_url: str = DEFAULT_BASE_URL
49
+
50
+ def _run(self, address: Optional[str] = None, lat: Optional[float] = None, lon: Optional[float] = None,
51
+ dry_run: bool = False, max_age_days: Optional[int] = None,
52
+ min_confidence: Optional[float] = None) -> Dict[str, Any]:
53
+ client = SibflyClient(api_key=self.api_key, base_url=self.base_url)
54
+ return client.motion(address=address, lat=lat, lon=lon, dry_run=dry_run,
55
+ max_age_days=max_age_days, min_confidence=min_confidence)
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.4
2
+ Name: crewai-sibfly
3
+ Version: 0.1.0
4
+ Summary: CrewAI tool for SibFly — measured ground motion (subsidence & uplift) per US address, from NASA Sentinel-1 InSAR
5
+ Author-email: SibFly <support@sibfly.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://sibfly.com
8
+ Project-URL: Documentation, https://sibfly.com/docs
9
+ Project-URL: Repository, https://github.com/james-sib/crewai-sibfly
10
+ Keywords: crewai,crewai-tools,sibfly,insar,ground-motion,subsidence,geospatial,nasa,agents,tools
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: GIS
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: crewai>=0.70
23
+ Requires-Dist: httpx>=0.27
24
+ Requires-Dist: pydantic>=2.0
25
+ Dynamic: license-file
26
+
27
+ # crewai-sibfly
28
+
29
+ A [CrewAI](https://github.com/crewAIInc/crewAI) tool for **[SibFly](https://sibfly.com)** — measured ground motion (subsidence & uplift) for any US address, in **mm/year**, from NASA OPERA Sentinel-1 satellite radar (InSAR). **Measured, not modeled.**
30
+
31
+ Negative mm/year = the ground is sinking. Give your agents ground truth about whether the land under an address is sinking, rising, or stable.
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ pip install -U crewai-sibfly
37
+ export SIBFLY_API_KEY="sf_live_..." # free key at https://sibfly.com (agents can self-register)
38
+ ```
39
+
40
+ ## Use
41
+
42
+ ```python
43
+ from crewai import Agent
44
+ from crewai_sibfly import SibflyGroundMotionTool
45
+
46
+ analyst = Agent(
47
+ role="Property risk analyst",
48
+ goal="Tell the user if the ground under an address is sinking",
49
+ tools=[SibflyGroundMotionTool()],
50
+ )
51
+ ```
52
+
53
+ Or call it directly:
54
+
55
+ ```python
56
+ from crewai_sibfly import SibflyGroundMotionTool
57
+
58
+ tool = SibflyGroundMotionTool() # reads SIBFLY_API_KEY
59
+ tool.run(address="1100 Congress Ave, Austin, TX")
60
+ tool.run(lat=36.098, lon=-119.56, dry_run=True) # FREE coverage + price check
61
+ ```
62
+
63
+ ## Pricing (agent-friendly)
64
+
65
+ - **$0.40 per covered report.** Out-of-coverage, no-data, too-stale, and low-confidence results are **free** (`cost_usd: 0`).
66
+ - Pass `dry_run=True` for a free coverage + price check before spending.
67
+ - Route logic on the stable `assessment_code` (`rapid_subsidence` / `notable_subsidence` / `stable` / `mild_uplift` / `strong_uplift`), not the human-readable string.
68
+
69
+ ## Also available
70
+
71
+ LangChain (`langchain-sibfly`), LlamaIndex (`llama-index-tools-sibfly`), n8n (`n8n-nodes-sibfly`), a hosted **MCP server** at `https://sibfly.com/mcp`, and a plain REST API. See <https://sibfly.com/docs>.
72
+
73
+ Data: NASA OPERA DISP-S1 (contains modified Copernicus Sentinel data). Screening estimate from satellite radar, not an engineering survey. MIT-licensed integration.
@@ -0,0 +1,12 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ crewai_sibfly/__init__.py
5
+ crewai_sibfly/client.py
6
+ crewai_sibfly/py.typed
7
+ crewai_sibfly/tool.py
8
+ crewai_sibfly.egg-info/PKG-INFO
9
+ crewai_sibfly.egg-info/SOURCES.txt
10
+ crewai_sibfly.egg-info/dependency_links.txt
11
+ crewai_sibfly.egg-info/requires.txt
12
+ crewai_sibfly.egg-info/top_level.txt
@@ -0,0 +1,3 @@
1
+ crewai>=0.70
2
+ httpx>=0.27
3
+ pydantic>=2.0
@@ -0,0 +1 @@
1
+ crewai_sibfly
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "crewai-sibfly"
7
+ version = "0.1.0"
8
+ description = "CrewAI tool for SibFly — measured ground motion (subsidence & uplift) per US address, from NASA Sentinel-1 InSAR"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "SibFly", email = "support@sibfly.com" }]
13
+ keywords = ["crewai", "crewai-tools", "sibfly", "insar", "ground-motion", "subsidence", "geospatial", "nasa", "agents", "tools"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Topic :: Scientific/Engineering :: GIS",
23
+ ]
24
+ dependencies = ["crewai>=0.70", "httpx>=0.27", "pydantic>=2.0"]
25
+
26
+ [project.urls]
27
+ Homepage = "https://sibfly.com"
28
+ Documentation = "https://sibfly.com/docs"
29
+ Repository = "https://github.com/james-sib/crewai-sibfly"
30
+
31
+ [tool.setuptools]
32
+ packages = ["crewai_sibfly"]
33
+
34
+ [tool.setuptools.package-data]
35
+ crewai_sibfly = ["py.typed"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+