Skip to content

Commit 3cf8960

Browse files
feat: refactor Analysis class initialization and improve region support
Restructured Analysis class to separate initialization from execution flow using new init() method pattern. Modified TagoContext from TypedDict to class for better runtime flexibility. Updated documentation examples to reflect Python runtime instead of Deno.
1 parent 35506c6 commit 3cf8960

4 files changed

Lines changed: 63 additions & 50 deletions

File tree

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"ignoretz",
99
"PYPI",
1010
"pytest",
11-
"serie_number"
11+
"serie_number",
12+
"Tago"
1213
]
1314
}

src/tagoio_sdk/modules/Analysis/Analysis.py

Lines changed: 58 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -44,50 +44,69 @@ def my_analysis(context, scope):
4444
# Your analysis logic here
4545
print("Processing data...")
4646
47-
analysis = Analysis(my_analysis, {"token": "your-analysis-token"})
47+
Analysis.use(analysis=my_analysis, params={"token": "your-analysis-token"})
4848
```
4949
50-
Example: Environment variables
50+
Example: Analysis with EU region
5151
```python
52+
from tagoio_sdk import Analysis
53+
5254
def my_analysis(context, scope):
53-
env = context.environment
54-
api_key = next((e["value"] for e in env if e["key"] == "API_KEY"), None)
55+
context.log("Running in EU region")
56+
print("Environment:", context.environment)
57+
58+
# Using Analysis.use() method
59+
Analysis.use(analysis=my_analysis, params={"token": "your-analysis-token", "region": "eu-w1"})
60+
```
5561
56-
analysis = Analysis(my_analysis)
62+
Example: Analysis with Tago Deploy
63+
```python
64+
from tagoio_sdk import Analysis
65+
66+
def my_analysis(context, scope):
67+
context.log("Running in TDeploy")
68+
print("Scope:", scope)
69+
70+
# Tago Deploy requires a dictionary with tdeploy ID
71+
Analysis.use(
72+
analysis=my_analysis,
73+
params={
74+
"token": "your-analysis-token",
75+
"region": {"tdeploy": "your-tdeploy-id"}
76+
}
77+
)
5778
```
5879
59-
Example: Manual start control
80+
Example: Environment variables
6081
```python
61-
analysis = Analysis(my_analysis, {
62-
"token": "token",
63-
"autostart": False
64-
})
82+
def my_analysis(context, scope):
83+
env = context.environment
84+
api_key = next((e["value"] for e in env if e["key"] == "API_KEY"), None)
6585
66-
# Start analysis manually
67-
analysis.start()
86+
Analysis.use(analysis=my_analysis, params={"token": "your-analysis-token"})
6887
```
6988
"""
7089

71-
def __init__(self, analysis: AnalysisFunction, params: Optional[AnalysisConstructorParams] = None):
90+
def __init__(self, params: Optional[AnalysisConstructorParams] = None):
7291
if params is None:
7392
params = {"token": "unknown"}
7493

7594
super().__init__(params)
7695
self.params = params
77-
self.analysis = analysis
78-
self.started = False
7996
self._running = True
8097

81-
if params.get("autostart", True):
82-
self.start()
98+
def init(self, analysis: AnalysisFunction):
99+
self.analysis = analysis
83100

84-
def start(self) -> None:
85-
if self.started:
86-
return
101+
if not os.environ.get("T_ANALYSIS_TOKEN") and self.params.get("token"):
102+
os.environ["T_ANALYSIS_TOKEN"] = self.params.get("token")
87103

88-
self.started = True
104+
# Configure runtime region
105+
runtimeRegion = getRegionObj(self.params["region"]) if self.params.get("region") else None
106+
if runtimeRegion:
107+
setRuntimeRegion(runtimeRegion)
89108

90-
if not os.environ.get("T_ANALYSIS_CONTEXT"):
109+
if T_ANALYSIS_CONTEXT is None:
91110
self._localRuntime()
92111
else:
93112
self._runOnTagoIO()
@@ -96,13 +115,13 @@ def _runOnTagoIO(self) -> None:
96115
if not self.analysis or not callable(self.analysis):
97116
raise TypeError("Invalid analysis function")
98117

99-
# Create context object
100-
context = {
101-
"log": print,
102-
"token": os.environ.get("T_ANALYSIS_TOKEN", ""),
103-
"environment": JSONParseSafe(os.environ.get("T_ANALYSIS_ENV", "[]"), []),
104-
"analysis_id": os.environ.get("T_ANALYSIS_ID", ""),
105-
}
118+
def context():
119+
pass
120+
121+
context.log = print
122+
context.token = os.environ.get("T_ANALYSIS_TOKEN", "")
123+
context.analysis_id = (JSONParseSafe(os.environ.get("T_ANALYSIS_ENV", "[]"), []),)
124+
context.environment = (os.environ.get("T_ANALYSIS_ID", ""),)
106125

107126
data = JSONParseSafe(os.environ.get("T_ANALYSIS_DATA", "[]"), [])
108127

@@ -148,12 +167,13 @@ def log(*args: Any) -> None:
148167
except Exception as e:
149168
print(f"Console error: {e}", file=sys.stderr)
150169

151-
context = {
152-
"log": log,
153-
"token": token,
154-
"environment": environment,
155-
"analysis_id": analysisID,
156-
}
170+
def context():
171+
pass
172+
173+
context.log = log
174+
context.token = token
175+
context.environment = environment
176+
context.analysis_id = analysisID
157177

158178
# Execute analysis function
159179
if inspect.iscoroutinefunction(self.analysis):
@@ -180,7 +200,7 @@ def _localRuntime(self) -> None:
180200
analysis = None
181201

182202
if not analysis:
183-
print("¬ Error :: Analysis not found or not active.", file=sys.stderr)
203+
print("¬ Error :: Analysis not found or not active or invalid analysis token.", file=sys.stderr)
184204
return
185205

186206
if analysis.get("run_on") != "external":
@@ -220,7 +240,7 @@ def _localRuntime(self) -> None:
220240
payload.get("environment", []),
221241
payload.get("data", []),
222242
payload.get("analysis_id", ""),
223-
payload.get("token", self.params.get("token", "")),
243+
self.token,
224244
)
225245
except Exception as e:
226246
print(f"¬ Error processing event: {e}", file=sys.stderr)
@@ -256,12 +276,4 @@ def my_analysis(context, scope):
256276
if params is None:
257277
params = {"token": "unknown"}
258278

259-
if not os.environ.get("T_ANALYSIS_TOKEN") and params.get("token"):
260-
os.environ["T_ANALYSIS_TOKEN"] = params["token"]
261-
262-
# Configure runtime region
263-
runtimeRegion = params.get("region") if getRegionObj(params.get("region")) else None
264-
if runtimeRegion:
265-
setRuntimeRegion(runtimeRegion)
266-
267-
return Analysis(analysis, params)
279+
return Analysis(params).init(analysis)

src/tagoio_sdk/modules/Analysis/Analysis_Type.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class AnalysisConstructorParams(TypedDict, total=False):
4545
AnalysisID = str
4646

4747

48-
class TagoContext(TypedDict):
48+
class TagoContext:
4949
"""
5050
TagoIO Analysis Context interface.
5151
As current version of the SDK doesn't provide the full TagoContext interface.

src/tagoio_sdk/modules/Resources/Analyses.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,10 @@ def listSnippets(self, runtime: SnippetRuntime) -> SnippetsListResponse:
343343
@example:
344344
```python
345345
resources = Resources()
346-
deno_snippets = resources.analyses.listSnippets("deno-rt2025")
346+
python_snippets = resources.analyses.listSnippets("python-rt2025")
347347
348348
# Print all snippet titles
349-
for snippet in deno_snippets["snippets"]:
349+
for snippet in python_snippets["snippets"]:
350350
print(f"{snippet['title']}: {snippet['description']}")
351351
```
352352

0 commit comments

Comments
 (0)