GX-TXT 0.9.8.10-dev-031
analysis.python_script 1.1.0
Python Script Client v1
Guida in italiano

GX-TXT — Guida completa agli script Python nel viewer dedicato

Uso del Python Script Workspace, Script Registry, contesto di Sessione, Dataset API, NumPy, servizi numerici, pubblicazione di Dataset e file, Plot Dataset, parallelismo e provenance.

Riferimento tecnico verificato sulla copia di raccolta del server: GX-TXT 0.9.8.10-dev-031.

Indice

1. Scopo e modello mentale

analysis.python_script consente di usare Python come ambiente di analisi scientifica integrato in GX-TXT senza dover creare immediatamente un plugin completo. Lo script viene registrato, associato a una Sessione, eseguito tramite il runtime Python configurato dal framework e può accedere ai dati e ai servizi di GX-TXT esclusivamente attraverso API pubbliche script-callable.

Principio fondamentale
Uno script Python GX-TXT non deve cercare file nella struttura interna della Sessione e non deve importare moduli interni del framework. Deve ottenere identità e dati attraverso il client pubblico gxtxt e le API registrate.

Il flusso corretto è:

  1. registrare lo script;
  2. assegnarlo alla Sessione;
  3. leggere gxtxt_context();
  4. verificare le API necessarie;
  5. leggere Dataset tramite Dataset ID e Variable ID;
  6. elaborare i dati con Python/NumPy/SciPy o con servizi GX-TXT;
  7. pubblicare risultati attraverso le API di pubblicazione;
  8. creare grafici tramite Plot Dataset quando necessario.

2. Architettura del sistema Python

ComponenteFunzione
Python Script WorkspaceEditor dedicato dei sorgenti .py.
CORE Script RegistryGestisce ID stabile, lingua, versione, revisione, SHA-256, parametri e API richieste.
CORE Script ExecutionVerifica il sorgente, crea uno snapshot immutabile ed esegue lo script.
runtime.pythonInterprete Python effettivamente usato dal framework e relativo ambiente scientifico.
Python Script ClientPackage pubblico gxtxt che espone contesto, discovery e chiamate API.
Script BridgeTrasporto condiviso con Octave verso i provider pubblici GX-TXT.

Per ragioni di compatibilità storica il metadata del bridge conserva l’identificatore OCTAVE_SCRIPT_BRIDGE_API_v1, ma lo stesso bridge è usato anche dal client Python. Il contesto indica la lingua corrente e i provider dichiarano le lingue supportate.

Python non usa la modalità external_file
Nella build verificata il modulo analysis.python_script esegue script registrati. A differenza del modulo Octave, non espone la modalità Analysis external_file. Il percorso normale e riproducibile è session:<script_id>.

3. Python Script Workspace

Con una Sessione aperta:

  1. abilitare il modulo Python Script;
  2. aprire Viewers → Python Script Workspace;
  3. scegliere New;
  4. selezionare scope User o Session;
  5. impostare Script ID, nome, versione semantica, descrizione, API richieste e parametri tipizzati;
  6. scrivere o importare il sorgente .py;
  7. salvare.

L’editor fornisce numeri di riga, evidenziazione Python, undo/redo, ricerca avanti/indietro, vai-a-riga, UTF-8, import/export .py e aiuto sul bridge pubblico.

3.1 Run registered

Il comando Run registered... usa il dialogo CORE Script Execution già esistente. I parametri tipizzati dichiarati nel Registry vengono validati prima dell’esecuzione.

3.2 Eliminazione

La cancellazione passa attraverso il lifecycle comune delle risorse. GX-TXT può rifiutare la cancellazione quando esistono dipendenze Analysis attive; gli snapshot storici delle esecuzioni restano conservati.

4. Script Registry e scope

Ogni script possiede una vera identità GX-TXT. Il riferimento pubblico è:

user:my_script
session:my_script

Il filesystem non costituisce l’identità dello script registrato.

4.1 User script

Uno script User è una risorsa riutilizzabile. Può essere modificato nella libreria senza cambiare le copie già assegnate alle Sessioni.

4.2 Session script

Quando uno script User viene assegnato a una Sessione, GX-TXT crea una copia fisica Session-owned. Il sorgente diventa indipendente dal record User originale.

4.3 Revisione e SHA-256

Ogni modifica mantiene lo stable ID ma incrementa la revisione e modifica lo SHA-256. Il runner esegue sempre una copia verificata e registra l’identità completa nella provenance.

5. Il package pubblico gxtxt

Uno script importa le funzioni supportate dal package pubblico:

from gxtxt import (
    gxtxt_context,
    gxtxt_bridge_info,
    gxtxt_api_list,
    gxtxt_api_has,
    gxtxt_api_describe,
    gxtxt_api_has_operation,
    gxtxt_api_require,
    gxtxt_api_call,
    GXTXTBridgeError,
    gxtxt_callback_register,
    gxtxt_callback_release,
)

Lo script non avvia il bridge: lifecycle, endpoint e chiusura appartengono al framework.

5.1 Primo script

from gxtxt import gxtxt_context, gxtxt_bridge_info, gxtxt_api_list

print(gxtxt_bridge_info())

ctx = gxtxt_context()
print(ctx)

apis = gxtxt_api_list()
print(f"API pubbliche disponibili: {len(apis)}")

for api in apis:
    print(api)

6. Contesto di esecuzione e input

gxtxt_context() restituisce un dizionario con informazioni relative al run. Fra i campi rilevanti:

6.1 Dataset associato a primary

from gxtxt import gxtxt_context

ctx = gxtxt_context()

primary = ctx["inputs"]["primary"]
dataset_id = primary["dataset_id"]

print("Dataset:", dataset_id)
Non ricostruire il percorso
Il contesto fornisce il Dataset ID, non il percorso privato di storage. Il Dataset va letto tramite CANONICAL_DATASET_API_v2.

7. Discovery e preflight delle API

La disponibilità di una funzione non va dedotta dalla presenza di file nel framework. Va interrogato il bridge.

from gxtxt import (
    gxtxt_api_has,
    gxtxt_api_has_operation,
    gxtxt_api_describe,
    gxtxt_api_require,
)

api_id = "CANONICAL_DATASET_API_v2"

if not gxtxt_api_has(api_id):
    raise RuntimeError(f"API assente: {api_id}")

desc = gxtxt_api_describe(api_id)
print(desc)

if not gxtxt_api_has_operation(api_id, "read_range"):
    raise RuntimeError("read_range non disponibile")

gxtxt_api_require("CANONICAL_DATASET_API_v2@2")

7.1 Requisiti multipli

gxtxt_api_require([
    "CANONICAL_DATASET_API_v2@2",
    "DATASET_VARIABLE_SCHEMA_API_v3@3",
    "NUMERIC_API_v1@1:math.numeric",
])

Le dichiarazioni possono includere versione, provider e capability:

PLOT_DATASET_API_v3@3:plot.dataset+plotspec|render

8. Leggere Dataset canonici

CANONICAL_DATASET_API_v2 è la superficie pubblica backend-neutral. Uno script non deve sapere se il Dataset sottostante è CSV, HDF5 o fornito da un backend futuro.

OperazioneArgomenti PythonRisultato
list[]Lista di Dataset ID.
describe[dataset_id]Dizionario di metadati.
read_range[dataset_id, variable_ids, start0, count]Dizionario indicizzato per Variable ID.

8.1 Elenco dei Dataset

from gxtxt import gxtxt_api_call

dataset_ids = gxtxt_api_call(
    "CANONICAL_DATASET_API_v2",
    "list",
    [],
)

for dataset_id in dataset_ids:
    print(dataset_id)

8.2 Descrizione

description = gxtxt_api_call(
    "CANONICAL_DATASET_API_v2",
    "describe",
    [dataset_id],
)

print(description)

8.3 Lettura di un intervallo

block = gxtxt_api_call(
    "CANONICAL_DATASET_API_v2",
    "read_range",
    [dataset_id, ["v0001", "v0002"], 0, 1000],
)

x = block["v0001"]["values"]
y = block["v0002"]["values"]

Il parametro start è zero-based secondo il contratto Dataset. Per Dataset grandi usare letture limitate anziché richiedere automaticamente l’intero payload.

9. Schema delle variabili

DATASET_VARIABLE_SCHEMA_API_v3 permette di lavorare con identità stabili e metadati tipizzati.

variables = gxtxt_api_call(
    "DATASET_VARIABLE_SCHEMA_API_v3",
    "list",
    [dataset_id],
)

for variable in variables:
    print(variable)

Per una singola variabile:

v = gxtxt_api_call(
    "DATASET_VARIABLE_SCHEMA_API_v3",
    "get",
    [dataset_id, "v0001"],
)

print(v)

Il descrittore può includere dtype, rank, shape, dimensioni, coordinate, asse uniforme, ruolo della coordinata, group ID e componenti.

Identità scientifica
Usare sempre Dataset ID + Variable ID. Header CSV, label leggibili e numero di colonna non devono essere usati come identità persistenti.

10. NumPy e trasporto numerico

Quando NumPy è installato nel runtime.python, i vettori e le matrici numeriche restituiti dal bridge sono normalmente numpy.ndarray. Senza NumPy vengono restituiti come liste Python.

import numpy as np

block = gxtxt_api_call(
    "CANONICAL_DATASET_API_v2",
    "read_range",
    [dataset_id, ["v0001"], 0, 1000],
)

values = np.asarray(block["v0001"]["values"]).reshape(-1)

print(values.shape)
print(values.dtype)

10.1 Array grandi

Per payload numerici superiori alla soglia interna di 10.000 elementi, il bridge usa automaticamente un trasporto binario privato little-endian. Lo script continua a ricevere normali array Python/NumPy e non deve gestire file temporanei.

10.2 Forma delle matrici

Gli array NumPy mantengono la shape nel trasporto verso il bridge. Il contratto è compatibile con la rappresentazione matriciale usata dal client Octave.

10.3 Interi

Gli scalari interi mantengono la loro identità di intero. Il trasporto degli array numerici usa il formato numerico previsto dal bridge, attualmente float64 per il payload numerico generico.

11. Calcolo con NUMERIC_API_v1

Python può svolgere calcoli direttamente con NumPy/SciPy, ma può anche usare NUMERIC_API_v1 quando si desidera un servizio numerico GX-TXT pubblico, condiviso con gli altri consumer del framework.

11.1 Operazione su array

operand = {
    "kind": "vector",
    "value": [-2.0, -1.0, 0.0, 1.0, 2.0],
}

result = gxtxt_api_call(
    "NUMERIC_API_v1",
    "array_unary",
    ["abs", operand],
)

print(result["values"])

11.2 Operazione binaria

a = {"kind": "vector", "value": [1.0, 2.0, 3.0]}
b = {"kind": "scalar", "value": 4.0}

result = gxtxt_api_call(
    "NUMERIC_API_v1",
    "array_binary",
    ["multiply", a, b],
)

print(result["values"])

11.3 Algebra lineare complessa

A = {"real": [[2.0, 1.0], [1.0, 3.0]]}
B = {"real": [[1.0], [2.0]]}

result = gxtxt_api_call(
    "NUMERIC_API_v1",
    "linear_matrix",
    ["solve", A, B],
)

solution = result["value_real"]
print(solution)

11.4 Mathematical Foundation

gxtxt_api_require(
    "NUMERIC_API_v1@1:math.numeric+mathematical_foundation"
)

a = {
    "kind": "array",
    "shape": [2, 1],
    "real": [1.0, 2.0],
}
b = {
    "kind": "array",
    "shape": [2, 1],
    "real": [3.0, 4.0],
}
empty = {"kind": "empty"}

result = gxtxt_api_call(
    "NUMERIC_API_v1",
    "foundation",
    ["vector", "dot", a, b, empty],
)

print(result)

La Mathematical Foundation comprende, fra gli altri, vettori, tensori, griglie, interpolazione, famiglie di curve, calcolo, ODE, ottimizzazione vincolata, geometria, sparse, statistiche e funzioni speciali.

12. Unità di misura

UNIT_REGISTRY_API_v1 centralizza compatibilità e conversione.

compatible = gxtxt_api_call(
    "UNIT_REGISTRY_API_v1",
    "compatible",
    ["mV", "V"],
)

if not compatible:
    raise ValueError("Unità incompatibili")

values_v = gxtxt_api_call(
    "UNIT_REGISTRY_API_v1",
    "convert",
    [[1000.0, 2500.0, 5000.0], "mV", "V"],
)

print(values_v)

Le unità non riconosciute possono restare opache. GX-TXT non inventa conversioni scientifiche non dichiarate.

13. Pubblicare Dataset strutturati

Per creare un nuovo Dataset scientifico strutturato usare DATASET_PUBLICATION_API_v2. La pubblicazione è transazionale.

13.1 Lifecycle

begin
declare_dimension
declare_variable
write_variable / append
finalize

In caso di errore, usare abort.

13.2 Esempio completo

from gxtxt import gxtxt_api_call, gxtxt_api_require

gxtxt_api_require("DATASET_PUBLICATION_API_v2@2")

definition = {
    "dataset_id": "derived_example",
    "contract": "table.generic",
    "storage": "auto",
    "producer_version": "1.0.0",
}

writer = gxtxt_api_call(
    "DATASET_PUBLICATION_API_v2",
    "begin",
    [definition],
)

try:
    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "declare_dimension",
        [writer, "row", 5, {}],
    )

    schema_x = {
        "dtype": "float64",
        "rank": 1,
        "dimension_ids": ["row"],
        "coordinate_role": "data",
    }

    schema_y = dict(schema_x)

    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "declare_variable",
        [writer, "x", schema_x],
    )

    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "declare_variable",
        [writer, "y", schema_y],
    )

    x = [0.0, 1.0, 2.0, 3.0, 4.0]
    y = [v * v for v in x]

    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "write_variable",
        [writer, "x", x, [5]],
    )

    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "write_variable",
        [writer, "y", y, [5]],
    )

    published = gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "finalize",
        [writer],
    )

    print(published)

except Exception:
    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "abort",
        [writer],
    )
    raise
Perché non scrivere direttamente nei Dataset
La Publication API seleziona il backend, valida schema e dimensioni, crea staging, calcola SHA-256, effettua il posizionamento atomico e aggiorna il Dataset Registry solo dopo il successo completo.

14. Pubblicare file prodotti dallo script

Quando lo script produce un file scientifico completo — per esempio testo, JSON, immagine scientifica o un formato binario definito dal progetto — può pubblicarlo tramite DATASET_FILE_PUBLICATION_API_v1.

Il file deve essere completato e trovarsi dentro gxtxt_context()["output_dir"].

14.1 Esempio

from pathlib import Path
from gxtxt import gxtxt_context, gxtxt_api_call

ctx = gxtxt_context()

output_dir = Path(ctx["output_dir"])
output_file = output_dir / "summary.txt"

output_file.write_text(
    "Analysis completed\n",
    encoding="utf-8",
)

request = {
    "dataset_id": "analysis_summary",
    "contract": "document.text",
    "format": "txt",
    "source_file": str(output_file),
    "storage_kind": "text",
    "media_type": "text/plain",
    "producer_version": "1.0.0",
}

result = gxtxt_api_call(
    "DATASET_FILE_PUBLICATION_API_v1",
    "publish",
    [request],
)

print(result)

Il bridge verifica che source_file sia realmente dentro la directory di output assegnata allo script. Il risultato espone Dataset ID e SHA-256 autorevole, ma non il percorso interno di storage.

output_dir non è una cartella generica
Serve per i file prodotti dal run corrente destinati alla pubblicazione. Non va usata per scoprire o modificare dati interni della Sessione.

15. Creare grafici con Plot Dataset

La facciata corrente è PLOT_DATASET_API_v3, fornita da plot.dataset 3.12.0 nella build verificata. Lo script crea un PlotSpec pubblico e lo lega a Dataset/Variable ID.

15.1 Creare un PlotSpec

spec = gxtxt_api_call(
    "PLOT_DATASET_API_v3",
    "new_spec",
    ["plot.dataset.xy", "Temperature"],
)

print(spec)

15.2 Aggiungere una serie

panel = spec["panels"][0]

panel["series"] = [
    {
        "id": "temperature",
        "dataset_id": "reactor",
        "x_variable_id": "v0001",
        "y_variable_id": "v0002",
        "axis": "left",
        "kind": "line",
        "label": "Temperature",
    }
]

spec["panels"] = [panel]

15.3 Validare, creare/aggiornare e renderizzare

valid = gxtxt_api_call(
    "PLOT_DATASET_API_v3",
    "validate_spec",
    [spec],
)

if not valid:
    raise ValueError("PlotSpec non valido")

plot_ref = gxtxt_api_call(
    "PLOT_DATASET_API_v3",
    "upsert_plot",
    ["main_result", spec],
)

render_result = gxtxt_api_call(
    "PLOT_DATASET_API_v3",
    "render",
    [plot_ref],
)

artifacts = gxtxt_api_call(
    "PLOT_DATASET_API_v3",
    "artifacts",
    [plot_ref],
)

print(render_result)
print(artifacts)

La chiave passata a upsert_plot viene automaticamente scoped al modulo dello script dal binding. Rerun successivi possono quindi aggiornare la stessa identità persistente.

Grafico riproducibile
Il PlotSpec contiene riferimenti scientifici tramite Dataset ID e Variable ID. Il PNG finale è un artifact di rendering, non l’identità del grafico.

16. Dataset grandi e streaming

Per dataset grandi esistono due strategie principali.

16.1 Range bounded

chunk_rows = 50000
start = 0

while True:
    block = gxtxt_api_call(
        "CANONICAL_DATASET_API_v2",
        "read_range",
        [dataset_id, ["v0001", "v0002"], start, chunk_rows],
    )

    # Elaborare il blocco e usare i metadati restituiti
    # per determinare quanti elementi sono stati letti.

    # break quando non rimangono altre righe
    start += chunk_rows

16.2 TABLE_STREAM_API_v3

Il bridge espone:

open_dataset
metadata
next
diagnostics
close

È la scelta adatta quando l’algoritmo deve consumare un Dataset tabellare come stream, mantenendo memoria limitata e senza conoscere il backend fisico.

17. Parallelismo Python e policy CORE

Python può usare concurrent.futures, multiprocessing o librerie scientifiche proprie. Prima di creare worker deve però leggere la policy pubblica di GX-TXT.

policy = gxtxt_api_call(
    "PARALLEL_EXECUTION_API_v1",
    "resources",
    [],
)

print(policy)

La policy corrente espone almeno stato, worker predefiniti, massimo consentito e raccomandazione sui thread numerici interni.

17.1 Calcolo del numero di worker

requested = 8

if policy["enabled"]:
    workers = min(
        requested,
        int(policy["default_workers"]),
        int(policy["max_workers"]),
    )
else:
    workers = 1

print("Workers:", workers)

17.2 Esempio con ThreadPoolExecutor

from concurrent.futures import ThreadPoolExecutor

def work(item):
    return item * item

items = list(range(20))

if workers == 1:
    results = [work(item) for item in items]
else:
    with ThreadPoolExecutor(max_workers=workers) as pool:
        results = list(pool.map(work, items))

Per workload CPU-bound il ricercatore può scegliere processi o librerie native appropriate. L’importante è rispettare il limite CORE, chiudere i pool e mantenere un ramo seriale valido.

Nessun command execution arbitrario dal bridge
La Script Bridge API espone la policy di risorse, non un generatore arbitrario di processi host. I processi creati direttamente dallo script Python restano normali processi del runtime del ricercatore e devono essere gestiti responsabilmente.

18. Progress e servizi di Sessione

18.1 Pubblicare progress

PROGRESS_API_v1 espone l’operazione publish con un dizionario evento.

event = {
    "state": "running",
    "mode": "determinate",
    "stage": "processing",
    "message": "Processing rows",
    "current": 250,
    "total": 1000,
}

gxtxt_api_call(
    "PROGRESS_API_v1",
    "publish",
    [event],
)

Il progress è uno stato sintetico, non un canale di log. Traceback, warning e diagnostica restano output ordinario.

18.2 Ispezione della Sessione

summary = gxtxt_api_call(
    "SESSION_INSPECTION_API_v1",
    "summary",
    [],
)

dataset_ids = gxtxt_api_call(
    "SESSION_INSPECTION_API_v1",
    "dataset_ids",
    [],
)

print(summary)
print(dataset_ids)

18.3 Commit

Quando un flusso pubblico richiede un commit esplicito:

commit_result = gxtxt_api_call(
    "SESSION_PERSISTENCE_API_v1",
    "commit",
    [],
)

Non chiamare commit come sostituto delle API transazionali specifiche: Dataset Publication e altri servizi gestiscono già il proprio lifecycle.

19. Tutorial passo passo

Tutorial A — Creare il primo script registrato

  1. Aprire una Sessione.
  2. Aprire Python Script Workspace.
  3. Creare uno script Session.
  4. Usare ID hello_gxtxt.
  5. Salvare il codice seguente.
  6. Avviare Run registered....
from gxtxt import gxtxt_context, gxtxt_bridge_info

print(gxtxt_bridge_info())

ctx = gxtxt_context()

print("Run:", ctx["run_id"])
print("Script:", ctx["script_name"])
print("Language:", ctx["script_language"])

Tutorial B — Usare il Dataset associato a primary

import numpy as np

from gxtxt import (
    gxtxt_context,
    gxtxt_api_require,
    gxtxt_api_call,
)

gxtxt_api_require([
    "CANONICAL_DATASET_API_v2@2",
    "DATASET_VARIABLE_SCHEMA_API_v3@3",
])

ctx = gxtxt_context()
dataset_id = ctx["inputs"]["primary"]["dataset_id"]

if not dataset_id:
    raise RuntimeError("Nessun Dataset associato a primary")

description = gxtxt_api_call(
    "CANONICAL_DATASET_API_v2",
    "describe",
    [dataset_id],
)

variables = gxtxt_api_call(
    "DATASET_VARIABLE_SCHEMA_API_v3",
    "list",
    [dataset_id],
)

print(description)
for variable in variables:
    print(variable)

block = gxtxt_api_call(
    "CANONICAL_DATASET_API_v2",
    "read_range",
    [dataset_id, ["v0001"], 0, 100],
)

values = np.asarray(block["v0001"]["values"]).reshape(-1)

print(values)

Tutorial C — Calcolo NumPy e pubblicazione del risultato

import numpy as np
from gxtxt import gxtxt_api_call

x = np.linspace(0.0, 10.0, 101)
y = np.sin(x)

definition = {
    "dataset_id": "sine_result",
    "contract": "table.generic",
    "storage": "auto",
    "producer_version": "1.0.0",
}

writer = gxtxt_api_call(
    "DATASET_PUBLICATION_API_v2",
    "begin",
    [definition],
)

try:
    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "declare_dimension",
        [writer, "row", int(x.size), {}],
    )

    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "declare_variable",
        [writer, "x", {
            "dtype": "float64",
            "rank": 1,
            "dimension_ids": ["row"],
            "coordinate_role": "coordinate",
        }],
    )

    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "declare_variable",
        [writer, "sin_x", {
            "dtype": "float64",
            "rank": 1,
            "dimension_ids": ["row"],
            "coordinate_role": "data",
        }],
    )

    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "write_variable",
        [writer, "x", x, [int(x.size)]],
    )

    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "write_variable",
        [writer, "sin_x", y, [int(y.size)]],
    )

    published = gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "finalize",
        [writer],
    )

except Exception:
    gxtxt_api_call(
        "DATASET_PUBLICATION_API_v2",
        "abort",
        [writer],
    )
    raise

print(published)

Tutorial D — Pubblicare un report testuale

from pathlib import Path
from gxtxt import gxtxt_context, gxtxt_api_call

ctx = gxtxt_context()
path = Path(ctx["output_dir"]) / "report.txt"

path.write_text(
    "Mean = 1.234\nStandard deviation = 0.056\n",
    encoding="utf-8",
)

published = gxtxt_api_call(
    "DATASET_FILE_PUBLICATION_API_v1",
    "publish",
    [{
        "dataset_id": "analysis_report",
        "contract": "document.text",
        "format": "txt",
        "source_file": str(path),
        "storage_kind": "text",
        "media_type": "text/plain",
        "producer_version": "1.0.0",
    }],
)

print(published)

Tutorial E — Creare il grafico del Dataset pubblicato

spec = gxtxt_api_call(
    "PLOT_DATASET_API_v3",
    "new_spec",
    ["plot.dataset.xy", "Sine function"],
)

panel = spec["panels"][0]
panel["series"] = [{
    "id": "sine",
    "dataset_id": "sine_result",
    "x_variable_id": "x",
    "y_variable_id": "sin_x",
    "axis": "left",
    "kind": "line",
    "label": "sin(x)",
}]
spec["panels"] = [panel]

if not gxtxt_api_call(
    "PLOT_DATASET_API_v3",
    "validate_spec",
    [spec],
):
    raise RuntimeError("PlotSpec validation failed")

plot_ref = gxtxt_api_call(
    "PLOT_DATASET_API_v3",
    "upsert_plot",
    ["sine_plot", spec],
)

gxtxt_api_call(
    "PLOT_DATASET_API_v3",
    "render",
    [plot_ref],
)

artifacts = gxtxt_api_call(
    "PLOT_DATASET_API_v3",
    "artifacts",
    [plot_ref],
)

print(artifacts)

Tutorial F — Gestire un errore del bridge

from gxtxt import gxtxt_api_call, GXTXTBridgeError

try:
    result = gxtxt_api_call(
        "CANONICAL_DATASET_API_v2",
        "describe",
        ["dataset_that_does_not_exist"],
    )
except GXTXTBridgeError as exc:
    print("GX-TXT API error")
    print(exc)
    raise

Tutorial G — Script scientifico completo: struttura consigliata

import numpy as np

from gxtxt import (
    gxtxt_context,
    gxtxt_api_require,
    gxtxt_api_call,
)

# 1. Requisiti pubblici
gxtxt_api_require([
    "CANONICAL_DATASET_API_v2@2",
    "DATASET_VARIABLE_SCHEMA_API_v3@3",
    "DATASET_PUBLICATION_API_v2@2",
    "PLOT_DATASET_API_v3@3:plot.dataset",
])

# 2. Contesto
ctx = gxtxt_context()
dataset_id = ctx["inputs"]["primary"]["dataset_id"]

# 3. Schema / identità
schema = gxtxt_api_call(
    "DATASET_VARIABLE_SCHEMA_API_v3",
    "list",
    [dataset_id],
)

# 4. Lettura
# block = gxtxt_api_call(...)

# 5. Calcolo NumPy / SciPy
# result = ...

# 6. Pubblicazione Dataset
# writer = ...

# 7. Plot persistente
# spec = ...
# plot_ref = ...

# 8. Eventuale file aggiuntivo in ctx["output_dir"]

20. Errori e troubleshooting

20.1 Script non visibile nel modulo Analysis

20.2 ImportError per NumPy/SciPy

Il viewer non installa automaticamente librerie Python. Lo script usa il runtime.python configurato. Un package assente genera il normale traceback Python.

20.3 API sconosciuta

print(gxtxt_api_list())
print(gxtxt_api_describe("CANONICAL_DATASET_API_v2"))

20.4 Operazione non disponibile

if not gxtxt_api_has_operation(
    "PLOT_DATASET_API_v3",
    "upsert_plot",
):
    raise RuntimeError("upsert_plot non disponibile")

20.5 Errori GXTXTBridgeError

Il client usa identificatori stabili per categorie come:

20.6 Scrittura file rifiutata

Per DATASET_FILE_PUBLICATION_API_v1, il file deve esistere ed essere contenuto nella directory output_dir del run corrente.

20.7 Parametri di Script Registry

I parametri tipizzati vengono validati dal CORE prima dell’esecuzione. Non sostituire automaticamente i parametri strutturati con parsing manuale di una stringa quando il Registry offre già il relativo schema.

20.8 Report del run

Il modulo dichiara come output:

La Script Execution conserva inoltre log, execution metadata e provenance sotto analysis/scripts/ nella Sessione.

21. Riproducibilità e provenance

Un run registrato conserva:

Modificare successivamente la copia User non modifica i risultati già prodotti dalla Sessione.

22. Buone pratiche

  1. Non leggere registri interni o path privati. Usare il client pubblico.
  2. Usare Dataset ID + Variable ID.
  3. Fare preflight delle API.
  4. Usare gxtxt_api_describe() per conoscere il contratto runtime.
  5. Non assumere che NumPy o SciPy siano installati. Dipendono dal runtime configurato.
  6. Leggere Dataset grandi a blocchi o tramite Table Stream.
  7. Pubblicare Dataset strutturati tramite Publication API v2.
  8. Pubblicare file solo da output_dir.
  9. Usare Plot Dataset per grafici persistenti.
  10. Rispettare la policy CORE prima di creare pool di worker.
  11. Separare progress e logging.
  12. Trasformare lo script in modulo quando diventa una funzionalità stabile.

23. Riferimento rapido

23.1 Import minimo

from gxtxt import (
    gxtxt_context,
    gxtxt_api_require,
    gxtxt_api_call,
)

23.2 Import completo del client

from gxtxt import (
    gxtxt_context,
    gxtxt_bridge_info,
    gxtxt_api_list,
    gxtxt_api_has,
    gxtxt_api_describe,
    gxtxt_api_has_operation,
    gxtxt_api_require,
    gxtxt_api_call,
    GXTXTBridgeError,
    gxtxt_callback_register,
    gxtxt_callback_release,
)

23.3 API centrali

EsigenzaAPI
Dataset readCANONICAL_DATASET_API_v2
Variable schemaDATASET_VARIABLE_SCHEMA_API_v3
Dataset metadataDATASET_METADATA_API_v1
Dataset strutturato in outputDATASET_PUBLICATION_API_v2
File completato in outputDATASET_FILE_PUBLICATION_API_v1
NumericaNUMERIC_API_v1
Signal processingSIGNAL_API_v1
UnitàUNIT_REGISTRY_API_v1
GraficiPLOT_DATASET_API_v3
Dataset grandi tabellariTABLE_STREAM_API_v3
Risorse parallelePARALLEL_EXECUTION_API_v1
ProgressPROGRESS_API_v1
Session inspectionSESSION_INSPECTION_API_v1

23.4 Altri provider script-callable presenti in dev-023

La build verificata include inoltre provider per Temporal Set, Project, Interactive Document read, Graph Series inspection, Viewer Provider scene/layer, Scientific Reference Library, Semantic Registry, documentazione pubblica, RF network, signal processing e magnetics. La disponibilità effettiva va sempre verificata a runtime.

23.5 Riferimenti tecnici verificati

Versione di riferimento
Questa edizione è stata preparata contro GX-TXT 0.9.8.10-dev-031. In release successive, gxtxt_api_list() e gxtxt_api_describe() sono l’autorità runtime per API, provider, capability e operazioni disponibili.