@@ -165,22 +165,22 @@ geometric mean (depending on the signs of the input values).
```python
import math
-def granta_mean(value):
+def granta_mean(value: mpy.Range | None):
if value is None:
return None
- if "high" not in value:
- return value["low"]
- if "low" not in value:
- return value["high"]
- product = value["low"] * value["high"]
+ if value.high is None:
+ return value.low
+ if value.low is None:
+ return value.high
+ product = value.low * value.high
if product > 0:
gm = math.sqrt(product)
- if value["low"] > 0:
+ if value.low > 0:
return gm
else:
return -gm
else:
- return sum(value.values())/2
+ return sum([value.low, value.high]) / 2
```
Apply the `granta_mean` function to each cell in the *Density*, *Young's modulus*, *Tensile strength*, and *Electrical
@@ -449,7 +449,7 @@ separate `dict` that provides a simple mapping between column headings and units
units = {
mi_attr: material_universe.attributes[mi_attr].unit
for mi_attr in attributes
- if material_universe.attributes[mi_attr].unit
+ if getattr(material_universe.attributes[mi_attr], "unit", None) is not None
}
units
```
@@ -591,7 +591,8 @@ ax.scatter(
df_processed["Density"],
df_processed["Young's modulus"],
df_processed["Electrical resistivity"],
- s=50)
+ s=50,
+)
_ = ax.set_title(r"$\rho$ vs E vs Density")
```
@@ -603,7 +604,7 @@ _ = ax.set_title(r"$\rho$ vs E vs Density")
### Adding a continuous color axis to a 2D scatter plot
-Add a continuous color axis using the `c` and `cmap` arguments to the `plot.scatter()` constructor.
+Add a continuous color axis using the `c` and `cmap` arguments to the `plot.scatter()` constructor.
This example uses the optional `norm` argument to specify an alternative method of mapping numeric values to a color
in the colormap. The **color_norm** variable contains a logarithmic normalization which ensures color variation is
@@ -657,6 +658,7 @@ the continuous *Electrical resistivity* values to those categories.
```python
import numpy as np
+
min_value = df_processed["Electrical resistivity"].min()
max_value = df_processed["Electrical resistivity"].max()
@@ -664,9 +666,10 @@ max_value = df_processed["Electrical resistivity"].max()
spacing = np.geomspace(min_value, max_value, 6)
df_processed["Electrical resistivity (binned)"] = pd.cut(
- df_processed['Electrical resistivity'],
+ df_processed["Electrical resistivity"],
spacing,
- labels=['Very low', 'Low', 'Medium', 'High', 'Very high'],
+ labels=["Very low", "Low", "Medium", "High", "Very high"],
+ include_lowest=True,
)
df_processed.head()
```
@@ -710,7 +713,7 @@ df_processed.head()
Opaque
Al (Aluminum)
7075
-
NaN
+
Very low
00000e38-000e-4fff-8fff-dd92ffff0000
@@ -823,20 +826,12 @@ ax.set_xscale("log")
ax.set_xlabel(density_label)
ax.set_yscale("log")
ax.set_ylabel(ym_label)
-ax.set_title("E vs Density grouped by Base (using seaborn)")
-```
-
-
-
-*Previous cell output:*
-```output
-Text(0.5, 1.0, 'E vs Density grouped by Base (using seaborn)')
+_ = ax.set_title("E vs Density grouped by Base (using seaborn)")
```
-
-
+
@@ -878,8 +873,8 @@ g = sns.pairplot(
for i in range(len(g.axes)):
for j in range(len(g.axes[i])):
- g.axes[i,j].set_xscale("log")
- g.axes[i,j].set_yscale("log")
+ g.axes[i, j].set_xscale("log")
+ g.axes[i, j].set_yscale("log")
_ = g.fig.suptitle(r"Pair plot comparing Density, E, $F_{{{tu}}}$ and $\rho$, grouped by Base", y=1.03)
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_31_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_31_0.png
index 38ac59956b..47c9a80870 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_31_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_31_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_34_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_34_0.png
index 5c9e9ff3a8..cba14af988 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_34_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_34_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_37_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_37_0.png
index aca889cafe..5154b09dd4 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_37_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_37_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_40_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_40_0.png
index eb1fa9da04..f423b830be 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_40_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_40_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_43_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_43_0.png
index d6f96317cf..741ea8b324 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_43_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_43_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_48_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_48_0.png
index 7bae5cab79..428f3bff72 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_48_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_48_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_51_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_51_0.png
new file mode 100644
index 0000000000..8a4e9e4e4f
Binary files /dev/null and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_51_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_54_1.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_54_1.png
index e3ba85d921..d30f52bb74 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_54_1.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/00_Create_scatter_plots_files/00_Create_scatter_plots_54_1.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically.md
index 82ba1a90a1..468899f9d5 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically.md
@@ -9,14 +9,14 @@ Connect to MI and specify a database.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
db.unit_system = "Metric"
```
-Specify the records and attributes you want to export from the first table.
+Specify the records and attributes you want to export from the first table.
For this example, we need *Build ID* and *Travel Speed* for all records in the *AM Builds* table.
@@ -367,7 +367,7 @@ Finally, create a `units` dict so you can create plots with meaningful axis labe
```python
attr_defs = [am_builds.attributes[attr] for attr in build_attributes] + \
[tensile_test_data.attributes[attr] for attr in tensile_attributes]
-units = {attr.name: attr.unit for attr in attr_defs if attr.unit}
+units = {attr.name: attr.unit for attr in attr_defs if getattr(attr, "unit", None) is not None}
units
```
@@ -418,7 +418,7 @@ _ = ax.set_title("$F_{{tu}}$ vs Travel Speed")
There is a clear dependence of the *Ultimate Tensile Strength* on the *Travel Speed*. It is also clear that *Travel Speed*
-is an independent variable, with the values chosen for each build falling into a set of well-defined bins.
+is an independent variable, with the values chosen for each build falling into a set of well-defined bins.
Instead of judging the distribution by eye, we can use box plots to describe the distribution of values.
@@ -454,7 +454,7 @@ _ = ax.set_title("$F_{{tu}}$ vs Travel Speed (Violin Plot)")
### Investigate the impact of a third property
-The orientation of each specimen during the test was also exported, but not included on the plots above.
+The orientation of each specimen during the test was also exported, but not included on the plots above.
The simplest way to visualize this data is to add it to the original scatter plot as a color axis.
@@ -504,7 +504,7 @@ Name: count, dtype: int64
```
-There are only 7 values for 'AT', which is less than 10% of the overall dataset.
+There are only 7 values for 'AT', which is less than 10% of the overall dataset.
The code below creates a series of `True` or `False` values in `rows_to_keep` (set to `True` if the value is in the
specified list). `rows_to_keep` is then passed as a selector into the DataFrame, which maps the list onto the
@@ -512,7 +512,7 @@ DataFrame rows and returns a new DataFrame with only the `True` rows included.
```python
-rows_to_keep = df_processed["Specimen Orientation"].map(lambda x: x in ['L', 'LT'])
+rows_to_keep = df_processed["Specimen Orientation"].map(lambda x: x in ["L", "LT"])
df_L_or_LT = df_processed[rows_to_keep]
df_L_or_LT.head()
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_30_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_30_0.png
index ed0e933029..730e86c0b4 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_30_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_30_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_32_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_32_0.png
index 60565fc8d0..baeb604c77 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_32_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_32_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_34_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_34_0.png
index 289bfef1cb..f92a4727d6 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_34_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_34_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_37_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_37_0.png
index 0822003db4..93c536ee02 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_37_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_37_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_45_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_45_0.png
index 9d70ee8ea1..8c76316ed9 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_45_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/01_Compare_datasets_graphically_files/01_Compare_datasets_graphically_45_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category.md
index f03976d6e8..7f01198a36 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category.md
@@ -9,9 +9,9 @@ Connect to Granta MI and specify a database.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
db.unit_system = "Metric"
```
@@ -45,7 +45,8 @@ tensile_test_records = {tr for pr in pedigree_records for tr in pr.links[link_gr
tensile_test_records = list(tensile_test_records)
```
-Specify the attributes you want to export from the second table. *Panel number* will be used to relate the tensile tests to the layup data.
+Specify the attributes you want to export from the second table. *Panel number* will be used to relate the tensile
+tests to the layup data.
```python
@@ -198,14 +199,14 @@ tensile_df.head()
LBJ14
LBJ1413A
-
[]
+
NaN
1613.614663
0° tension
LBJ14
LBJ1415A
-
[]
+
NaN
1611.201497
0° tension
@@ -291,7 +292,7 @@ df.head()
1.431636
0.238044
LBJ1413A
-
[]
+
NaN
1613.614663
0° tension
@@ -301,7 +302,7 @@ df.head()
1.431636
0.238044
LBJ1415A
-
[]
+
NaN
1611.201497
0° tension
@@ -317,7 +318,7 @@ Finally, create a `units` dict so you can create plots with meaningful axis labe
```python
attr_defs = [comp_pedigree.attributes[attr] for attr in pedigree_attributes] + \
[tensile_test_data.attributes[attr] for attr in tensile_attributes]
-units = {attr.name: attr.unit for attr in attr_defs if attr.unit}
+units = {attr.name: attr.unit for attr in attr_defs if getattr(attr, "unit", None) is not None}
units
```
@@ -379,7 +380,7 @@ each column.
```python
-df.describe(include='all')
+df.describe(include="all")
```
@@ -406,7 +407,7 @@ df.describe(include='all')
67.000000
67.000000
67
-
67
+
18.000000
67.000000
67
@@ -416,7 +417,7 @@ df.describe(include='all')
NaN
NaN
67
-
19
+
NaN
NaN
2
@@ -426,7 +427,7 @@ df.describe(include='all')
NaN
NaN
LBJ1311A
-
[]
+
NaN
NaN
0° tension
@@ -436,7 +437,7 @@ df.describe(include='all')
NaN
NaN
1
-
49
+
NaN
NaN
56
@@ -446,7 +447,7 @@ df.describe(include='all')
1.534167
0.235604
NaN
-
NaN
+
42.775844
1288.110261
NaN
@@ -456,7 +457,7 @@ df.describe(include='all')
0.294450
0.005039
NaN
-
NaN
+
13.523385
557.743977
NaN
@@ -466,7 +467,7 @@ df.describe(include='all')
1.379415
0.229948
NaN
-
NaN
+
13.217251
44.629768
NaN
@@ -476,7 +477,7 @@ df.describe(include='all')
1.385455
0.231279
NaN
-
NaN
+
47.022249
1353.613343
NaN
@@ -486,7 +487,7 @@ df.describe(include='all')
1.410677
0.234618
NaN
-
NaN
+
47.973725
1545.653034
NaN
@@ -496,7 +497,7 @@ df.describe(include='all')
1.438564
0.240007
NaN
-
NaN
+
49.364743
1603.610369
NaN
@@ -506,7 +507,7 @@ df.describe(include='all')
2.213429
0.245727
NaN
-
NaN
+
51.400420
1639.559637
NaN
@@ -599,7 +600,7 @@ ax2.set_ylabel(ftu_90_label)
h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
-ax1.legend(h1+h2, [ftu_0_label, ftu_90_label], loc="lower right")
+ax1.legend(h1 + h2, [ftu_0_label, ftu_90_label], loc="lower right")
_ = ax1.set_title(r"$F_{tu}, 0^{{\circ}}$ and $90^{{\circ}}$ vs Average ply thickness")
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_28_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_28_0.png
index a05cbd4219..645738fa3b 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_28_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_28_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_36_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_36_0.png
index 41e0849e39..426cab0997 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_36_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_36_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_38_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_38_0.png
index ceebe1a6b0..02707e70e7 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_38_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/02_Plot_data_by_category_files/02_Plot_data_by_category_38_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/03_Fit_series_data_and_import.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/03_Fit_series_data_and_import.md
index b800a10a62..057f34873f 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/03_Fit_series_data_and_import.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/03_Fit_series_data_and_import.md
@@ -9,9 +9,9 @@ Specify a database and tables.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
statistics_table = db.get_table("Fatigue Statistical Data")
@@ -29,11 +29,11 @@ First, perform a criteria search to find the target record.
```python
criterion_type = statistics_table.attributes["Material type"].search_criterion(contains="Aluminum alloys")
criterion_status = statistics_table.attributes["Statistical Analysis Status"].search_criterion(contains="In Progress")
-records = statistics_table.search_for_records_where([criterion_type, criterion_status])
-print(f"Found {len(records)} corresponding HCF test results.")
+statistical_records = statistics_table.search_for_records_where([criterion_type, criterion_status])
+print(f"Found {len(statistical_records)} corresponding HCF test results.")
-r = records[0]
-print(f"Analyzing fatigue data for {r.name}.")
+record = statistical_records[0]
+print(f"Analyzing fatigue data for {record.name}.")
```
*Previous cell output:*
```output
@@ -50,36 +50,35 @@ the attribute values from the test result records into a `pandas` DataFrame for
import pandas as pd
import statistics
-r_ratio_mean = statistics.mean(r.attributes["Target R-Ratio Range"].value.values())
-test_temperature_mean = statistics.mean(r.attributes["Test Temperature Range"].value.values())
-material_id_value = f"{r.attributes['Alloy'].value}-{r.attributes['Condition'].value}/{r.attributes['Form'].value}"
+r_ratio = record.attributes["Target R-Ratio Range"].value
+r_ratio_mean = statistics.mean([r_ratio.low, r_ratio.high])
+test_temperature = record.attributes["Test Temperature Range"].value
+test_temperature_mean = statistics.mean([test_temperature.low, test_temperature.high])
+material_id_value = f"{record.attributes['Alloy'].value}-{record.attributes['Condition'].value}/{record.attributes['Form'].value}"
target_r_ratio = test_data_table.attributes["Target r-ratio"]
target_r_ratio_criterion = target_r_ratio.search_criterion(
less_than=r_ratio_mean,
greater_than=r_ratio_mean,
)
-test_temperature = test_data_table.attributes['Test temperature']
+test_temperature = test_data_table.attributes["Test temperature"]
test_temperature_criterion = test_temperature.search_criterion(
less_than=test_temperature_mean,
greater_than=test_temperature_mean,
)
-material_id = test_data_table.attributes['Material ID']
+material_id = test_data_table.attributes["Material ID"]
material_id_criterion = material_id.search_criterion(contains=material_id_value)
-records = test_data_table.search_for_records_where(
+test_records = test_data_table.search_for_records_where(
[target_r_ratio_criterion, test_temperature_criterion, material_id_criterion]
)
-print(f"Found {len(records)} corresponding HCF test results.")
+print(f"Found {len(test_records)} corresponding HCF test results.")
t_results = ["Cyclic life", "Maximum stress", "Fatigue failure"]
-test_data_table.bulk_fetch(
- records=records,
- attributes=t_results
-)
+test_data_table.bulk_fetch(records=test_records, attributes=t_results)
-rs_dict = {attribute: [r.attributes[attribute].value for r in records] for attribute in t_results}
-rs_dict.update({"ShortName": [r.short_name for r in records]})
+rs_dict = {attribute: [r.attributes[attribute].value for r in test_records] for attribute in t_results}
+rs_dict.update({"ShortName": [r.short_name for r in test_records]})
rs_df = pd.DataFrame(rs_dict)
```
@@ -90,7 +89,13 @@ Found 66 corresponding HCF test results.
## Fit the data
Fit the fatigue test data using the SciPy `curve_fit()` function, and create a new DataFrame for the fitted data and
-the lower bound.
+the lower bound. Define an expression for fitting as follows:
+
+
+
+To maximize the fit precision, normalize the y values to a single order of magnitude. The y values are of the order of
+100 MPa, so use a scale factor of 0.01. Based on the expression being used, multiplying by a scale factor
+requires adding log10 of the scale factor to the A1 result.
```python
@@ -98,36 +103,36 @@ from scipy.optimize import curve_fit
import numpy as np
def fatigue_func(x, A1, A2):
- return 10 **(A2 * np.log10(x) - A1)
-
+ return 10 ** (-A1) * x ** A2
+
+SCALE_FACTOR = 0.01
+
(A1, A2), pcov = curve_fit(
fatigue_func,
rs_df["Cyclic life"],
- rs_df["Maximum stress"],
+ rs_df["Maximum stress"] * SCALE_FACTOR,
bounds=([-500.0, -500.0], [500.0, 500.0]),
)
+A1 += np.log10(SCALE_FACTOR)
+
min_coefficient = 0.9
x = np.geomspace(
start=rs_df["Cyclic life"].min(),
stop=rs_df["Cyclic life"].max(),
num=rs_df["Cyclic life"].count(),
)
-fitted_series = 10 **(A2 * np.log10(x) - A1)
+fitted_series = 10 ** (-A1) * x ** A2
fitted_df = (
pd.DataFrame(
index=x,
- data=np.transpose([fitted_series, min_coefficient*fitted_series]),
+ data=np.transpose([fitted_series, min_coefficient * fitted_series]),
columns=["Fitted Data", "Minimum"],
)
.reset_index()
.melt(id_vars=["index"])
- .rename(columns={
- "index": "Cyclic life",
- "value": "Maximum stress",
- "variable": "Type"
- })
+ .rename(columns={"index": "Cyclic life", "value": "Maximum stress", "variable": "Type"})
)
fitted_df.head()
@@ -151,31 +156,31 @@ fitted_df.head()
0
5000.000000
Fitted Data
-
527.961774
+
527.961676
1
5870.634799
Fitted Data
-
520.792043
+
520.791950
2
6892.870589
Fitted Data
-
513.719678
+
513.719590
3
8093.105189
Fitted Data
-
506.743355
+
506.743272
4
9502.332991
Fitted Data
-
499.861771
+
499.861692
@@ -206,7 +211,7 @@ plt.show()
-
+
@@ -224,7 +229,7 @@ fig
-
+
@@ -236,42 +241,61 @@ fitted data. Use `Session.update()` to push the changes to Granta MI.
```python
-fit = r.attributes["Maximum Stress v Cycles (Equivalent Stress)"]
-fit.clear()
+fit = record.attributes["Maximum Stress v Cycles (Equivalent Stress)"]
fit.unit = test_data_table.attributes["Maximum stress"].unit
-for _, row in fitted_df.iterrows():
- point = {
- "y": row["Maximum stress"],
- "Number of Cycles": row["Cyclic life"],
- "Data Type": row["Type"],
- "Stress Ratio": r_ratio_mean,
- }
- fit.add_point(point)
-for _, row in rs_df.iterrows():
- point = {
- "y": row["Maximum stress"],
- "Number of Cycles": row["Cyclic life"],
- "Data Type": "Test Data",
- "Stress Ratio": r_ratio_mean,
- }
- fit.add_point(point)
-
-fit.series_linestyles[3] = "Markers"
-
-r.attributes["Equivalent Stress, A1"].value = A1
-r.attributes["Equivalent Stress, A2"].value = A2
-r.attributes["Statistical Analysis Status"].value = "Complete"
-r.set_attributes([
- r.attributes["Equivalent Stress, A1"],
- r.attributes["Equivalent Stress, A2"],
- # The status is not updated; this allows the notebook to be re-run.
- # r.attributes["Statistical Analysis Status"],
- fit
-])
-fit.value
-mi.update([r])
-print(f"Updated attributes in {r.name}.")
+fitted_data = fitted_df[fitted_df["Type"]=="Fitted Data"]
+series_fitted = mpy.SeriesPoint(
+ y=tuple(fitted_data["Maximum stress"]),
+ x=tuple(fitted_data["Cyclic life"]),
+ parameters=(
+ mpy.SeriesParameterValue("Data Type", "Fitted Data"),
+ mpy.SeriesParameterValue("Stress Ratio", r_ratio_mean),
+ ),
+ decoration=mpy.GraphDecoration.LINES,
+)
+
+minimum_data = fitted_df[fitted_df["Type"]=="Minimum"]
+series_minimum = mpy.SeriesPoint(
+ y=tuple(minimum_data["Maximum stress"]),
+ x=tuple(minimum_data["Cyclic life"]),
+ parameters=(
+ mpy.SeriesParameterValue("Data Type", "Minimum"),
+ mpy.SeriesParameterValue("Stress Ratio", r_ratio_mean),
+ ),
+ decoration=mpy.GraphDecoration.LINES,
+)
+
+series_test_data = mpy.SeriesPoint(
+ y=tuple(rs_df["Maximum stress"]),
+ x=tuple(rs_df["Cyclic life"]),
+ parameters=(
+ mpy.SeriesParameterValue("Data Type", "Test Data"),
+ mpy.SeriesParameterValue("Stress Ratio", r_ratio_mean),
+ ),
+ decoration=mpy.GraphDecoration.MARKERS,
+)
+fit.value = (
+ series_fitted,
+ series_minimum,
+ series_test_data,
+)
+
+record.attributes["Equivalent Stress, A1"].value = A1
+record.attributes["Equivalent Stress, A2"].value = A2
+record.attributes["Statistical Analysis Status"].value = "Complete"
+record.set_attributes(
+ [
+ record.attributes["Equivalent Stress, A1"],
+ record.attributes["Equivalent Stress, A2"],
+ # The status is not updated; this allows the notebook to be re-run.
+ # r.attributes["Statistical Analysis Status"],
+ fit,
+ ]
+)
+
+mi.update([record])
+print(f"Updated attributes in {record.name}.")
```
*Previous cell output:*
```output
@@ -283,12 +307,12 @@ Add a record link group, and use `Session.update_links()` to push the changes to
```python
-rec_link_group = r.links["Fatigue Test Data"]
-for rsi in records:
+rec_link_group = record.links["Fatigue Test Data"]
+for rsi in test_records:
rec_link_group.add(rsi)
-r.set_links("Fatigue Test Data", rec_link_group)
-mi.update_links([r])
-print(f"Updated links in {r.name}.")
+record.set_links("Fatigue Test Data", rec_link_group)
+mi.update_links([record])
+print(f"Updated links in {record.name}.")
```
*Previous cell output:*
```output
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/03_Fit_series_data_and_import_files/03_Fit_series_data_and_import_12_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/03_Fit_series_data_and_import_files/03_Fit_series_data_and_import_12_0.png
index 2dddf4d398..cae7c157ff 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/03_Fit_series_data_and_import_files/03_Fit_series_data_and_import_12_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/03_Fit_series_data_and_import_files/03_Fit_series_data_and_import_12_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/03_Fit_series_data_and_import_files/03_Fit_series_data_and_import_14_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/03_Fit_series_data_and_import_files/03_Fit_series_data_and_import_14_0.png
new file mode 100644
index 0000000000..80013e36d1
Binary files /dev/null and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/03_Fit_series_data_and_import_files/03_Fit_series_data_and_import_14_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import.md
index 1b2096c567..d9f5f67116 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import.md
@@ -241,7 +241,7 @@ _ = ax.set_title("Stress vs Strain")
-Since the plastic region extends over a large strain range, it is difficult to see detail in the elastic region.
+Since the plastic region extends over a large strain range, it is difficult to see detail in the elastic region.
Create an inset and plot the elastic and yield region only.
@@ -272,7 +272,7 @@ fig
### Calculate Ultimate tensile strength
-*Ultimate tensile strength* can be calculated by taking the maximum value of the `df.Stress` column.
+*Ultimate tensile strength* can be calculated by taking the maximum value of the `df.Stress` column.
Calculate and store the tensile strength in SI units and MPa (the latter will be used later).
@@ -292,12 +292,22 @@ strength*.
```python
strain_at_uts = df.Strain[df.Stress == tens_strength].iloc[0]
-ax.scatter(x=[strain_at_uts], y=[tens_strength_MPa], color="black", marker="x", alpha=0.75, s=50, zorder=1)
-ax.annotate(rf"$\sigma_{{ts}}$: {tens_strength_MPa:.2f} MPa",
- xy=(strain_at_uts, tens_strength_MPa),
- xytext=(0,-14),
- textcoords="offset points",
- fontsize=8)
+ax.scatter(
+ x=[strain_at_uts],
+ y=[tens_strength_MPa],
+ color="black",
+ marker="x",
+ alpha=0.75,
+ s=50,
+ zorder=1,
+)
+ax.annotate(
+ rf"$\sigma_{{ts}}$: {tens_strength_MPa:.2f} MPa",
+ xy=(strain_at_uts, tens_strength_MPa),
+ xytext=(0, -14),
+ textcoords="offset points",
+ fontsize=8,
+)
fig
```
@@ -327,7 +337,7 @@ def get_stress_strain_at_fraction_of_tensile_strength(fraction):
nearest_row_number = stress_difference.abs().argsort()[0]
nearest_row = df.iloc[nearest_row_number]
return nearest_row.Strain, nearest_row.Stress
-
+
lower_strain, lower_stress = get_stress_strain_at_fraction_of_tensile_strength(LOWER_FRACTION)
upper_strain, upper_stress = get_stress_strain_at_fraction_of_tensile_strength(UPPER_FRACTION)
@@ -446,9 +456,10 @@ ax_inset.scatter(
ax_inset.annotate(
rf"$\sigma_y$: {yield_stress_MPa:.2f} MPa",
xy=(strain_at_yield, yield_stress_MPa),
- xytext=(-60,6),
+ xytext=(-60, 6),
textcoords="offset points",
- fontsize=8)
+ fontsize=8,
+)
fig
```
@@ -509,7 +520,7 @@ ax.legend(handles, labels, bbox_to_anchor=legend_position, prop={"size": 8})
ax.annotate(
rf"$\epsilon_f$: {elongation:.3}",
xy=(elongation, 0),
- xytext=(-40,5),
+ xytext=(-40, 5),
textcoords="offset points",
fontsize=8,
)
@@ -660,7 +671,7 @@ plastic_strain = df.True_Strain - df.True_Stress / youngs_modulus - STRAIN_OFFSE
df_plastic["Strain"] = plastic_strain[plastic_strain > 0]
# Get only the stress values with a corresponding strain
-df_plastic["Stress"] = df.True_Stress.align(df_plastic.Strain, join='right')[0]
+df_plastic["Stress"] = df.True_Stress.align(df_plastic.Strain, join="right")[0]
# Manually add the first point Strain = 0, Stress = yield stress
first_point = pd.DataFrame({"Strain": [0], "Stress": [yield_stress]})
@@ -735,21 +746,21 @@ _ = ax.set_title("True Stress vs True Plastic Strain")
## Import data and results into Granta MI
-Finally, import the raw data, processed data and results into a new Granta MI record.
+Finally, import the raw data, processed data and results into a new Granta MI record.
Connect to Granta MI and specify a database and table.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
-db = mi.get_db(db_key='MI_Training')
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
+db = mi.get_db(db_key="MI_Training")
-tensile_test_table = db.get_table('Tensile Test Data')
+tensile_test_table = db.get_table("Tensile Test Data")
```
-Create a new record to import the data into, using `datetime.now()` to ensure the record name is unique.
+Create a new record to import the data into, using `datetime.now()` to ensure the record name is unique.
At this stage, the record has only been created in the MI Scripting Toolkit. The changes will be pushed to Granta MI
when `session.update()` is called at the end of the notebook.
@@ -788,7 +799,7 @@ dimensionless but will be imported as a percentage, so they are multiplied by 10
stress_attrs = {
"Ultimate Tensile Strength": tens_strength,
"Young's Modulus (11-axis)": youngs_modulus,
- "0.2% Offset Yield Stress": yield_stress
+ "0.2% Offset Yield Stress": yield_stress,
}
strain_attrs = {
"Strain at Ultimate Tensile Strength": strain_at_uts * 100,
@@ -828,10 +839,10 @@ could easily be read from the source file.
```python
range_text = f"Linear fit between [{LOWER_FRACTION:.1%}:{UPPER_FRACTION:.1%}] of Tensile strength"
text_attrs = {
- "Young's Modulus Calculation": 'Chord',
- "Test Type": 'Tensile',
- "Testing Standards": 'ASTM E8',
- "Alloy": 'AMS 6520',
+ "Young's Modulus Calculation": "Chord",
+ "Test Type": "Tensile",
+ "Testing Standards": "ASTM E8",
+ "Alloy": "AMS 6520",
"Modulus Calculation Range": range_text,
}
write_text(text_attrs)
@@ -847,9 +858,12 @@ def write_functional(attr_name, y_unit, x_unit, x_name, y_values, x_values):
a = record.attributes[attr_name]
a.unit = y_unit
a.parameters[x_name].unit = x_unit
- a.xaxis[x_name] = True
- for x, y in zip(x_values, y_values):
- a.add_point({'y': y, x_name: x})
+ a.value = (
+ mpy.SeriesPoint(
+ x=tuple(x_values),
+ y=tuple(y_values),
+ ),
+ )
record.set_attributes([a])
```
@@ -896,6 +910,6 @@ mi.update([record])
*Previous cell output:*
```output
-[]
+[]
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_12_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_12_0.png
index 2270552562..a75a45b15e 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_12_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_12_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_17_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_17_0.png
index 0f7d2ec831..9c76f011e8 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_17_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_17_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_19_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_19_0.png
index 47728e183b..c9d861c0b3 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_19_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_19_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_24_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_24_0.png
index 0fbb692e2d..eabc56e56e 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_24_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_24_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_29_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_29_0.png
index 77e1b0d080..56432156ea 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_29_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_29_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_32_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_32_0.png
index e77e6e7acb..26d7397bf9 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_32_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_32_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_36_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_36_0.png
index 675468199c..070086c949 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_36_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_36_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_41_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_41_0.png
index 9961c2c393..4265b166c3 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_41_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_41_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_46_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_46_0.png
index b9240b5073..1df7863964 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_46_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_46_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_51_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_51_0.png
index c539d62f71..606b15be20 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_51_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/04_Process_datasets_and_import_files/04_Process_datasets_and_import_51_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve.md
index c0a6da7a09..5c6a0e00c9 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve.md
@@ -9,9 +9,9 @@ Create a session, and specify a database and table.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
db.unit_system = "SI (Consistent)"
@@ -48,8 +48,7 @@ you separate the datum into the first list item (the column headers) and the sub
import pandas as pd
def functional_to_dataframe(attr):
- headers = attr.value[0]
- func_data = attr.value[1:]
+ headers, *func_data = attr.table_view.table_view
df = pd.DataFrame(func_data, columns=headers)
return df
@@ -72,8 +71,8 @@ df_stress_strain.head()
Strain [strain]
Temperature [°C]
Time [s]
-
Other []
-
Stress/Strain Curve Type []
+
Other [None]
+
Stress/Strain Curve Type [None]
Estimated point?
@@ -156,7 +155,7 @@ def clean_dataframe(df, y_name, x_name, columns_to_drop=None, columns_to_keep=No
columns_to_drop = []
if not columns_to_keep:
columns_to_keep = []
- new_df = df.drop(columns=[f"Y max ({y_name})"]+[f"Y min ({y_name})"]+columns_to_drop)
+ new_df = df.drop(columns=[f"Y max ({y_name})"] + [f"Y min ({y_name})"] + columns_to_drop)
new_df["y"] = df[[f"Y max ({y_name})", f"Y min ({y_name})"]].mean(axis=1)
new_df = new_df.rename(columns={x_name: "x"})
new_df[columns_to_keep] = df[columns_to_keep]
@@ -175,8 +174,8 @@ df_stress_strain_clean = clean_dataframe(
"Y max (Tensile Stress/Strain, L [Pa])",
"Time [s]",
"Estimated point?",
- "Other []",
- "Stress/Strain Curve Type []"
+ "Other [None]",
+ "Stress/Strain Curve Type [None]",
],
columns_to_keep=["Temperature [°C]"],
)
@@ -244,7 +243,7 @@ df_yield_stress_clean = clean_dataframe(
"Y max (Tens. Yield Stress (L-dir) with Temp. [Pa])",
"Time [s]",
"Estimated point?",
- "Other []",
+ "Other [None]",
],
)
df_yield_stress_clean.head()
@@ -304,7 +303,7 @@ df_youngs_modulus_clean = clean_dataframe(
"Y max (Tensile Modulus (L-dir) with Temp. [Pa])",
"Time [s]",
"Estimated point?",
- "Other []",
+ "Other [None]",
],
)
df_youngs_modulus_clean.head()
@@ -531,7 +530,7 @@ _ = ax.set_title("Deformation Energy $U_T$ vs Temperature")
### Compare Deformation Energy at temperature extrema
The area under the high- and low-temperature *Stress-Strain* curves can be shown graphically, providing a
-more visual comparison.
+more visual comparison.
Create a basic *Stress-Strain* plot at both temperatures, dividing the plotted y values by $10^6$ and changing the
y-axis units to MPa. Add the legend manually.
@@ -632,7 +631,7 @@ fig
-Finally, add a chart title and annotate the filled areas with the corresponding *Deformation Energy*.
+Finally, add a chart title and annotate the filled areas with the corresponding *Deformation Energy*.
To render the *Deformation Energy* value in standard form, we've defined a function which returns the mantissa and
exponent, and inserted them into LaTeX-formatted strings.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_39_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_39_0.png
index 08221620aa..da402f400a 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_39_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_39_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_43_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_43_0.png
index b051382b2a..fab91ef9f1 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_43_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_43_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_47_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_47_0.png
index 72737aa45e..b0656a9baa 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_47_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_47_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_49_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_49_0.png
index dc1a3485e7..cf751f8dcc 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_49_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/05_Find_area_under_a_curve_files/05_Find_area_under_a_curve_49_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/06_Calculate_statistics_for_records.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/06_Calculate_statistics_for_records.md
index 3e82b63211..b7dda4b312 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/06_Calculate_statistics_for_records.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/06_Calculate_statistics_for_records.md
@@ -1,6 +1,6 @@
# Calculate statistics for a set of records
-Summarise (roll up) test results into new statistical data records.
+Summarise (roll up) test results into new statistical data records.
In this example, the tests are stored in *Tensile Test Data* table and the statistical data is stored in *Tensile
Statistical Data*. Since the sample data is arranged by specimen, the mean and other statistics will be stored by
@@ -29,18 +29,18 @@ To simplify your own roll-up, you can:
```python
import statistics
from typing import List
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
def rollup_point_attribute(
source_attributes: List[mpy.AttributeValue],
target_attribute: mpy.AttributeValue,
record: mpy.Record,
) -> None:
-
+ if any(isinstance(attr, mpy.AttributePointMulti) for attr in source_attributes):
+ raise TypeError("Multi-valued points are not supported by this script")
+
values = [attr.value for attr in source_attributes if attr.value]
- assert all([isinstance(value, float) for value in values]), "Multi-valued points are not supported by this script"
-
if len(values) == 0:
return
@@ -96,28 +96,29 @@ def copy_attribute(
target_attribute: mpy.AttributeValue,
record: mpy.Record,
) -> None:
-
if target_attribute.type == "POIN":
- values = set([attr.value for attr in source_attributes if attr.value])
-
- assert all(
- [isinstance(value, float) for value in values]
- ), "Multi-valued points are not supported by this script"
-
- assert len(values) == 1, "Values must be identical to copy, received '{0}'".format(', '.join(values))
+ if any(isinstance(attr, mpy.AttributePointMulti) for attr in source_attributes):
+ raise TypeError("Multi-valued points are not supported by this script")
+ values = {attr.value for attr in source_attributes if attr.value}
+ if len(values) != 1:
+ formatted_values = ", ".join(values)
+ raise ValueError(f"Values must be identical to copy, received '{formatted_values}'")
target_attribute.value = values.pop()
elif target_attribute.type == "DISC":
- # No support for multivalued
- if any(attr.is_multivalued for attr in source_attributes):
- raise TypeError("No support for multivalued")
- values = set([attr.value for attr in source_attributes if attr.value])
- assert len(values) == 1, "Values must be identical to copy, received '{0}'".format(', '.join(values))
+ if any(isinstance(attr, mpy.AttributeDiscreteMulti) for attr in source_attributes):
+ raise TypeError("Multi-valued discretes are not supported by this script")
+ values = {attr.value for attr in source_attributes if attr.value}
+ if len(values) != 1:
+ formatted_values = ", ".join(values)
+ raise ValueError(f"Values must be identical to copy, received '{formatted_values}'")
target_attribute.value = values.pop()
else:
- values = set([attr.value for attr in source_attributes if attr.value])
- assert len(values) == 1, "Values must be identical to copy, received '{0}'".format(', '.join(values))
+ values = {attr.value for attr in source_attributes if attr.value}
+ if len(values) != 1:
+ formatted_values = ", ".join(values)
+ raise ValueError(f"Values must be identical to copy, received '{formatted_values}'")
target_attribute.value = values.pop()
record.set_attributes([target_attribute])
@@ -132,19 +133,24 @@ Connect to Granta MI and fetch the folder corresponding to the composite *3M, S-
```python
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
test_table = db.get_table("Tensile Test Data")
statistics_table = db.get_table("Tensile Statistical Data")
material_record = test_table.search_for_records_by_name("3M, S-Glass Unitape S2/SP381")[0]
-print(material_record)
+material_record
```
+
+
+
*Previous cell output:*
```output
```
+
+
To make processing easier, convert the structure of the data from
Material => Orientation => RTD => Specimen => Test result
@@ -167,8 +173,8 @@ to dealing with advanced tree-traversal.
orientation_records = material_record.children
test_records = {
orientation.name: {
- specimen.name: specimen.children for specimen in
- test_table.get_records_from_path(
+ specimen.name: specimen.children
+ for specimen in test_table.get_records_from_path(
starting_node=orientation,
tree_path=["RTD"],
use_short_names=True,
@@ -181,7 +187,7 @@ test_records = {
Define the attributes you want to calculate statistics for, and those you want to copy from the test records.
To fetch large numbers of records or attributes efficiently, use the `table.bulk_fetch()` method (see
-[Performance optimization](./../../user_guide/performance_optimization.rst)).
+[Performance optimization](../../user_guide/performance_optimization.rst)).
```python
@@ -259,18 +265,19 @@ statistical data record and the test records it summarises.
```python
import datetime
+
timestamp = datetime.datetime.now().isoformat()
for orientation, specimens in test_records.items():
folder = statistics_table.path_from(
starting_node=None,
- tree_path = [
+ tree_path=[
"Epoxy/Glass",
"3M, S-Glass Unitape S2/SP381",
timestamp,
orientation,
"RTD",
],
- color=mpy.RecordColor.Aqua
+ color=mpy.RecordColor.Aqua,
)
for specimen, test_runs in specimens.items():
rollup_record = statistics_table.create_record(name=specimen, parent=folder)
@@ -279,7 +286,7 @@ for orientation, specimens in test_records.items():
try:
target_attribute = rollup_record.attributes[rollup]
rollup_point_attribute(source_attributes, target_attribute, rollup_record)
- except AssertionError: # Attribute contains multivalued data
+ except TypeError: # Attribute contains multivalued data
continue
except KeyError:
print("No attribute in target table to roll attribute '{0}' into.".format(rollup))
@@ -290,7 +297,7 @@ for orientation, specimens in test_records.items():
try:
target_attribute = rollup_record.attributes[copy_attr]
copy_attribute(source_attributes, target_attribute, rollup_record)
- except AssertionError: # Attribute contains multivalued data
+ except TypeError: # Attribute contains multivalued data
continue
except KeyError:
print("No attribute in target table to copy attribute '{0}' into.".format(copy_attr))
@@ -307,12 +314,12 @@ for orientation, specimens in test_records.items():
```
*Previous cell output:*
```output
-Rollup completed for the specimen 'LBU15', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=32d98e87-d538-4958-bf4d-93d4cf4bf61e'
-Rollup completed for the specimen 'LBU14', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=58b52053-d236-447d-b5fd-7fa0e66cd1c3'
-Rollup completed for the specimen 'LBJ83', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=021bf20b-d0a8-4be6-99f3-9ee57993b1a3'
-Rollup completed for the specimen 'LBJ62', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=baab458e-ebd3-486c-9e50-d6da39493e27'
-Rollup completed for the specimen 'LBJ53', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=dbab2acf-fdc2-4444-9e0a-a2551063f3e4'
-Rollup completed for the specimen 'LBJ42', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=7a59d226-e6bb-4f55-97cc-b68157ef9355'
-Rollup completed for the specimen 'LBJ14', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=ab4a3789-6adf-4302-b220-acd899a829ae'
-Rollup completed for the specimen 'LBJ13', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=6266db70-d0b5-4acd-95aa-6864b9ed2da0'
+Rollup completed for the specimen 'LBU15', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=de12216b-85c0-49c9-b605-3448a89e13c5'
+Rollup completed for the specimen 'LBU14', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=00addbdf-1631-4bef-99cc-6c0a962f1833'
+Rollup completed for the specimen 'LBJ83', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=2395f499-c293-4446-acb3-1e904fafab90'
+Rollup completed for the specimen 'LBJ62', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=f44b6cb6-749e-4913-861d-5cd07d8db2d7'
+Rollup completed for the specimen 'LBJ53', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=f94cfc30-d44c-4100-b2f2-a7b57abf4d85'
+Rollup completed for the specimen 'LBJ42', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=219396fd-ad80-4def-a91c-f435074ef72c'
+Rollup completed for the specimen 'LBJ14', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=6d964778-afc3-42e3-808f-c86f3253815f'
+Rollup completed for the specimen 'LBJ13', view this record at 'http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=9de8cc1b-c728-4ed4-844c-ae47ee57f929'
```
\ No newline at end of file
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/06_Calculate_statistics_for_records_files/06_Calculate_statistics_for_records_12_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/06_Calculate_statistics_for_records_files/06_Calculate_statistics_for_records_12_0.png
index cd0e21c8fd..6af1709cb3 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/06_Calculate_statistics_for_records_files/06_Calculate_statistics_for_records_12_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/06_Calculate_statistics_for_records_files/06_Calculate_statistics_for_records_12_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/07_Calculate_statistics_for_functional_attributes.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/07_Calculate_statistics_for_functional_attributes.md
index 73bd21b2e1..99a100ca80 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/07_Calculate_statistics_for_functional_attributes.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/07_Calculate_statistics_for_functional_attributes.md
@@ -9,9 +9,9 @@ Connect to Granta MI and specify a database and tables.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
test_table = db.get_table("Tensile Test Data")
@@ -45,11 +45,7 @@ test_records = plate_folder.get_descendants()
test_records = bulk_fetch_attributes_and_return_populated_records(
table=test_table,
records=test_records,
- attributes=[
- "Specimen ID",
- "Tensile Response (11 axis)",
- "Test Temperature"
- ]
+ attributes=["Specimen ID", "Tensile Response (11 axis)", "Test Temperature"],
)
temperature_unit = test_table.attributes["Test Temperature"].unit
temperature_column_name = f"Test Temperature [{temperature_unit}]"
@@ -73,7 +69,9 @@ for record in test_records:
specimen_id = record.attributes["Specimen ID"].value
test_temperature = record.attributes["Test Temperature"].value
- df_functional_data = pd.DataFrame(response_attr.value[1:], columns=response_attr.value[0])
+ df_functional_data = pd.DataFrame(
+ response_attr.table_view.table_view[1:], columns=response_attr.table_view.table_view[0]
+ )
df_current = pd.concat(
[
@@ -85,7 +83,7 @@ for record in test_records:
]
]
.mean(axis=1)
- .rename("Tensile Response (11 axis) [MPa]")
+ .rename("Tensile Response (11 axis) [MPa]"),
],
axis=1,
)
@@ -143,7 +141,7 @@ for temperature_index, temperature in enumerate(grouped_by.groups):
data=zip(
*[
[row[temperature_index] for row in confidence_intervals[0]],
- [row[temperature_index] for row in confidence_intervals[1]]
+ [row[temperature_index] for row in confidence_intervals[1]],
],
),
index=df_interpolated.index,
@@ -156,7 +154,7 @@ for temperature_index, temperature in enumerate(grouped_by.groups):
grouped_by.mean().T[temperature].rename("mean"),
grouped_by.min().T[temperature].rename("min"),
grouped_by.max().T[temperature].rename("max"),
- df_cis
+ df_cis,
],
axis=1,
).dropna()
@@ -224,7 +222,7 @@ plt.show()
## Import roll-up data into Granta MI
Define two helper functions: one that resamples a DataFrame linearly based on a target column's values, and one that
-appends a series of range values to a `FloatFunctionalAttributeValue`, skipping any `NaN` values.
+creates a series of range values.
(Although `pandas` has a built-in `resample()` function, it only operates on time-series data.)
@@ -235,23 +233,22 @@ import numpy as np
def subsample_dataframe(df, x_axis, n_samples):
new_index = np.linspace(df[x_axis].min(), df[x_axis].max(), n_samples)
df.index = df[x_axis]
- df_subsampled = (
- df
- .reindex(df.index.union(new_index))
- .interpolate("index")
- .reindex(index=new_index)
- )
+ df_subsampled = df.reindex(df.index.union(new_index)).interpolate("index").reindex(index=new_index)
df_subsampled.index = range(n_samples)
return df_subsampled
-def append_series(functional_attribute, x_data, y_low_data, y_high_data=None, data_type=None):
+def make_series(x_data, y_low_data, y_high_data=None, data_type=None) -> mpy.SeriesRange:
if y_high_data is None:
y_high_data = y_low_data
- for x, y_low, y_high in zip(x_data, y_low_data, y_high_data):
- if pd.isna(y_low) or pd.isna(y_high):
- continue
- functional_attribute.value.append([y_low, y_high, x, data_type, False])
+ return mpy.SeriesRange(
+ x=tuple(x_data),
+ y_low=tuple(y_low_data),
+ y_high=tuple(y_high_data),
+ parameters=(
+ mpy.SeriesParameterValue("Data Type", data_type),
+ ) if data_type is not None else tuple()
+ )
```
Import the roll-up data into a Granta MI database. Use `path_from()` to create a folder path, and then create a
@@ -279,44 +276,44 @@ for plot_index, temperature in enumerate(grouped_by.groups):
name=f"Functional Rollup ({round(temperature, 0)} {temperature_unit})",
parent=folder,
)
-
+
temp_attribute = rec.attributes["Test Temperature"]
temp_attribute.value = temperature
temp_attribute.unit = temperature_unit
- func_attr = rec.attributes["Tensile Response Analysis (11 axis)"]
+ func_attr: mpy.AttributeFunctionalSeriesRange = rec.attributes["Tensile Response Analysis (11 axis)"]
func_attr.unit = "MPa"
# Get the rows corresponding to the current temperature
df_current = df_all_plots.loc[df_all_plots["temperature"] == temperature]
df_current = subsample_dataframe(df_current, "strain", 101)
- append_series(
- func_attr,
- df_current["strain"],
- df_current["mean"],
- data_type="Mean",
- )
- append_series(
- func_attr,
- df_current["strain"],
- df_current["lower_ci"],
- df_current["upper_ci"],
- data_type="95% Confidence Interval",
- )
- append_series(
- func_attr,
- df_current["strain"],
- df_current["min"],
- df_current["max"],
- data_type="Range",
+ func_attr.value = (
+ make_series(
+ df_current["strain"],
+ df_current["mean"],
+ data_type="Mean",
+ ),
+ make_series(
+ df_current["strain"],
+ df_current["lower_ci"],
+ df_current["upper_ci"],
+ data_type="95% Confidence Interval",
+ ),
+ make_series(
+ df_current["strain"],
+ df_current["min"],
+ df_current["max"],
+ data_type="Range",
+ ),
)
rec.set_attributes([temp_attribute, func_attr])
rec = mi.update([rec])[0]
associated_test_records = [
- test_record for test_record in test_records
+ test_record
+ for test_record in test_records
if round(test_record.attributes["Test Temperature"].value, 1) == temperature
]
rec.set_links("Tensile Test Data", associated_test_records)
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/07_Calculate_statistics_for_functional_attributes_files/07_Calculate_statistics_for_functional_attributes_12_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/07_Calculate_statistics_for_functional_attributes_files/07_Calculate_statistics_for_functional_attributes_12_0.png
index 4c18215e80..683ffa631e 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/07_Calculate_statistics_for_functional_attributes_files/07_Calculate_statistics_for_functional_attributes_12_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/07_Calculate_statistics_for_functional_attributes_files/07_Calculate_statistics_for_functional_attributes_12_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/08_Fit_model_to_series_data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/08_Fit_model_to_series_data.md
index 7b1bdc0428..7c777add26 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/08_Fit_model_to_series_data.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/08_Fit_model_to_series_data.md
@@ -11,9 +11,9 @@ Set the unit system explicitly to ensure repeatable results.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
db.unit_system = "Metric"
@@ -28,13 +28,7 @@ to iterate through the different values of *Test Temperature*.
```python
-all_records = test_data_table.get_records_from_path(
- starting_node=None,
- tree_path=[
- "High Alloy Steels",
- "AMS 6520"
- ]
-)
+all_records = test_data_table.get_records_from_path(starting_node=None, tree_path=["High Alloy Steels", "AMS 6520"])
plate_record = all_records[0]
temperature_test_groups = plate_record.children
@@ -60,7 +54,7 @@ temperature_unit = test_temperature.unit
tensile_response = test_data_table.attributes["Tensile Response (11 axis)"]
tensile_response_unit = tensile_response.unit
strain_unit = tensile_response.parameters["Strain"].unit
-record_name = mpy.PseudoAttributeDefinition(name="name")
+record_name = mpy.RecordProperties.name
test_record_dict = {}
for test_group in temperature_test_groups:
@@ -71,7 +65,8 @@ for test_group in temperature_test_groups:
)
test_records = [
- test_record for test_record in test_records
+ test_record
+ for test_record in test_records
if not test_record.attributes["Test Temperature"].is_empty()
and not test_record.attributes["Tensile Response (11 axis)"].is_empty()
]
@@ -103,14 +98,14 @@ import numpy as np
def ramberg_osgood_model(stress_: np.ndarray, modulus_: float, k_: float, n_: float) -> np.ndarray:
hook_strain = stress_ / modulus_
- return hook_strain + k_ * hook_strain ** n_
+ return hook_strain + k_ * hook_strain**n_
```
## Define a helper function to fit the model to a series
Using the `scipy.optimize` package, fit the Ramberg-Osgood model to the stress-strain data at each temperature.
-Provide initial values and constrain the parameters to positive and realistic values. These values are material
+Provide initial values and constrain the parameters to positive and realistic values. These values are material
dependent - for Steel we use the following:
| Parameter | Minimum | Maximum | Initial Value |
@@ -127,20 +122,16 @@ The goodness of fit can be estimated by inspecting the diagonal of the covarianc
from typing import Tuple, List
from scipy.optimize import curve_fit
-def fit_ramberg_osgood_model(stress_strain_data: np.ndarray) -> Tuple[np.ndarray, Tuple[float, float, float]]:
+def fit_ramberg_osgood_model(
+ stress_strain_data: np.ndarray,
+) -> Tuple[np.ndarray, Tuple[float, float, float]]:
parameter_bounds = ((1, 0, 0), (1e5, 1e2, 1e2))
f_init = (1e3, 1, 1)
stress = stress_strain_data[:, 0]
strain = stress_strain_data[:, 1]
- fitted_parameters, covariance = curve_fit(
- ramberg_osgood_model,
- stress,
- strain,
- f_init,
- bounds=parameter_bounds
- )
+ fitted_parameters, covariance = curve_fit(ramberg_osgood_model, stress, strain, f_init, bounds=parameter_bounds)
# Compute the sum-of-squared error for each model parameter
sse = np.sqrt(np.diag(covariance))
@@ -162,20 +153,16 @@ Define three more helper functions to make the main loop easier to understand:
```python
def get_response_data(records: List[mpy.Record]) -> np.ndarray:
- # Iterate through records, extract the appropriate attribute and ensure the units are set correctly
- test_response_attributes = []
+ # Iterate through records, extract the appropriate attribute
+ test_response_series = []
for record in records:
tensile_response = record.attributes["Tensile Response (11 axis)"]
- test_response_attributes.append(tensile_response)
-
- # Convert the AttributeValue objects into numpy arrays:
- # 1. Trim off the first row, which contains the column headers
- # 2. Cast each element to float (numpy treats these values as an object unless told otherwise)
- test_response_data = [np.array(attribute.value[1:]).astype(float) for attribute in test_response_attributes]
+ # Test records are expected to include a single series
+ if len(tensile_response.value) != 1:
+ raise ValueError
+ test_response_series.append(tensile_response.value[0])
- # The MI Scripting Toolkit stores all functional data as ranges. Since both values are the same,
- # take the first.
- stress_strain_response = [np.column_stack((curve[1:, 0], curve[1:, 2])) for curve in test_response_data]
+ stress_strain_response = [np.column_stack((series.y, series.x)) for series in test_response_series]
return stress_strain_response
@@ -200,7 +187,7 @@ def compute_yield_point(stress_strain_data: np.ndarray, modulus: float) -> Tuple
## Fit to the data
-For each set of test records, extract the stress-strain curve and fit to the Ramberg-Osgood model using the helper
+For each set of test records, extract the stress-strain curve and fit to the Ramberg-Osgood model using the helper
functions defined above. Combine all the test runs into one dataset and fit the model to the aggregate data.
In your own scripts, you will also need to take into account multiple series, range data, and other features of your
@@ -229,7 +216,7 @@ for test_temperature, tests_at_temperature in sorted(test_record_dict.items()):
"modulus": modulus,
"yield_point": (yield_strain, yield_stress),
"k": k,
- "n": n
+ "n": n,
}
print(f"Fit parameters at Temperature {test_temperature:.1f}{temperature_unit}:")
pprint.pprint(tests_at_temperature["model_parameters"])
@@ -238,51 +225,50 @@ for test_temperature, tests_at_temperature in sorted(test_record_dict.items()):
*Previous cell output:*
```output
Fit parameters at Temperature 194.3K:
-{'k': np.float64(0.14863494441724703),
- 'modulus': np.float64(2062.0202035684933),
- 'n': np.float64(8.791864160782794),
- 'yield_point': (np.float64(1.2342202393471564),
- np.float64(2132.5830284732797))}
+{'k': np.float64(0.1486344480944722),
+ 'modulus': np.float64(2062.019771768718),
+ 'n': np.float64(8.791873200741906),
+ 'yield_point': (np.float64(1.234217805863505), np.float64(2132.5775640058087))}
Fit parameters at Temperature 296.1K:
-{'k': np.float64(0.1791326818346526),
- 'modulus': np.float64(1981.6619869624521),
- 'n': np.float64(9.114593900403749),
- 'yield_point': (np.float64(1.2120542799247618),
- np.float64(2005.5494952695572))}
+{'k': np.float64(0.17913223713103874),
+ 'modulus': np.float64(1981.6616644768533),
+ 'n': np.float64(9.114602167742552),
+ 'yield_point': (np.float64(1.2120572321072252),
+ np.float64(2005.5550191234408))}
Fit parameters at Temperature 422.0K:
-{'k': np.float64(0.30688860274078),
- 'modulus': np.float64(1904.622968058874),
- 'n': np.float64(8.456684372086439),
- 'yield_point': (np.float64(1.1505510048627243),
- np.float64(1810.4412761729873))}
+{'k': np.float64(0.30688819443104687),
+ 'modulus': np.float64(1904.6227482778297),
+ 'n': np.float64(8.456689311588288),
+ 'yield_point': (np.float64(1.1505438661129421),
+ np.float64(1810.4274706346653))}
Fit parameters at Temperature 588.7K:
-{'k': np.float64(0.46386736088140446),
- 'modulus': np.float64(1825.4403056571182),
- 'n': np.float64(8.486132455089072),
- 'yield_point': (np.float64(1.1055238461378185),
- np.float64(1652.9797264736287))}
+{'k': np.float64(0.4638673295642107),
+ 'modulus': np.float64(1825.4402932299422),
+ 'n': np.float64(8.486132687862076),
+ 'yield_point': (np.float64(1.1055222098943815),
+ np.float64(1652.9767283558251))}
Fit parameters at Temperature 699.8K:
-{'k': np.float64(0.4788380313466644),
- 'modulus': np.float64(1720.6433395354948),
- 'n': np.float64(7.1629878083927006),
- 'yield_point': (np.float64(1.0851718213011277),
- np.float64(1523.0649986662886))}
+{'k': np.float64(0.47884481281833274),
+ 'modulus': np.float64(1720.646273499455),
+ 'n': np.float64(7.162934830935863),
+ 'yield_point': (np.float64(1.0851710034728455),
+ np.float64(1523.0661885353247))}
Fit parameters at Temperature 810.9K:
-{'k': np.float64(3.0310550950006268),
- 'modulus': np.float64(1501.671776811084),
- 'n': np.float64(6.911013554765233),
- 'yield_point': (np.float64(0.8747695429959347),
- np.float64(1013.2823785687083))}
+{'k': np.float64(3.0310724717671658),
+ 'modulus': np.float64(1501.6751764376415),
+ 'n': np.float64(6.910966909404485),
+ 'yield_point': (np.float64(0.8747594343770989),
+ np.float64(1013.2694926711931))}
```
## Plot the results
@@ -312,13 +298,11 @@ for test_temperature, tests_at_temperature in sorted(test_record_dict.items()):
# Plot source data series
for series in response_data:
- ax_current.plot(
- series[:, 1], series[:, 0], alpha=0.3
- )
+ ax_current.plot(series[:, 1], series[:, 0], alpha=0.3)
# Plot fitted model
fitted_data = tests_at_temperature["fitted_model_data"]
- fit_curve = ax_current.plot(fitted_data[:, 1], fitted_data[:, 0], '--', label="Fitted Model")
+ fit_curve = ax_current.plot(fitted_data[:, 1], fitted_data[:, 0], "--", label="Fitted Model")
# Add the yield point
yield_strain, yield_stress = model_parameters["yield_point"]
@@ -329,16 +313,13 @@ for test_temperature, tests_at_temperature in sorted(test_record_dict.items()):
xytext=(-50, -60),
textcoords="offset points",
size=8,
- arrowprops={
- "arrowstyle": "->",
- "connectionstyle": "arc3,rad=.2"
- }
+ arrowprops={"arrowstyle": "->", "connectionstyle": "arc3,rad=.2"},
)
# Add the elastic response line
- elastic_strain_region = [0., yield_strain]
- elastic_stress = [0., model_parameters["modulus"] * yield_strain]
- elastic_curve = ax_current.plot(elastic_strain_region, elastic_stress, '-.', label="Elastic Response")
+ elastic_strain_region = [0.0, yield_strain]
+ elastic_stress = [0.0, model_parameters["modulus"] * yield_strain]
+ elastic_curve = ax_current.plot(elastic_strain_region, elastic_stress, "-.", label="Elastic Response")
# Add Legend to last subplot (where there is more whitespace)
if current_plot_index == 5:
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/08_Fit_model_to_series_data_files/08_Fit_model_to_series_data_16_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/08_Fit_model_to_series_data_files/08_Fit_model_to_series_data_16_0.png
index db9681078b..1eef387093 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/08_Fit_model_to_series_data_files/08_Fit_model_to_series_data_16_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/08_Fit_model_to_series_data_files/08_Fit_model_to_series_data_16_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/09_Compare_test_data_to_specification_values.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/09_Compare_test_data_to_specification_values.md
index ea72ea32e0..8de68dae7b 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/09_Compare_test_data_to_specification_values.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/09_Compare_test_data_to_specification_values.md
@@ -9,14 +9,14 @@ test data.
Connect to Granta MI and specify the database and table containing the test results.
Since this operation is likely to be performed as a batch operation, see
-[Authentication](./../../user_guide/authentication.rst) for more information about connecting to Granta MI securely in
+[Authentication](../../user_guide/authentication.rst) for more information about connecting to Granta MI securely in
batch mode operation.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
test_data_table = db.get_table("Tensile Test Data")
print(test_data_table)
@@ -53,7 +53,6 @@ where the attribute is populated, but the meta-attribute is empty.
```python
from typing import List
-
def find_unprocessed_records_for_attribute(test_attribute_name: str) -> List[mpy.Record]:
test_attribute_definition = test_data_table.attributes[test_attribute_name]
spec_result_attribute_definition = test_attribute_definition.meta_attributes[SPEC_STATUS_META_ATTRIBUTE]
@@ -138,7 +137,7 @@ for attribute_name in COMPARISON_ATTRIBUTES.values():
attribute = test_data_table.attributes[attribute_name]
meta_attribute = attribute.meta_attributes[SPEC_STATUS_META_ATTRIBUTE]
test_data_attributes.extend([attribute, meta_attribute])
-
+
test_data_table.bulk_fetch(records=records_to_process, attributes=test_data_attributes)
print(f"Bulk fetched {len(test_data_attributes)} attributes across {len(records_to_process)} records")
```
@@ -160,7 +159,7 @@ spec_records = set()
for r in records_to_process:
spec_records.update(r.links[SPEC_LINK_GROUP_NAME])
spec_records = list(spec_records)
-
+
# Step 2: Get the specification table object
specification_table_name = spec_records[0].table_name
specification_table = db.get_table(specification_table_name)
@@ -188,9 +187,9 @@ def compare_test_to_spec(test_attribute: mpy.AttributePoint, spec_attribute: mpy
if test_attribute.is_empty() or spec_attribute.is_empty():
return None
test_value = test_attribute.value
- low_spec_value = spec_attribute.value["low"] or float("-inf")
- high_spec_value = spec_attribute.value["high"] or float("inf")
-
+ low_spec_value = spec_attribute.value.low if spec_attribute.value.low is not None else float("-inf")
+ high_spec_value = spec_attribute.value.high if spec_attribute.value.high is not None else float("inf")
+
if low_spec_value <= test_value <= high_spec_value:
return "Test meets specification"
else:
@@ -199,7 +198,7 @@ def compare_test_to_spec(test_attribute: mpy.AttributePoint, spec_attribute: mpy
### Compare the data
Finally, iterate over all records in the `records_to_process` list and all attributes in the `COMPARISON_ATTRIBUTES`
-constant. For each combination of record and attribute, call the function defined above and store the result in the
+constant. For each combination of record and attribute, call the function defined above and store the result in the
*Specification Status* meta-attribute. The comparison is skipped if the meta-attribute is already populated.
@@ -209,22 +208,22 @@ records_to_update = []
for test_record in records_to_process:
test_specimen_id = test_record.attributes[SPECIMEN_ID_ATTRIBUTE].value
print(f"{test_specimen_id}")
-
+
spec_record = next(iter(test_record.links[SPEC_LINK_GROUP_NAME]))
modified_attributes = []
for spec_attribute_name, test_attribute_name in COMPARISON_ATTRIBUTES.items():
test_attribute = test_record.attributes[test_attribute_name]
- spec_status_meta_attribute = test_attribute.meta_attributes[SPEC_STATUS_META_ATTRIBUTE]
+ spec_status_meta_attribute = test_attribute.meta_attributes[SPEC_STATUS_META_ATTRIBUTE]
if not spec_status_meta_attribute.is_empty():
print(f" - {test_attribute_name} skipped: ")
continue
-
+
spec_attribute = spec_record.attributes[spec_attribute_name]
status = compare_test_to_spec(test_attribute, spec_attribute)
if not status:
print(f" - {test_attribute_name} skipped: ")
continue
-
+
print(f" - {test_attribute_name} result: {status}")
spec_status_meta_attribute.value = status
modified_attributes.append(spec_status_meta_attribute)
@@ -275,8 +274,7 @@ if records_to_update:
modified_records = mi.update(records_to_update)
print(f"{len(modified_records)} records modified. Links to the MI Viewer datasheets are provided below.")
for modified_record in modified_records:
- print(f"{modified_record.attributes[SPECIMEN_ID_ATTRIBUTE].value}"
- f": {modified_record.viewer_url}")
+ print(f"{modified_record.attributes[SPECIMEN_ID_ATTRIBUTE].value}: {modified_record.viewer_url}")
else:
print("No records modified")
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/10_Material_datasheet_report.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/10_Material_datasheet_report.md
index c2e02e836b..f6b6ddeee5 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/10_Material_datasheet_report.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/10_Material_datasheet_report.md
@@ -86,9 +86,9 @@ Export the data for all the required attributes for the 'released' version of th
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
db.unit_system = UNIT_SYSTEM
@@ -132,7 +132,7 @@ instead.
```python
from docx import Document
-report = Document(docx="supporting_files/10_report_template.docx")
+report = Document(docx="./supporting_files/10_report_template.docx")
```
@@ -170,13 +170,13 @@ style respectively.
from typing import Optional
from docx import table
-def write_value_to_cell(cell: table._Cell, value: str, style: Optional[str]=None) -> None:
+def write_value_to_cell(cell: table._Cell, value: str, style: Optional[str] = None) -> None:
paragraph = next(cell.iter_inner_content())
paragraph.text = value
paragraph.style = style
```
-### Write the datasheet title
+### Write the datasheet title
The first table in the template contains identifying information about the material. The first row
contains the title, and subsequent rows contain additional information about the material.
@@ -249,15 +249,15 @@ def format_attribute(
format_spec: str = ".3g",
include_unit: bool = False,
) -> Optional[str]:
-
value = attribute.value
+
# A null value may either be None or an empty list
if not value and value != 0:
return None
# Switch based on the attribute type
if attribute.type == "RNGE":
- formatted_value = f"{value['low']:{format_spec}} - {value['high']:{format_spec}}"
+ formatted_value = f"{value.low:{format_spec}} - {value.high:{format_spec}}"
elif attribute.type == "POIN":
# Single-valued point only
if isinstance(attribute.value, (float, int)):
@@ -270,7 +270,7 @@ def format_attribute(
raise NotImplementedError(f'Attribute type "{attribute.type}" not supported.')
# Include the unit in the output if requested and if it exists
- if include_unit and attribute.unit:
+ if include_unit and hasattr(attribute, "unit") and attribute.unit:
return f"{formatted_value} {attribute.unit}"
else:
return formatted_value
@@ -349,11 +349,11 @@ for idx, (attribute_name, label) in enumerate(SINGLE_VALUED_PROPERTIES.items()):
write_value_to_cell(label_cell, label, "Property Label")
# Write the value to the cell in the center column (column 1 or 4) with the style "Property Value"
- value_cell = property_table.cell(target_row, target_column_offset+1)
+ value_cell = property_table.cell(target_row, target_column_offset + 1)
write_value_to_cell(value_cell, value, "Property Value")
# Write the unit to the cell in the rightmost column (column 2 or 5) with the style "Property Unit"
- unit_cell = property_table.cell(target_row, target_column_offset+2)
+ unit_cell = property_table.cell(target_row, target_column_offset + 2)
write_value_to_cell(unit_cell, unit, "Property Unit")
```
@@ -388,7 +388,7 @@ import seaborn as sns
sns.set_theme(
palette=["black"], # Datasheet reports are typically black and white
- rc={"figure.figsize": (7, 5)} # This size produces plots suitable for printing
+ rc={"figure.figsize": (7, 5)}, # This size produces plots suitable for printing
)
sns.set_style("ticks") # Include tickmarks on axes
```
@@ -403,38 +403,31 @@ import io
import pandas as pd
def make_graph(
- attribute: mpy.AttributeFunctional,
+ attribute: mpy.AttributeFunctionalSeriesPoint,
plot_title: str,
y_label: str,
x_label: str,
constraint_param_name: Optional[str] = None,
constraint_label: Optional[str] = None,
) -> io.BytesIO:
-
value = attribute.value
# This dictionary will be used to construct a dataframe
data = {"y": list(), "x": list(), "constraint": list()}
-
+
# If a constraint_param_name was provided, set a CONSTRAINT flag to True
if constraint_param_name:
CONSTRAINT = True
else:
CONSTRAINT = False
- # Get the position of the constraint parameter in the functional data value object
- if CONSTRAINT:
- param_idx = attribute.constraint_column_index[constraint_param_name]
- else:
- param_idx = None
- parameter_unit = None
-
# Add the functional data to the dataframe dictionary
- for row in value[1:]:
- data["y"].append(row[0])
- data["x"].append(row[2])
+ for series in value:
+ data["y"].extend(series.y)
+ data["x"].extend(series.x)
if CONSTRAINT:
- data["constraint"].append(f"{row[param_idx]:.3g}")
+ constraint_value = f"{series.parameters_by_name[constraint_param_name]:.3g}"
+ data["constraint"].extend([constraint_value]*len(series.x))
if not CONSTRAINT:
# Remove the constraint key from the dictionary before converting to a dataframe
@@ -459,21 +452,21 @@ def make_graph(
y="y",
marker="o",
)
-
- x_unit = attribute.xaxis_parameter.unit
+
+ x_unit = attribute.parameters[attribute.x_axis].unit
y_unit = attribute.unit
plt.set(
title=plot_title,
xlabel=f"{x_label} / {x_unit}",
ylabel=f"{y_label} / {y_unit}",
)
-
+
# If we have a constraint, add a legend
if CONSTRAINT:
parameter_unit = attribute.parameters[constraint_param_name].unit
legend_title = f"{constraint_label} [{parameter_unit}]"
plt.legend(title=legend_title)
-
+
png = convert_plot_to_png(plt)
return png
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/11_Powerpoint_summary_example.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/11_Powerpoint_summary_example.md
index 0c4f2a167b..902d19894c 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/11_Powerpoint_summary_example.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/11_Powerpoint_summary_example.md
@@ -71,7 +71,7 @@ refers to:
```python
GRAPHS = {
- "Thermal Conductivity with Temp.": ("Thermal conductivity vs Temperature", "Thermal conductivity", "Temperature", None),
+ "Thermal Conductivity with Temp.": ("Thermal conductivity vs Temperature", "Thermal conductivity", "Temperature", None),
"Thermal Expansion with Temp.": ("Thermal expansion vs Temperature", "Thermal expansion", "Temperature", None),
"Specific Heat with Temp.": ("Specific heat vs Temperature", "Specific heat", "Temperature", None),
"Tensile Stress/Strain, L": ("Stress vs Strain and Temperature", "Stress", "Strain", ("Temperature", "Temperature")),
@@ -84,9 +84,9 @@ Export the data for all the required attributes for the 'released' version of th
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key=DATABASE)
db.unit_system = UNIT_SYSTEM
@@ -130,7 +130,7 @@ instead.
```python
from pptx import Presentation
-prs = Presentation(pptx="supporting_files/11_presentation_template.pptx")
+prs = Presentation(pptx="./supporting_files/11_presentation_template.pptx")
```
@@ -187,13 +187,13 @@ title = f"{material_name} [v{record_version_number}]"
# Since the title placeholder is so commonly used, it is available via the title property
title_slide.shapes.title.text = title
-# The subtitle placeholder does not have a dedicated property. To determine the
+# The subtitle placeholder does not have a dedicated property. To determine the
# correct placeholder shape, iterate through each one and identify it by name.
# If the same placeholder is used multiple times, the idx value is static for
# each layout and can be used directly once identified.
subtitle = placeholder_idx = None
for shape in title_slide.placeholders:
- print('%d %s' % (shape.placeholder_format.idx, shape.name))
+ print("%d %s" % (shape.placeholder_format.idx, shape.name))
if shape.name.startswith("Subtitle"):
placeholder_idx = shape.placeholder_format.idx
subtitle = shape
@@ -214,6 +214,10 @@ was run previously that saved a file to disk.
```python
from pathlib import Path
+```
+
+
+```python
output_folder = Path("./output")
output_folder.mkdir(exist_ok=True)
```
@@ -270,7 +274,6 @@ def format_attribute(
format_spec: str = ".3g",
include_unit: bool = False,
) -> Optional[str]:
-
value = attribute.value
# A null value may either be None or an empty list
if not value and value != 0:
@@ -278,7 +281,7 @@ def format_attribute(
# Switch based on the attribute type
if attribute.type == "RNGE":
- formatted_value = f"{value['low']:{format_spec}} - {value['high']:{format_spec}}"
+ formatted_value = f"{value.low:{format_spec}} - {value.high:{format_spec}}"
elif attribute.type == "POIN":
# Single-valued point only
if isinstance(attribute.value, (float, int)):
@@ -291,10 +294,11 @@ def format_attribute(
raise NotImplementedError(f'Attribute type "{attribute.type}" not supported.')
# Include the unit in the output if requested and if it exists
- if include_unit and attribute.unit:
+ if include_unit and hasattr(attribute, "unit") and attribute.unit:
return f"{formatted_value} {attribute.unit}"
else:
return formatted_value
+
```
Next, create the content slide and populate with the exported data.
@@ -402,7 +406,7 @@ value, and unit to the table.
```python
for (attribute_name, label), row in zip(SINGLE_VALUED_PROPERTIES.items(), property_table.rows):
attribute = released_record.attributes[attribute_name]
-
+
# Use standard form for numeric attributes
value = format_attribute(attribute, format_spec=".4e", include_unit=False)
unit = attribute.unit
@@ -410,7 +414,7 @@ for (attribute_name, label), row in zip(SINGLE_VALUED_PROPERTIES.items(), proper
# If there is no value for this attribute, set the value and unit to a dash
if value is None:
value = unit = "-"
- elif unit == "":
+ elif unit is None:
unit = "-"
# Write the label to the cell in the leftmost column (column 0 or 3) with the style "Property Label"
@@ -454,6 +458,7 @@ def convert_plot_to_png(plt: pyplot) -> io.BytesIO:
fig.clf()
buffer.seek(0)
return buffer
+
```
Next, import `seaborn` and set the plot style.
@@ -478,37 +483,30 @@ import io
import pandas as pd
def make_graph(
- attribute: mpy.AttributeFunctional,
+ attribute: mpy.AttributeFunctionalSeriesPoint,
y_label: str,
x_label: str,
constraint_param_name: Optional[str] = None,
constraint_label: Optional[str] = None,
) -> io.BytesIO:
-
value = attribute.value
# This dictionary will be used to construct a dataframe
data = {"y": list(), "x": list(), "constraint": list()}
-
+
# If a constraint_param_name was provided, set a CONSTRAINT flag to True
if constraint_param_name:
CONSTRAINT = True
else:
CONSTRAINT = False
- # Get the position of the constraint parameter in the functional data value object
- if CONSTRAINT:
- param_idx = attribute.constraint_column_index[constraint_param_name]
- else:
- param_idx = None
- parameter_unit = None
-
# Add the functional data to the dataframe dictionary
- for row in value[1:]:
- data["y"].append(row[0])
- data["x"].append(row[2])
+ for series in value:
+ data["y"].extend(series.y)
+ data["x"].extend(series.x)
if CONSTRAINT:
- data["constraint"].append(f"{row[param_idx]:.3g}")
+ constraint_value = f"{series.parameters_by_name[constraint_param_name]:.3g}"
+ data["constraint"].extend([constraint_value]*len(series.x))
if not CONSTRAINT:
# Remove the constraint key from the dictionary before converting to a dataframe
@@ -534,22 +532,23 @@ def make_graph(
y="y",
marker="o",
)
-
- x_unit = attribute.xaxis_parameter.unit
+
+ x_unit = attribute.parameters[attribute.x_axis].unit
y_unit = attribute.unit
plt.set(
xlabel=f"{x_label} / {x_unit}",
ylabel=f"{y_label} / {y_unit}",
)
-
+
# If we have a constraint, add a legend
if CONSTRAINT:
parameter_unit = attribute.parameters[constraint_param_name].unit
legend_title = f"{constraint_label} [{parameter_unit}]"
plt.legend(title=legend_title)
-
+
png = convert_plot_to_png(plt)
return png
+
```
Finally, use this function to create a plot image for each functional attribute and add it to the
@@ -575,7 +574,7 @@ for attribute_name, (title, y_label, x_label, constraint_info) in GRAPHS.items()
)
# Create a new slide based on the graph layout
graph_slide = prs.slides.add_slide(graph_layout)
-
+
# Set the title of the slide to be the graph title
graph_slide.shapes.title.text = title
for shape in graph_slide.placeholders:
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/12_Preparing_data_for_Power_BI.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/12_Preparing_data_for_Power_BI.md
index 60efac7e23..0e7f5db741 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/12_Preparing_data_for_Power_BI.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/12_Preparing_data_for_Power_BI.md
@@ -72,10 +72,10 @@ DataFrames have unique variable names.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
-import pandas
+import ansys.grantami.core as mpy
+import pandas as pd
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
# Create a DataFrame of all databases.
_databases = [
@@ -86,7 +86,7 @@ _databases = [
}
for db in mi.dbs
]
-databases = pandas.DataFrame.from_records(_databases)
+databases = pd.DataFrame.from_records(_databases)
# Create a DataFrame of all tables in all databases.
_tables = [
@@ -97,7 +97,7 @@ _tables = [
}
for db in mi.dbs for table in db.tables
]
-tables = pandas.DataFrame.from_records(_tables)
+tables = pd.DataFrame.from_records(_tables)
# Create a DataFrame of all attributes in all tables in all databases.
_all_attributes = [
@@ -106,13 +106,13 @@ _all_attributes = [
"Table.Guid": table.guid,
"Attribute.Name": attribute.name,
"Attribute.Type": attribute.type,
- "Attribute.Unit": attribute.unit,
+ "Attribute.Unit": getattr(attribute, "unit", None) or "",
"Attribute.Created": attribute.history.created_at,
"Attribute.LastModified": attribute.history.last_modified_at,
}
for db in mi.dbs for table in db.tables for attribute in table.attributes.values()
]
-all_attributes = pandas.DataFrame.from_records(_all_attributes)
+all_attributes = pd.DataFrame.from_records(_all_attributes)
```
## Advanced usage
@@ -152,7 +152,7 @@ example_table.bulk_fetch(
mpy.RecordProperties.last_modified_on,
mpy.RecordProperties.created_by,
mpy.RecordProperties.last_modified_by,
- ]
+ ],
)
_example_records_properties = [
{
@@ -167,7 +167,7 @@ _example_records_properties = [
}
for record in example_records
]
-example_records_revision = pandas.DataFrame.from_records(_example_records_properties)
+example_records_revision = pd.DataFrame.from_records(_example_records_properties)
# Create a DataFrame with the data revision information for all attributes for all records in the example table.
example_table.bulk_fetch_data_revision_history(example_records)
@@ -187,7 +187,7 @@ _example_records_data_revision = [
}
for record in example_records for attribute_name, attribute_revision in record.data_revision_history.items()
]
-example_records_data_revision = pandas.DataFrame.from_records(_example_records_data_revision)
+example_records_data_revision = pd.DataFrame.from_records(_example_records_data_revision)
```
### Performance considerations
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/13_Data_validation.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/13_Data_validation.md
index 81fec5420c..266ddc9afa 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/13_Data_validation.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/13_Data_validation.md
@@ -18,7 +18,7 @@ Before we define the rules, import the Scripting Toolkit so we can use Python ty
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
```
### check_attribute_is_populated
@@ -29,7 +29,7 @@ Next, define the first data validation rule. This rule will check that an attrib
```python
def check_attribute_is_populated(record: mpy.Record, attribute_name: str) -> tuple[bool, str | None]:
attribute = record.attributes[attribute_name]
- if attribute.is_empty():
+ if attribute.is_empty():
return False, f'Attribute "{attribute_name}" is not populated for record "{record.name}"'
return True, None
```
@@ -70,33 +70,24 @@ monotonically increasing for each individual series.
```python
def check_attribute_is_monotonically_increasing(record: mpy.Record, attribute_name: str) -> tuple[bool, str | None]:
- attribute = record.attributes[attribute_name]
-
- # Initialize values for the previous datapoint and series
- previous_y = previous_x = -float("inf")
- current_series = 0
-
- # Iterate over each row in the database, splitting the data by series
- for row in attribute.data_with_series_number[1:]:
- y = row[0] # First value is always the y attribute
- x = row[2] # Third value is always the x parameter
- series = row[-1] # The final value is the series number
-
- # If the series has changed, then update the series value
- if series != current_series:
- current_series = series
-
- # If the series hasn't changed, then check values
- elif y <= previous_y or x <= previous_x:
- return (
- False,
- f'Attribute "{attribute_name}", series {series} is not monotonically increasing for record '
- f'"{record.name}"'
- )
-
- # Update the previous values
- previous_y = y
- previous_x = x
+ attribute: mpy.AttributeFunctionalSeriesPoint = record.attributes[attribute_name]
+
+ for series_index, series in enumerate(attribute.value):
+ # Initialize values
+ previous_y = previous_x = -float("inf")
+ for y, x in zip(series.y, series.x):
+ # Check values
+ if y <= previous_y or x <= previous_x:
+ return (
+ False,
+ f'Attribute "{attribute_name}", series {series_index} is not monotonically increasing for record '
+ f'"{record.name}"',
+ )
+
+ # Update the previous values
+ previous_y = y
+ previous_x = x
+
return True, None
```
@@ -137,7 +128,7 @@ produces a list of records, for example searching for a last modified date, or u
```python
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
table = db.get_table("Design Data")
@@ -189,7 +180,7 @@ for record in records:
# Iterate over all validation rules for this attribute
for rule in validation_rules:
-
+
# These column values describe the check that will be performed.
check_result = {
"Record Name": record.name,
@@ -440,7 +431,7 @@ the following ways:
temperature is equal to a certain attribute.
* Automatically modifying the database to ensure consistency.
* Running the script automatically in batch mode. For more information see
- [Authentication](./../../user_guide/authentication.rst).
+ [Authentication](../../user_guide/authentication.rst).
* Tracking previous failures to provide a delta between multiple validation runs.
* Using a Python testing framework like [pytest](https://docs.pytest.org/en/stable/) to organize test cases
and provide result reports.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/assets/03_Expression.svg b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/assets/03_Expression.svg
new file mode 100644
index 0000000000..85023b986f
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/data-analytics/assets/03_Expression.svg
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/01_Exporting_data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/01_Exporting_data.md
index f077c16da6..567a58eef8 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/01_Exporting_data.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/01_Exporting_data.md
@@ -12,13 +12,13 @@ This example demonstrates:
## Create a Granta MI Session
-Import the GRANTA_MIScriptingToolkit package, and create a connection to a Granta MI server.
+Import the ansys.grantami.backend.soap package, and create a connection to a Granta MI server.
```python
-import GRANTA_MIScriptingToolkit as gdl
+import ansys.grantami.backend.soap as gdl
-session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", autoLogon=True)
+session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", auto_logon=True)
```
## Get the Databases
@@ -27,12 +27,12 @@ Access the browse service from the session and execute the *GetDatabases* method
```python
-browseService = session.browseService
-databases = browseService.GetDatabases().databases
+browse_service = session.browse_service
+databases = browse_service.get_databases().databases
print(f"Found {len(databases)} databases on the Granta MI Server")
for d in databases:
- print(f"Database key: {d.DBKey}, database name: {d.volumeName}")
+ print(f"Database key: {d.db_key}, database name: {d.volume_name}")
```
*Previous cell output:*
```output
@@ -47,8 +47,8 @@ import pandas as pd
df = pd.DataFrame(
{
- "DBKey": [db.DBKey for db in databases],
- "DBName": [db.volumeName for db in databases]
+ "DBKey": [db.db_key for db in databases],
+ "DBName": [db.volume_name for db in databases],
}
)
df
@@ -86,12 +86,12 @@ Use the *GetTables* method from the browse service to see what tables are availa
```python
dbKey = "MI_Training"
-tables = browseService.GetTables(gdl.GetTables(DBKey=dbKey)).tableDetails
+tables = browse_service.get_tables(gdl.GetTables(db_key=dbKey)).table_details
print(f"Found {len(tables)} tables in database {dbKey}")
print("Printing the first 5")
for t in tables[:5]:
- print(f"Table name: {t.tableReference.name}")
+ print(f"Table name: {t.table_reference.name}")
```
*Previous cell output:*
```output
@@ -113,22 +113,22 @@ normalized)*
table = "Tensile Test Data"
attribute = "Young's modulus (11-axis) (normalized)"
-tableRef = gdl.PartialTableReference(tableName=table)
-attrRef = gdl.AttributeReference(
+table_ref = gdl.PartialTableReference(table_name=table)
+attr_ref = gdl.AttributeReference(
name=attribute,
- DBKey=dbKey,
- partialTableReference=tableRef,
+ db_key=dbKey,
+ partial_table_reference=table_ref,
)
-searchCriterion = gdl.RecordSearchCriterion(
- searchAttribute=attrRef,
- existsSearchValue=gdl.ExistsSearchValue(),
+search_criterion = gdl.RecordSearchCriterion(
+ search_attribute=attr_ref,
+ exists_search_value=gdl.ExistsSearchValue(),
)
request = gdl.CriteriaSearch(
- DBKey=dbKey,
- searchCriteria=[searchCriterion],
+ db_key=dbKey,
+ search_criteria=[search_criterion],
)
-searchResults = session.searchService.CriteriaSearch(request).searchResults
+search_results = session.search_service.criteria_search(request).search_results
```
Print the *shortName* and *longName* of the first 5 records returned by the search.
@@ -137,8 +137,8 @@ Print the *shortName* and *longName* of the first 5 records returned by the sear
```python
df2 = pd.DataFrame(
{
- "ShortName": [r.shortName for r in searchResults],
- "LongName": [r.longName for r in searchResults]
+ "ShortName": [r.short_name for r in search_results],
+ "LongName": [r.long_name for r in search_results],
}
)
df2.head()
@@ -201,20 +201,21 @@ attributes = [
"Elastic Poisson's Ratio (12-plane)",
]
-attrRefs = [
+attribute_refs = [
gdl.AttributeReference(
name=a,
- DBKey=dbKey,
- partialTableReference=tableRef,
- ) for a in attributes
+ db_key=dbKey,
+ partial_table_reference=table_ref,
+ )
+ for a in attributes
]
-recordRefs = [r.recordReference for r in searchResults]
+record_refs = [r.record_reference for r in search_results]
request = gdl.GetRecordAttributesByRefRequest(
- recordReferences=recordRefs,
- attributeReferences=attrRefs,
+ record_references=record_refs,
+ attribute_references=attribute_refs,
)
-
-recordData = session.dataExportService.GetRecordAttributesByRef(request).recordData
+
+record_data = session.data_export_service.get_record_attributes_by_ref(request).record_data
```
Print the values of the attributes from the first 5 exported records. Note that some records may not have values for
@@ -222,13 +223,13 @@ all attributes.
```python
-s = [None]*len(df2)
+s = [None] * len(df2)
for attribute in attributes:
- for idx, record in enumerate(recordData):
- attrValue = next((x for x in record.attributeValues if x.attributeName == attribute), None)
- s[idx] = attrValue.pointDataType.points[0].value if attrValue else None
+ for idx, record in enumerate(record_data):
+ attr_value = next((x for x in record.attribute_values if x.attribute_name == attribute), None)
+ s[idx] = attr_value.point_data_value.points[0].value if attr_value else None
df2[attribute] = s
-
+
df2.head()
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/01_Exporting_data_files/01_Exporting_data_17_1.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/01_Exporting_data_files/01_Exporting_data_17_1.png
index aa92889473..89f975a382 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/01_Exporting_data_files/01_Exporting_data_17_1.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/01_Exporting_data_files/01_Exporting_data_17_1.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/02_Exporting_data_using_EngineeringDataService.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/02_Exporting_data_using_EngineeringDataService.md
index 43036460ae..77f0536276 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/02_Exporting_data_using_EngineeringDataService.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/02_Exporting_data_using_EngineeringDataService.md
@@ -11,13 +11,13 @@ This example demonstrates:
## Create a Granta MI Session
-Import the GRANTA_MIScriptingToolkit package, and create a connection to a Granta MI server.
+Import the ansys.grantami.backend.soap package, and create a connection to a Granta MI server.
```python
-import GRANTA_MIScriptingToolkit as gdl
+import ansys.grantami.backend.soap as gdl
-session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", autoLogon=True)
+session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", auto_logon=True)
```
## List the available exporters
@@ -26,33 +26,33 @@ Retrieve the list of FEA exporters that will export data from the database MI_Tr
```python
dbKey = "MI_Training"
-request = gdl.GetAvailableExportersRequest(DBKey=dbKey, package="ANSYS Workbench", matchDB=True)
+avail_exp_request = gdl.GetAvailableExportersRequest(db_key=dbKey, package="ANSYS Workbench", match_db=True)
print("Output of available Exporters for Ansys Workbench")
-response = session.engineeringDataService.GetAvailableExporters(request)
+avail_exp_response = session.engineering_data_service.get_available_exporters(avail_exp_request)
-for exporter in response.exporters:
+for exporter in avail_exp_response.exporters:
print(f"{exporter.name} ({exporter.package}) - {exporter.description}")
```
*Previous cell output:*
```output
Output of available Exporters for Ansys Workbench
-458E9A7E-C268-4ED0-9CC1-FF7438521B4F (ANSYS Workbench) - Exports linear, temperature-independent, isotropic data to the Ansys Workbench format
CE8DCFA2-B3EE-4545-8D3E-82810FA92AFC (ANSYS Workbench) - Exports linear, temperature-dependent, isotropic data to the Ansys Workbench format
+458E9A7E-C268-4ED0-9CC1-FF7438521B4F (ANSYS Workbench) - Exports linear, temperature-independent, isotropic data to the Ansys Workbench format
4B0B1EA3-8760-43DF-8060-2C79CA471D4C (ANSYS Workbench) - Exports linear, temperature-independent, isotropic with simple failure data to the Ansys Workbench format
```
Get a record by name.
```python
-req = gdl.RecordNameSearchRequest(
- recordName="Nickel alloys, Inconel 718, Forging",
- table=gdl.TableReference(DBKey=dbKey, name="Design Data"),
- searchShortNames=True
+search_req = gdl.RecordNameSearchRequest(
+ record_name="Nickel alloys, Inconel 718, Forging",
+ table=gdl.TableReference(db_key=dbKey, name="Design Data"),
+ search_short_names=True,
)
-resp = session.searchService.RecordNameSearch(req)
-print(f"Found {len(resp.searchResults)} record(s)")
-rec = resp.searchResults[0].recordReference
+search_resp = session.search_service.record_name_search(search_req)
+print(f"Found {len(search_resp.search_results)} record(s)")
+record = search_resp.search_results[0].record_reference
```
*Previous cell output:*
```output
@@ -63,23 +63,23 @@ Use the engineering data service to find valid FEA exporters for Inconel 718.
```python
-request = gdl.ExportersForRecordsRequest(records=[rec])
-resp = session.engineeringDataService.ExportersForRecords(request)
+exp_rec_request = gdl.ExportersForRecordsRequest(records=[record])
+exp_rec_resp = session.engineering_data_service.exporters_for_records(exp_rec_request)
print("Output of exporters for Inconel 718")
-for exporter in resp.records[0].exporters:
+for exporter in exp_rec_resp.records[0].exporters:
print(f"{exporter.name} ({exporter.package}) - {exporter.description}")
```
*Previous cell output:*
```output
Output of exporters for Inconel 718
+CE8DCFA2-B3EE-4545-8D3E-82810FA92AFC (ANSYS Workbench) - Exports linear, temperature-dependent, isotropic data to the Ansys Workbench format
71CE1C21-FDEA-4119-B481-81BDC41BD900 (Abaqus 6) - Exports temperature dependent, isotropic data to the Abaqus format.
-5C560880-4FD3-4E5C-992B-4B6CEF6A055A (Abaqus 6) - Exports temperature independent, isotropic data to the Abaqus 6 format.
911AF055-B388-439A-8AF6-EB18480E2D80 (Abaqus 6) - Linear, temperature-independent, isotropic, simple failure
+5C560880-4FD3-4E5C-992B-4B6CEF6A055A (Abaqus 6) - Exports temperature independent, isotropic data to the Abaqus 6 format.
3AE2BEA5-B1DB-45D3-A431-48915B8D1317 (Abaqus 6) - Linear, temperature-independent, isotropic, simple failure with thermal expansion
-722E5C46-3633-4B72-BF93-74E8112C20C3 (Abaqus 6) - Exports temperature dependent, isotropic data to the Abaqus 6 format.
B653C213-8BEB-42A7-8512-5F340EEBFAB4 (Abaqus 6) - Exports temperature independent, isotropic data to the Abaqus 6 format.
+722E5C46-3633-4B72-BF93-74E8112C20C3 (Abaqus 6) - Exports temperature dependent, isotropic data to the Abaqus 6 format.
458E9A7E-C268-4ED0-9CC1-FF7438521B4F (ANSYS Workbench) - Exports linear, temperature-independent, isotropic data to the Ansys Workbench format
-CE8DCFA2-B3EE-4545-8D3E-82810FA92AFC (ANSYS Workbench) - Exports linear, temperature-dependent, isotropic data to the Ansys Workbench format
4B0B1EA3-8760-43DF-8060-2C79CA471D4C (ANSYS Workbench) - Exports linear, temperature-independent, isotropic with simple failure data to the Ansys Workbench format
```
## Get a list of parameters that can be exported
@@ -87,10 +87,14 @@ Get the parameters that can be exported from Inconel 718 using an exporter that
```python
-exporter = resp.records[0].exporters[7]
-req = gdl.GetExporterParametersRequest(records=[rec], exporterKey=exporter.key)
-expParams = session.engineeringDataService.GetExporterParameters(req)
-for attrib in expParams.records[0].attributes:
+exporter = next(
+ exp for exp in exp_rec_resp.records[0].exporters
+ if exp.model == "Linear, temperature-dependent, isotropic"
+ and exp.package == "ANSYS Workbench"
+)
+exp_param_req = gdl.GetExporterParametersRequest(records=[record], exporter_key=exporter.key)
+exporter_parameters = session.engineering_data_service.get_exporter_parameters(exp_param_req)
+for attrib in exporter_parameters.records[0].attributes:
print(attrib.attribute.name)
for param in attrib.parameters:
print(f"\t{param.name}")
@@ -107,8 +111,8 @@ Get all applicable attributes for this record.
```python
-req = gdl.GetRecordAttributesRequest(recordReferences=[rec])
-attribs = session.browseService.GetRecordAttributes(req)
+gra_req = gdl.GetRecordAttributesRequest(record_references=[record])
+attribs = session.browse_service.get_record_attributes(gra_req)
```
If exporting a functional data attribute, you also need to define a parameter value to evaluate the attribute at.
@@ -116,15 +120,15 @@ Here, a parameter is fixed at 1.337.
```python
-myParam = expParams.records[0].attributes[0].parameters[0]
+parameter = exporter_parameters.records[0].attributes[0].parameters[0]
pwv = gdl.ParameterReferenceAndValue(
- parameterValue=gdl.ParameterValue(numericValue=1.337),
- parameter=myParam.parameterReference,
+ parameter_value=gdl.ParameterValue(numeric_value=1.337),
+ parameter=parameter.parameter_reference,
)
pv = gdl.UnittedParameterValue(
- unitSymbol=myParam.unit.unitSymbol,
- parameterWithValues=pwv,
+ unit_symbol=parameter.unit.unit_symbol,
+ parameter_with_values=pwv,
)
```
@@ -132,14 +136,14 @@ Run the FEA exporter, and print the output.
```python
-expReq = gdl.ExportRecordDataRequest(
- attributeReferences=[a.attribute.attribute for a in attribs.recordAttributes],
- records=[rec],
- exporterKey=exporter.key,
- parameterValues=[pv]
+export_data_request = gdl.ExportRecordDataRequest(
+ attribute_references=[a.attribute.attribute for a in attribs.record_attributes],
+ records=[record],
+ exporter_key=exporter.key,
+ parameter_values=[pv],
)
-resp = session.engineeringDataService.ExportRecordData(expReq)
+resp = session.engineering_data_service.export_record_data(export_data_request)
print(resp.text[:200] + "...")
```
@@ -156,11 +160,10 @@ directory.
```python
from pathlib import Path
-Path("./output").mkdir(exist_ok=True)
-```
+output_dir = Path("./output")
+output_dir.mkdir(exist_ok=True)
-```python
-with open("output/engineering_data.xml", "wb") as f:
+with open(output_dir / "engineering_data.xml", "wb") as f:
f.write(resp.text.encode("utf-8"))
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/03_Text_search.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/03_Text_search.md
index 05b9c17c64..493c6ddea9 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/03_Text_search.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/03_Text_search.md
@@ -10,13 +10,13 @@ This example demonstrates:
## Create a Granta MI Session
-Import the GRANTA_MIScriptingToolkit package, and create a connection to a Granta MI server.
+Import the ansys.grantami.backend.soap package, and create a connection to a Granta MI server.
```python
-import GRANTA_MIScriptingToolkit as gdl
+import ansys.grantami.backend.soap as gdl
-session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", autoLogon=True)
+session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", auto_logon=True)
```
## Select a database
@@ -25,11 +25,11 @@ View the databases available on your Granta MI server.
```python
-databases = session.browseService.GetDatabases().databases
+databases = session.browse_service.get_databases().databases
print(f"Found {len(databases)} databases on the Granta MI Server")
for d in databases:
- print(f"Database key: {d.DBKey}, Database name: {d.volumeName}")
+ print(f"Database key: {d.db_key}, Database name: {d.volume_name}")
```
*Previous cell output:*
```output
@@ -42,19 +42,19 @@ Search in the MI Training database for records containing the text *Leather*.
```python
-dbKey = "MI_Training"
-searchText = "leather"
+db_key = "MI_Training"
+search_text = "leather"
-simpleTextSearch = gdl.SimpleTextSearch(searchValue=searchText, DBKey=dbKey)
-simpleTextSearchResponse = session.searchService.SimpleTextSearch(simpleTextSearch)
+simple_text_search = gdl.SimpleTextSearch(search_value=search_text, db_key=db_key)
+search_response = session.search_service.simple_text_search(simple_text_search)
```
Print the results returned by the search.
```python
-for result in simpleTextSearchResponse.searchResults:
- print(result.shortName)
+for result in search_response.search_results:
+ print(result.short_name)
```
*Previous cell output:*
```output
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/04_Deleting_records.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/04_Deleting_records.md
index 5ebb71949c..174f0714e5 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/04_Deleting_records.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/04_Deleting_records.md
@@ -1,62 +1,62 @@
# Deleting records (DeleteOrWithdrawIfLatestRecordVersion)
-Let's start by creating a new record (Note: added receiveTimeout to the MISession)
+Let's start by creating a new record (Note: added receive_timeout to the MISession)
```python
from datetime import datetime
-import GRANTA_MIScriptingToolkit as gdl
+import ansys.grantami.backend.soap as gdl
-session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer/", autoLogon=True, receiveTimeout=5000)
+session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer/", auto_logon=True, receive_timeout=5000)
now = datetime.now().strftime("%c")
-record_name = f"Scripting toolkit foundation layer example 04:{now}"
+record_name = f"Scripting Toolkit Foundation Layer Example 4:{now}"
table_name = "Tensile Test Data"
subset_name = table_name
db_key = "MI_Training"
-import_service = session.dataImportService
-browse_service = session.browseService
+import_service = session.data_import_service
+browse_service = session.browse_service
-test_table_ref = gdl.TableReference(name=table_name, DBKey=db_key)
-partial_table_ref = gdl.PartialTableReference(tableName=table_name)
+test_table_ref = gdl.TableReference(name=table_name, db_key=db_key)
+partial_table_ref = gdl.PartialTableReference(table_name=table_name)
subset_ref = gdl.SubsetReference(
- DBKey=db_key,
- partialTableReference=partial_table_ref,
+ db_key=db_key,
+ partial_table_reference=partial_table_ref,
name=subset_name,
)
-table_root_ref = browse_service.GetRootNode(gdl.GetRootNode(table=test_table_ref)).rootNode.recordReference
+table_root_ref = browse_service.get_root_node(gdl.GetRootNode(table=test_table_ref)).root_node.record_reference
import_record = gdl.ImportRecord(
- recordName=record_name,
- importAttributeValues=None,
- isFolder=False,
- existingRecord=table_root_ref,
- subsetReferences=[subset_ref],
+ record_name=record_name,
+ import_attribute_values=None,
+ is_folder=False,
+ existing_record=table_root_ref,
+ subset_references=[subset_ref],
)
-import_request = gdl.SetRecordAttributesRequest(importRecords=[import_record])
-imported_records = import_service.SetRecordAttributes(import_request).recordsImported
-imported_record_ref = imported_records[0].recordReference
-print(f'Imported record "{imported_records[0].longName}" to table "{table_name}"')
+import_request = gdl.SetRecordAttributesRequest(import_records=[import_record])
+imported_records = import_service.set_record_attributes(import_request).records_imported
+imported_record_ref = imported_records[0].record_reference
+print(f'Imported record "{imported_records[0].long_name}" to table "{table_name}"')
```
*Previous cell output:*
```output
-Imported record "Scripting toolkit foundation layer example 04:Mon May 12 16:19:46 2025" to table "Tensile Test Data"
+Imported record "Scripting Toolkit Foundation Layer Example 4:Wed Jan 7 19:30:39 2026" to table "Tensile Test Data"
```
Now let's delete it!
```python
-delete_record = gdl.DeleteOrWithdrawRecord(recordReference=imported_record_ref)
+delete_record = gdl.DeleteOrWithdrawRecord(record_reference=imported_record_ref)
records_to_delete = [delete_record]
-delete_records_request = gdl.DeleteOrWithdrawIfLatestRecordVersionRequest(deleteOrWithdrawRecords=records_to_delete)
-delete_records_response = import_service.DeleteOrWithdrawIfLatestRecordVersion(delete_records_request)
-print(f"Record {imported_records[0].longName} was deleted")
+delete_records_request = gdl.DeleteOrWithdrawIfLatestRecordVersionRequest(delete_or_withdraw_records=records_to_delete)
+delete_records_response = import_service.delete_or_withdraw_if_latest_record_version(delete_records_request)
+print(f"Record {imported_records[0].long_name} was deleted")
```
*Previous cell output:*
```output
-Record Scripting toolkit foundation layer example 04:Mon May 12 16:19:46 2025 was deleted
+Record Scripting Toolkit Foundation Layer Example 4:Wed Jan 7 19:30:39 2026 was deleted
```
\ No newline at end of file
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/05_Functional_data_and_importing_data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/05_Functional_data_and_importing_data.md
index 51a19b4fd4..8e14580918 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/05_Functional_data_and_importing_data.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/05_Functional_data_and_importing_data.md
@@ -11,15 +11,14 @@ This example demonstrates:
## Create a Granta MI Session
-Import the GRANTA_MIScriptingToolkit package, and create a connection to a Granta MI server.
+Import the ansys.grantami.backend.soap package, and create a connection to a Granta MI server.
```python
from datetime import datetime
-import sys
-import GRANTA_MIScriptingToolkit as gdl
+import ansys.grantami.backend.soap as gdl
-session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", autoLogon=True)
+session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", auto_logon=True)
```
## Browse for records
@@ -30,28 +29,30 @@ Set the folder path for the record to browse to as: High Alloy Steel / AMS 6520
```python
-dbKey = "MI_Training"
+db_key = "MI_Training"
table = "Tensile Statistical Data"
-folderPath = ["High Alloy Steel", "AMS 6520", "Plate", "Room Temperature °F"]
+folder_path = ["High Alloy Steel", "AMS 6520", "Plate", "Room Temperature °F"]
```
Get the root node of the table of interest.
```python
-tableReference = gdl.TableReference(DBKey=dbKey, name=table)
-treeRecord = session.browseService.GetRootNode(gdl.GetRootNode(tableReference)).rootNode
+table_reference = gdl.TableReference(db_key=db_key, name=table)
+tree_record = session.browse_service.get_root_node(gdl.GetRootNode(table_reference)).root_node
```
Find the record of interest, *AMS 6520, Plate, Room Temperature °F*.
```python
-for folder in folderPath:
- treeRecords = session.browseService.GetChildNodes(gdl.GetChildNodes(parent=treeRecord.recordReference)).treeRecords
- treeRecord = next((r for r in treeRecords if r.shortName == folder), None)
- if treeRecord:
- print(f"Found treeRecord: {treeRecord.shortName}")
+for folder in folder_path:
+ tree_records = session.browse_service.get_child_nodes(
+ gdl.GetChildNodes(parent=tree_record.record_reference)
+ ).tree_records
+ tree_record = next((r for r in tree_records if r.short_name == folder), None)
+ if tree_record:
+ print(f"Found treeRecord: {tree_record.short_name}")
else:
raise ValueError(f"Unable to find folder: {folder}")
```
@@ -70,26 +71,26 @@ Export *Tensile Response (11 axis)* data from the record of interest.
```python
attribute = "Tensile Response (11 axis)"
-partialTableRef = gdl.PartialTableReference(tableName=table)
-attrRef = gdl.AttributeReference(
+partial_table_ref = gdl.PartialTableReference(table_name=table)
+attribute_reference = gdl.AttributeReference(
name=attribute,
- DBKey=dbKey,
- partialTableReference=partialTableRef,
+ db_key=db_key,
+ partial_table_reference=partial_table_ref,
)
request = gdl.GetRecordAttributesByRefRequest(
- recordReferences=[treeRecord.recordReference],
- attributeReferences=[attrRef],
+ record_references=[tree_record.record_reference],
+ attribute_references=[attribute_reference],
)
-data = session.dataExportService.GetRecordAttributesByRef(request).recordData[0]
+data = session.data_export_service.get_record_attributes_by_ref(request).record_data[0]
```
Check the data type of the *Tensile Response (11 axis)* attribute is FLOAT_FUNCTIONAL_SERIES.
```python
-value = data.attributeValues[0]
-print(f"Attribute Name: {value.attributeName}, Type {value.dataType}")
+value = data.attribute_values[0]
+print(f"Attribute Name: {value.attribute_name}, Type {value.data_type}")
```
*Previous cell output:*
```output
@@ -99,17 +100,17 @@ Extract the data from each curve into a list.
```python
-graph = value.floatFunctionalSeriesDataType.graph
+graph = value.float_functional_series_data_value.graph
series = graph.series
curves = []
for curve in series:
- points = curve.XYPoints.XYPoints
- x = [point.parameterValue.numericValue for point in points]
- y = [point.Y for point in points]
- curves.append([x,y])
-
+ points = curve.xy_points.xy_points
+ x = [point.parameter_value.numeric_value for point in points]
+ y = [point.y for point in points]
+ curves.append([x, y])
+
print(curves)
```
*Previous cell output:*
@@ -122,7 +123,7 @@ Plot the curves using the matplotlib package.
```python
import matplotlib.pyplot as plt
-x_label = f"{graph.XAxisParameter.name} ({graph.XAxisParameter.unit.unitSymbol})"
+x_label = f"{graph.x_axis_parameter.name} ({graph.x_axis_parameter.unit.unit_symbol})"
y_label = "Tensile stress 10^6 (Pa)"
fig = plt.figure()
@@ -149,15 +150,12 @@ import matplotlib.pyplot as plt
from scipy.optimize import leastsq
import numpy as np
-
def ramberg_osgood(p, stress):
- return (stress/p[0])*(1.0 + p[1]*(stress/p[2])**(p[3]-1))
-
+ return (stress / p[0]) * (1.0 + p[1] * (stress / p[2]) ** (p[3] - 1))
def error_function(p, stress, strain):
return ramberg_osgood(p, stress) - strain
-
strain = 0.01 * np.array(curves[0][0])
stress = np.array(curves[0][1])
@@ -171,23 +169,15 @@ ax.set_xlabel(x_label)
ax.set_ylabel(y_label)
ax.plot(ramberg_osgood(plsq[0], stress), stress, label="Fit")
-ax.plot(strain, stress, marker='o', linestyle=' ', label="Data")
+ax.plot(strain, stress, marker="o", linestyle=" ", label="Data")
ax.set_title("Ramberg-Osgood fit")
-ax.legend()
-```
-
-
-
-*Previous cell output:*
-```output
-
+_ = ax.legend()
```
-
-
+
@@ -200,20 +190,22 @@ Identify the folder to upload the new record to. Browse the record tree to get t
```python
-importDBKey = "MI_Training"
-importTableName = "Tensile Statistical Data"
-importFolders = ["High Alloy Steel", "AMS 6520"]
+import_db_key = "MI_Training"
+import_table_name = "Tensile Statistical Data"
+import_folders = ["High Alloy Steel", "AMS 6520"]
now = datetime.now().strftime("%c")
-importRecordName = f"Scripting toolkit foundation layer example 05:{now}"
-
-importTableReference = gdl.TableReference(DBKey=importDBKey, name=importTableName)
-treeRecord = session.browseService.GetRootNode(gdl.GetRootNode(table=importTableReference)).rootNode
-
-for folder in importFolders:
- treeRecords = session.browseService.GetChildNodes(gdl.GetChildNodes(parent=treeRecord.recordReference)).treeRecords
- treeRecord = next((r for r in treeRecords if r.shortName == folder), None)
- if treeRecord:
- print(f"Found treeRecord folder: {treeRecord.shortName}")
+import_record_name = f"Scripting Toolkit Foundation Layer Example 5:{now}"
+
+import_table_reference = gdl.TableReference(db_key=import_db_key, name=import_table_name)
+tree_record = session.browse_service.get_root_node(gdl.GetRootNode(table=import_table_reference)).root_node
+
+for folder in import_folders:
+ tree_records = session.browse_service.get_child_nodes(
+ gdl.GetChildNodes(parent=tree_record.record_reference)
+ ).tree_records
+ tree_record = next((r for r in tree_records if r.short_name == folder), None)
+ if tree_record:
+ print(f"Found treeRecord folder: {tree_record.short_name}")
else:
raise ValueError(f"Unable to find import folder: {folder}")
```
@@ -226,10 +218,10 @@ Define the record attribute to include in the new record.
```python
-modulusAttributeReference = gdl.AttributeReference(
+modulus_attribute_reference = gdl.AttributeReference(
name="Young's Modulus (11-axis)",
- DBKey=importDBKey,
- partialTableReference=gdl.PartialTableReference(tableName=importTableName)
+ db_key=import_db_key,
+ partial_table_reference=gdl.PartialTableReference(table_name=import_table_name),
)
```
@@ -237,12 +229,12 @@ Set values and units for the attributes of the new record.
```python
-fittedEValue = plsq[0][0]
-modulusValue = gdl.PointValueWithParameters(value=fittedEValue)
-modulusPointValue = gdl.PointDataType(unitSymbol="psi", points=[modulusValue])
-importModulusValue = gdl.ImportAttributeValue(
- attributeReference=modulusAttributeReference,
- pointDataValue=modulusPointValue,
+fitted_e_value = plsq[0][0]
+modulus_value = gdl.PointValueWithParameters(value=fitted_e_value)
+modulus_point_value = gdl.PointDataType(unit_symbol="psi", points=[modulus_value])
+import_modulus_value = gdl.ImportAttributeValue(
+ attribute_reference=modulus_attribute_reference,
+ point_data_value=modulus_point_value,
)
```
@@ -250,10 +242,10 @@ Create a reference to the subset that the new record will be added to.
```python
-subsetReference = gdl.SubsetReference(
+subset_reference = gdl.SubsetReference(
name="Statistical Test Data",
- DBKey=importDBKey,
- partialTableReference=gdl.PartialTableReference(tableName=importTableName)
+ db_key=import_db_key,
+ partial_table_reference=gdl.PartialTableReference(table_name=import_table_name),
)
```
@@ -261,20 +253,20 @@ Import the record to the Granta MI database.
```python
-importRecord = gdl.ImportRecord(
- recordName=importRecordName,
- existingRecord=treeRecord.recordReference,
- subsetReferences=[subsetReference],
- importAttributeValues=[importModulusValue],
+import_record = gdl.ImportRecord(
+ record_name=import_record_name,
+ existing_record=tree_record.record_reference,
+ subset_references=[subset_reference],
+ import_attribute_values=[import_modulus_value],
)
-setRecordAttributesRequest = gdl.SetRecordAttributesRequest(importRecords=[importRecord])
-setRecordAttributesResponse = session.dataImportService.SetRecordAttributes(setRecordAttributesRequest)
+set_record_attributes_request = gdl.SetRecordAttributesRequest(import_records=[import_record])
+set_record_attributes_response = session.data_import_service.set_record_attributes(set_record_attributes_request)
-for record in setRecordAttributesResponse.recordsImported:
- print(f"Imported record {record.shortName} to Granta MI database")
+for record in set_record_attributes_response.records_imported:
+ print(f"Imported record {record.short_name} to Granta MI database")
```
*Previous cell output:*
```output
-Imported record Scripting toolkit foundation layer example 05:Mon May 12 16:20:13 2025 to Granta MI database
+Imported record Scripting Toolkit Foundation Layer Example 5:Wed Jan 7 19:31:10 2026 to Granta MI database
```
\ No newline at end of file
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/05_Functional_data_and_importing_data_files/05_Functional_data_and_importing_data_15_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/05_Functional_data_and_importing_data_files/05_Functional_data_and_importing_data_15_0.png
index 489ce40f38..2a713e187b 100644
Binary files a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/05_Functional_data_and_importing_data_files/05_Functional_data_and_importing_data_15_0.png and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/05_Functional_data_and_importing_data_files/05_Functional_data_and_importing_data_15_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/05_Functional_data_and_importing_data_files/05_Functional_data_and_importing_data_17_0.png b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/05_Functional_data_and_importing_data_files/05_Functional_data_and_importing_data_17_0.png
new file mode 100644
index 0000000000..5b24fa3345
Binary files /dev/null and b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/05_Functional_data_and_importing_data_files/05_Functional_data_and_importing_data_17_0.png differ
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/06_Importing_and_exporting_tabular_data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/06_Importing_and_exporting_tabular_data.md
index fe7ed43474..991f3431a0 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/06_Importing_and_exporting_tabular_data.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/06_Importing_and_exporting_tabular_data.md
@@ -12,14 +12,14 @@ This example demonstrates:
## Create a Granta MI Session
-Import the GRANTA_MIScriptingToolkit package, and create a connection to a Granta MI server.
+Import the ansys.grantami.backend.soap package, and create a connection to a Granta MI server.
```python
from datetime import datetime
-import GRANTA_MIScriptingToolkit as gdl
+import ansys.grantami.backend.soap as gdl
-session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", autoLogon=True)
+session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", auto_logon=True)
```
## Get tabular data attribute information
@@ -28,34 +28,34 @@ Search for the record "Shore A75, flame retarded" in the "MI_Training" database.
```python
-dbKey = "MI_Training"
-tableName = "MaterialUniverse"
-recordName = "Shore A75, flame retarded"
+db_key = "MI_Training"
+table_name = "MaterialUniverse"
+record_name = "Shore A75, flame retarded"
req = gdl.RecordNameSearchRequest(
- caseSensitiveNames=False,
- searchShortNames=True,
- recordName=recordName,
+ case_sensitive_names=False,
+ search_short_names=True,
+ record_name=record_name,
)
-req.table = gdl.TableReference(DBKey=dbKey, name=tableName)
-resp = session.searchService.RecordNameSearch(req)
-record = resp.searchResults[0]
+req.table = gdl.TableReference(db_key=db_key, name=table_name)
+resp = session.search_service.record_name_search(req)
+record = resp.search_results[0]
```
Use the browse service to get the column headers for the tabular data attribute "Specifications".
```python
-attribName = "Restricted substances that may be associated with this material"
+attribute_name = "Restricted substances that may be associated with this material"
a = gdl.AttributeReference(
- name=attribName,
- partialTableReference=gdl.PartialTableReference(tableName=tableName),
- DBKey=dbKey,
+ name=attribute_name,
+ partial_table_reference=gdl.PartialTableReference(table_name=table_name),
+ db_key=db_key,
)
-resp = session.browseService.GetAttributeDetails(gdl.GetAttributeDetailsRequest([a]))
-for col in resp.attributeDetails[0].tabular.columns:
+resp = session.browse_service.get_attribute_details(gdl.GetAttributeDetailsRequest([a]))
+for col in resp.attribute_details[0].tabular.columns:
print(col.name)
```
*Previous cell output:*
@@ -77,21 +77,22 @@ Perform a data export request to get column data for the tabular data attribute.
```python
-dataExportRequest = gdl.GetRecordAttributesByRefRequest(
- recordReferences=[record.recordReference],
- attributeReferences=[a],
+data_export_request = gdl.GetRecordAttributesByRefRequest(
+ record_references=[record.record_reference],
+ attribute_references=[a],
)
-dataExportResponse = session.dataExportService.GetRecordAttributesByRef(dataExportRequest)
-myRecordData = dataExportResponse.recordData
+data_export_response = session.data_export_service.get_record_attributes_by_ref(data_export_request)
+record_data = data_export_response.record_data
-for rec in myRecordData:
- for attr in rec.attributeValues:
- if attr.attributeName == attribName:
- if not attr.dataType == "TABL":
- raise TypeError("No tables found! Check your record.")
- myTable = attr.tabularDataType
+tabular_value = None
+for rec in record_data:
+ for attr in rec.attribute_values:
+ if attr.attribute_name == attribute_name:
+ tabular_value = attr.tabular_data_value
print("Table found.")
+if tabular_value is None:
+ raise TypeError("No tables found! Check your record.")
```
*Previous cell output:*
```output
@@ -103,14 +104,14 @@ items all have a dataType attribute to help you pick the right data member to in
```python
i = 1
-for row in myTable.tabularDataRows:
- if len(row.cells[0].listDataValue.items) > 0:
+for row in tabular_value.tabular_data_rows:
+ if len(row.cells[0].list_data_value.items) > 0:
print(f"Row {i}:")
- print(f"\t{row.cells[0].listDataValue.items[0].shortTextDataValue.value}")
- print(f"\t{row.cells[1].listDataValue.items[0].shortTextDataValue.value}")
- print(f"\t{row.cells[2].rangeDataValue.low}-{row.cells[2].rangeDataValue.high}")
- print(f"\t{row.cells[3].discreteDataValue.discreteValues[0].value}")
- print(f"\t{row.cells[4].shortTextDataValue.value}")
+ print(f"\t{row.cells[0].list_data_value.items[0].short_text_data_value.value}")
+ print(f"\t{row.cells[1].list_data_value.items[0].short_text_data_value.value}")
+ print(f"\t{row.cells[2].range_data_value.low}-{row.cells[2].range_data_value.high}")
+ print(f"\t{row.cells[3].discrete_data_value.discrete_values[0].value}")
+ print(f"\t{row.cells[4].short_text_data_value.value}")
i = i + 1
```
*Previous cell output:*
@@ -135,40 +136,39 @@ Row 3:
```
## Import tabular data
-Search the database for a parent record under which you can create a new record.
+Search the database for a parent record under which you can create a new record.
```python
-dbKey = "MI_Training"
-tableName = "Training Exercise for Import"
-recordName = "Metal"
+db_key = "MI_Training"
+table_name = "Training Exercise for Import"
+record_name = "Metal"
req = gdl.RecordNameSearchRequest(
- caseSensitiveNames=False,
- searchShortNames=True,
- recordName=recordName,
+ case_sensitive_names=False,
+ search_short_names=True,
+ record_name=record_name,
)
-req.table = gdl.TableReference(DBKey=dbKey, name=tableName)
-resp = session.searchService.RecordNameSearch(req)
-destination = resp.searchResults[0]
+req.table = gdl.TableReference(db_key=db_key, name=table_name)
+resp = session.search_service.record_name_search(req)
+destination = resp.search_results[0]
```
Create an empty data structure, and populate it with tabular data values.
```python
-newTable = gdl.TabularDataType()
-newTable.AddColumn("Order")
-newTable.AddColumn("Notes")
+integer_value = gdl.IntegerDataType(value=1)
+integer_cell = gdl.TabularDataImportCell(column_name="Order", integer_data_value=integer_value)
-newRow = newTable.CreateRow()
-newInt = gdl.IntegerDataType(value=1)
-newRow.cells[0].data = newInt
+text_value = gdl.LongTextDataType(value="Some notes about a material")
+text_cell = gdl.TabularDataImportCell(column_name="Notes", long_text_data_value=text_value)
-newText = gdl.LongTextDataType(value="Some notes about a material")
-newRow.cells[1].data = newText
+new_row = gdl.TabularDataImportRow(cells=[integer_cell, text_cell])
-print(f"Created a table with cell data {newInt.value} and {newText.value}")
+tabular_update = gdl.TabularDataImportType(import_rows=[new_row])
+
+print(f"Created a table with cell data {integer_value.value} and {text_value.value}")
```
*Previous cell output:*
```output
@@ -178,16 +178,16 @@ Create a new import attribute, "Characterization of this material", that contain
```python
-attribName = "Characterization of this material"
+attribute_name = "Characterization of this material"
a = gdl.AttributeReference(
- name=attribName,
- partialTableReference=gdl.PartialTableReference(tableName=tableName),
- DBKey=dbKey,
+ name=attribute_name,
+ partial_table_reference=gdl.PartialTableReference(table_name=table_name),
+ db_key=db_key,
)
-importAtribute = gdl.ImportAttributeValue(attributeReference=a)
-importAtribute.tabularDataValue = newTable
+import_attribute_value = gdl.ImportAttributeValue(attribute_reference=a)
+import_attribute_value.tabular_data_value = tabular_update
```
Create a new import record.
@@ -195,28 +195,28 @@ Create a new import record.
```python
now = datetime.now().strftime("%c")
-recName = f"Scripting toolkit foundation layer example 06:{now}"
+new_record_name = f"Scripting Toolkit Foundation Layer Example 6:{now}"
-importRecord = gdl.ImportRecord(
- recordName=recName,
- existingRecord=destination.recordReference,
- importAttributeValues=[importAtribute],
+import_record = gdl.ImportRecord(
+ record_name=new_record_name,
+ existing_record=destination.record_reference,
+ import_attribute_values=[import_attribute_value],
)
-print(recName)
+print(new_record_name)
```
*Previous cell output:*
```output
-Scripting toolkit foundation layer example 06:Mon May 12 16:20:48 2025
+Scripting Toolkit Foundation Layer Example 6:Wed Jan 7 19:31:40 2026
```
Import the record to a Granta MI database.
```python
-setRecordAttributesRequest = gdl.SetRecordAttributesRequest(importRecords=[importRecord])
-response = session.dataImportService.SetRecordAttributes(setRecordAttributesRequest)
-recordsImported = response.recordsImported
+set_record_attributes_request = gdl.SetRecordAttributesRequest(import_records=[import_record])
+response = session.data_import_service.set_record_attributes(set_record_attributes_request)
+records_imported = response.records_imported
-print(f"{len(recordsImported)} records imported")
+print(f"{len(records_imported)} records imported")
```
*Previous cell output:*
```output
@@ -228,15 +228,15 @@ Retrieve the row ID of the data that you want to update.
```python
-dataExportRequest = gdl.GetRecordAttributesByRefRequest(
- recordReferences=[response.recordsImported[0].recordReference],
- attributeReferences=[a],
+data_export_request = gdl.GetRecordAttributesByRefRequest(
+ record_references=[response.records_imported[0].record_reference],
+ attribute_references=[a],
)
-dataExportResponse = session.dataExportService.GetRecordAttributesByRef(dataExportRequest)
-myRecordData = dataExportResponse.recordData[0]
-attribute = myRecordData.attributeValues[0].tabularDataType
+data_export_response = session.data_export_service.get_record_attributes_by_ref(data_export_request)
+my_record_data = data_export_response.record_data[0]
+attribute = my_record_data.attribute_values[0].tabular_data_value
-aid = attribute.tabularDataRows[0].Id
+aid = attribute.tabular_data_rows[0].id_
print(f"This row's ID is {aid}")
```
@@ -249,16 +249,13 @@ data values.
```python
-updatedValue = gdl.IntegerDataType(value=newInt.value * 1000)
-print(f"Updated previous value to {updatedValue.value}")
-
-tableUpdates = gdl.TabularDataType()
-tableUpdates.AddColumn("Order")
-
-changetype = gdl.TabularDataType.ChangeType.Update
+updated_value = gdl.IntegerDataType(value=integer_value.value * 1000)
+update_cell = gdl.TabularDataImportCell(column_name="Order", integer_data_value=updated_value)
+print(f"Updated previous value to {updated_value.value}")
-rowChange = tableUpdates.CreateUpdateRow(changetype, aid)
-rowChange.cells[0].data = updatedValue
+change_type = "Update"
+row_change = gdl.TabularDataUpdateRow(cells=[update_cell], id_=aid, update_type=change_type)
+table_updates = gdl.TabularDataImportType(update_rows=[row_change])
```
*Previous cell output:*
```output
@@ -268,24 +265,24 @@ Import the updated data into Granta MI using SetRecordAttributes.
```python
-attribute = gdl.ImportAttributeValue(attributeReference=a)
-attribute.tabularDataValue = tableUpdates
+attribute = gdl.ImportAttributeValue(attribute_reference=a)
+attribute.tabular_data_value = table_updates
-updateRecord = gdl.ImportRecord(
- importRecordMode="Update",
- existingRecord=recordsImported[0].recordReference,
- importAttributeValues=[attribute],
+update_record = gdl.ImportRecord(
+ import_record_mode="Update",
+ existing_record=records_imported[0].record_reference,
+ import_attribute_values=[attribute],
)
-setRecordAttributesRequest = gdl.SetRecordAttributesRequest(importRecords=[updateRecord])
-response = session.dataImportService.SetRecordAttributes(setRecordAttributesRequest)
+set_record_attributes_request = gdl.SetRecordAttributesRequest(import_records=[update_record])
+response = session.data_import_service.set_record_attributes(set_record_attributes_request)
print(
- f"Use MI Viewer to view {recName} and check that the Order "
- f"in 'Characterization of this material' is {updatedValue.value}"
+ f"Use MI Viewer to view '{new_record_name}' and check that the Order "
+ f"in 'Characterization of this material' is {updated_value.value}"
)
```
*Previous cell output:*
```output
-Use MI Viewer to view Scripting toolkit foundation layer example 06:Mon May 12 16:20:48 2025 and check that the Order in 'Characterization of this material' is 1000
+Use MI Viewer to view 'Scripting Toolkit Foundation Layer Example 6:Wed Jan 7 19:31:40 2026' and check that the Order in 'Characterization of this material' is 1000
```
\ No newline at end of file
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/07_Modified_date.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/07_Modified_date.md
index 17006d7043..5de207245c 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/07_Modified_date.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/07_Modified_date.md
@@ -4,44 +4,45 @@ Modify a record
```python
-import GRANTA_MIScriptingToolkit as gdl
-import datetime
+from datetime import datetime
-session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer/", autoLogon=True, receiveTimeout=5000)
+import ansys.grantami.backend.soap as gdl
+
+session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer/", auto_logon=True, receive_timeout=5000)
db_key = "MI_Training"
table_name = "Tensile Test Data"
-import_service = session.dataImportService
-browse_service = session.browseService
-export_service = session.dataExportService
+import_service = session.data_import_service
+browse_service = session.browse_service
+export_service = session.data_export_service
-partial_table_ref = gdl.PartialTableReference(tableName=table_name)
+partial_table_ref = gdl.PartialTableReference(table_name=table_name)
-modfied_record_guid = "4269f1bc-df6b-4a6d-870c-ef931728f37b"
-modified_record_ref = gdl.RecordReference(DBKey=db_key, recordGUID=modfied_record_guid)
+modified_record_guid = "4269f1bc-df6b-4a6d-870c-ef931728f37b"
+modified_record_ref = gdl.RecordReference(db_key=db_key, record_guid=modified_record_guid)
attribute_project_notes = "Project Notes"
-attribute_val = f"Project was updated: {datetime.datetime.now()}"
+attribute_val = f"Project was updated: {datetime.now()}"
attribute_ref = gdl.AttributeReference(
name=attribute_project_notes,
- DBKey=db_key,
- partialTableReference=partial_table_ref,
+ db_key=db_key,
+ partial_table_reference=partial_table_ref,
)
import_attribute_val = gdl.ImportAttributeValue(
- longTextDataValue=gdl.LongTextDataType(value=attribute_val),
- attributeReference=attribute_ref,
+ long_text_data_value=gdl.LongTextDataType(value=attribute_val),
+ attribute_reference=attribute_ref,
)
update_record = gdl.ImportRecord(
- recordName=None,
- importRecordMode="Update",
- importAttributeValues=[import_attribute_val],
- existingRecord=modified_record_ref,
+ record_name=None,
+ import_record_mode="Update",
+ import_attribute_values=[import_attribute_val],
+ existing_record=modified_record_ref,
)
-update_request = gdl.SetRecordAttributesRequest(importRecords=[update_record])
-updated_records = import_service.SetRecordAttributes(update_request).recordsImported
-updated_record_ref = updated_records[0].recordReference
-updated_record_name = updated_records[0].longName
+update_request = gdl.SetRecordAttributesRequest(import_records=[update_record])
+updated_records = import_service.set_record_attributes(update_request).records_imported
+updated_record_ref = updated_records[0].record_reference
+updated_record_name = updated_records[0].long_name
print(f'Updated record "{updated_record_name}"')
```
*Previous cell output:*
@@ -53,43 +54,48 @@ Now let's retrieve the record creator, createdDate, lastModifier and modifiedDat
```python
pseudo_creator = gdl.AttributeReference(
- pseudoAttribute=gdl.AttributeReference.MIPseudoAttributeReference.creator,
- DBKey=db_key,
- partialTableReference=partial_table_ref,
+ pseudo_attribute=gdl.AttributeReference.MIPseudoAttributeReference.creator,
+ db_key=db_key,
+ partial_table_reference=partial_table_ref,
)
pseudo_created_date = gdl.AttributeReference(
- pseudoAttribute=gdl.AttributeReference.MIPseudoAttributeReference.createdDate,
- DBKey=db_key,
- partialTableReference=partial_table_ref,
+ pseudo_attribute=gdl.AttributeReference.MIPseudoAttributeReference.createdDate,
+ db_key=db_key,
+ partial_table_reference=partial_table_ref,
)
pseudo_last_modifier = gdl.AttributeReference(
- pseudoAttribute=gdl.AttributeReference.MIPseudoAttributeReference.lastModifier,
- DBKey=db_key,
- partialTableReference=partial_table_ref,
+ pseudo_attribute=gdl.AttributeReference.MIPseudoAttributeReference.lastModifier,
+ db_key=db_key,
+ partial_table_reference=partial_table_ref,
)
pseudo_modified_date = gdl.AttributeReference(
- pseudoAttribute=gdl.AttributeReference.MIPseudoAttributeReference.modifiedDate,
- DBKey=db_key,
- partialTableReference=partial_table_ref,
+ pseudo_attribute=gdl.AttributeReference.MIPseudoAttributeReference.modifiedDate,
+ db_key=db_key,
+ partial_table_reference=partial_table_ref,
)
-attribute_refs = [pseudo_creator, pseudo_created_date, pseudo_last_modifier, pseudo_modified_date]
+attribute_refs = [
+ pseudo_creator,
+ pseudo_created_date,
+ pseudo_last_modifier,
+ pseudo_modified_date,
+]
export_request = gdl.GetRecordAttributesByRefRequest(
- recordReferences=[modified_record_ref],
- attributeReferences=attribute_refs,
+ record_references=[modified_record_ref],
+ attribute_references=attribute_refs,
)
-exported_data = export_service.GetRecordAttributesByRef(export_request).recordData
+exported_data = export_service.get_record_attributes_by_ref(export_request).record_data
for record in exported_data:
- creator = [a.shortTextDataType.value for a in record.attributeValues if a.attributeName == "[creator]"][0]
- created_date = [a.dateTimeDataType.value for a in record.attributeValues if a.attributeName == "[createdDate]"][0]
- modifier = [a.shortTextDataType.value for a in record.attributeValues if a.attributeName == "[lastModifier]"][0]
- modified_date = [a.dateTimeDataType.value for a in record.attributeValues if a.attributeName == "[modifiedDate]"][0]
+ creator = [a.short_text_data_value.value for a in record.attribute_values if a.attribute_name == "[creator]"][0]
+ created_date = [a.date_time_data_value.value for a in record.attribute_values if a.attribute_name == "[createdDate]"][0]
+ modifier = [a.short_text_data_value.value for a in record.attribute_values if a.attribute_name == "[lastModifier]"][0]
+ modified_date = [a.date_time_data_value.value for a in record.attribute_values if a.attribute_name == "[modifiedDate]"][0]
print(f'"{creator}" imported the record on {created_date}')
print(f'The record was last modified on {modified_date} by "{modifier}"')
```
*Previous cell output:*
```output
"Ansys Granta 1" imported the record on 2023-09-20T12:11:05.873
-The record was last modified on 2025-05-12T16:21:14.687 by "ANSYS\mi-sw-admin"
+The record was last modified on 2026-01-07T19:32:11.27 by "ANSYS\mi-sw-admin"
```
\ No newline at end of file
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/08_Inspecting_record_link_groups.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/08_Inspecting_record_link_groups.md
index c7a1df5512..d774bcea21 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/08_Inspecting_record_link_groups.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/08_Inspecting_record_link_groups.md
@@ -1,4 +1,4 @@
-# Inspecting record link groups
+# Inspecting record link groups
Find which record link groups are in a specified database, and find which records are contained in a specified record
link group.
@@ -9,13 +9,13 @@ This example demonstrates:
- Retrieve a list of records within a specified record link group
## Create a Granta MI session
-Import the GRANTA_MIScriptingToolkit package, and create a connection to a Granta MI server.
+Import the ansys.grantami.backend.soap package, and create a connection to a Granta MI server.
```python
-import GRANTA_MIScriptingToolkit as gdl
+import ansys.grantami.backend.soap as gdl
-session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", autoLogon=True)
+session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", auto_logon=True)
print("Session created")
```
@@ -24,23 +24,23 @@ print("Session created")
Session created
```
## Retrieve record link groups from a given database
-You can use GetRecordLinkGroups to retrieve information about all the link groups in a given database.
+You can use get_record_link_groups to retrieve information about all the link groups in a given database.
Find the record link groups and the group IDs for groups in the MI_Training database.
```python
-dbKey = "MI_Training"
-tableName = "Metals Pedigree"
-
-req = gdl.GetRecordLinkGroups(DBKey=dbKey)
-grlg_resp = session.browseService.GetRecordLinkGroups(req)
-
-groups = {} # Will be populated as RLG name -> RLG object
-for i, r in enumerate(grlg_resp.recordLinkGroups):
- if i < 20: # Print first 20 group names
- print(f"{r.name}: id={r.reference.recordLinkGroupIdentity}")
- if r.fromTable.name == tableName:
- groups[r.name] = r
+db_key = "MI_Training"
+table_name = "Metals Pedigree"
+
+req = gdl.GetRecordLinkGroups(db_key=db_key)
+grlg_resp = session.browse_service.get_record_link_groups(req)
+
+groups = {} # Will be populated as RLG name -> RLG object
+for idx, rlg in enumerate(grlg_resp.record_link_groups):
+ if idx < 5: # Print first 5 group names
+ print(f"{rlg.name}: id={rlg.reference.record_link_group_identity}")
+ if rlg.from_table.name == table_name:
+ groups[rlg.name] = rlg
```
*Previous cell output:*
```output
@@ -49,39 +49,27 @@ Tensile Statistical Data: id=106
Design Data: id=105
Tensile Test Data: id=104
Metals Pedigree: id=102
-Specification Values: id=127
-Tensile Statistical Data: id=103
-Fatigue Test Data: id=125
-Fatigue Statistical Data: id=126
-Test Data: id=128
-AM builds using this batch: id=123
-Tensile Test Data: id=101
-Tensile test data: id=8
-Material batch: id=124
-Tensile tests from this build: id=10
-Machine learning: Build parameters: id=11
-MaterialUniverse: id=115
-Smart Link to MaterialUniverse: id=3
```
## List the records within a record link group
Search for records containing "ICS-46634". Subsequent steps will use only these search results.
```python
-def TextSearch(session, text, dbKey):
+def text_search(session: gdl.GRANTA_MISession, text: str, db_key: str):
"""
Simple wrapper around textsearch
"""
- search = session.searchService
- s = gdl.SimpleTextSearch()
- s.DBKey = dbKey
- s.searchValue = text
- s.populateGUIDs = True
- resp = search.SimpleTextSearch(s)
+ search = session.search_service
+ s = gdl.SimpleTextSearch(
+ db_key=db_key,
+ search_value=text,
+ populate_guids=True,
+ )
+ resp = search.simple_text_search(s)
return resp
-results = TextSearch(session, "ICS-46634", dbKey)
+results = text_search(session, "ICS-46634", db_key)
```
Collate the record references from the search results. Use GetLinkedRecords to specify the record link group "Tensile
@@ -89,29 +77,29 @@ Test Data".
```python
-recs = [r.recordReference for r in results.searchResults]
+records = [r.record_reference for r in results.search_results]
name = "Tensile Test Data"
-g = groups[name]
+rlg = groups[name]
req = gdl.GetLinkedRecordsRequest(
- recordLinkGroups=[g.reference],
- recordReferences=recs,
+ record_link_groups=[rlg.reference],
+ record_references=records,
)
-glr_resp = session.browseService.GetLinkedRecords(req)
+glr_resp = session.browse_service.get_linked_records(req)
```
Collate and list the number of results from the record link group.
```python
-links = [] # list of ordered pairs of refs
-for sr in glr_resp.sourceRecords:
- for rlg in sr.recordLinkGroups.recordLinkGroups:
- for tr in rlg.linkedRecords:
- links.append((sr.record, tr.recordReference))
-print(f"{len(links)} links found from {len(recs)} source records")
+links = [] # list of ordered pairs of refs
+for sr in glr_resp.source_records:
+ for rlg in sr.record_link_groups.record_link_groups:
+ for tr in rlg.linked_records:
+ links.append((sr.record, tr.record_reference))
+print(f"{len(links)} links found from {len(records)} source records")
```
*Previous cell output:*
```output
@@ -123,24 +111,24 @@ group.
```python
# Prepare to use GetTreeRecords to find record names corresponding to record references
-idsToFetch = set([pair[0].identity for pair in links]) # source records
-idsToFetch.update([pair[1].identity for pair in links]) # also add target records
+ids_to_fetch = set([pair[0].identity for pair in links]) # source records
+ids_to_fetch.update([pair[1].identity for pair in links]) # also add target records
# create ref objects for all source/target records
-recordRefs = [gdl.RecordReference(DBKey=dbKey, identity=recId) for recId in idsToFetch]
+record_references = [gdl.RecordReference(db_key=db_key, identity=recId) for recId in ids_to_fetch]
# use GetTreeRecords to find record names
-req = gdl.GetTreeRecordsRequest(records=recordRefs)
-resp = session.browseService.GetTreeRecords(req)
-nameLookup = {tr.recordReference.identity:tr.shortName for tr in resp.treeRecords}
+req = gdl.GetTreeRecordsRequest(records=record_references)
+resp = session.browse_service.get_tree_records(req)
+name_lookup = {tr.record_reference.identity: tr.short_name for tr in resp.tree_records}
# Get and print record names
-linkPairs = []
+link_pairs = []
for r in links:
- linkPairs.append((nameLookup[r[0].identity], nameLookup[r[1].identity]))
-
+ link_pairs.append((name_lookup[r[0].identity], name_lookup[r[1].identity]))
+
print(f"Records linked by '{name}':")
-for pair in linkPairs:
+for pair in link_pairs:
print(f"{pair[0]:<30}-> {pair[1]}")
```
*Previous cell output:*
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/09_Modifying_record_link_groups.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/09_Modifying_record_link_groups.md
index 7e564c4ddb..6d495465c3 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/09_Modifying_record_link_groups.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/09_Modifying_record_link_groups.md
@@ -9,15 +9,15 @@ This example demonstrates:
- Create a link between the new record and another record
## Create a Granta MI session
-Import the GRANTA_MIScriptingToolkit package, and create a connection to a Granta MI server.
+Import the ansys.grantami.backend.soap package, and create a connection to a Granta MI server.
```python
from datetime import datetime
-import GRANTA_MIScriptingToolkit as gdl
+import ansys.grantami.backend.soap as gdl
-session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", autoLogon=True)
+session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer", auto_logon=True)
```
## Create a link between a current record and a new record
@@ -25,18 +25,18 @@ Find the record link groups that can be created within MaterialUniverse.
```python
-dbkey = "MI_Training"
-tableName = "MaterialUniverse"
+db_key = "MI_Training"
+table_name = "MaterialUniverse"
-req = gdl.GetRecordLinkGroups(DBKey=dbkey)
+req = gdl.GetRecordLinkGroups(db_key=db_key)
-grlg_resp = session.browseService.GetRecordLinkGroups(req)
+grlg_resp = session.browse_service.get_record_link_groups(req)
groups = {}
-for r in grlg_resp.recordLinkGroups:
- if r.fromTable.name == tableName:
- print(f"{r.name}: id={r.reference.recordLinkGroupIdentity}")
- groups[r.name] = r
+for rlg in grlg_resp.record_link_groups:
+ if rlg.from_table.name == table_name:
+ print(f"{rlg.name}: id={rlg.reference.record_link_group_identity}")
+ groups[rlg.name] = rlg
```
*Previous cell output:*
```output
@@ -47,19 +47,19 @@ be the target record to create a link to later.
```python
-grn_req = gdl.GetRootNode(table=groups["Training Exercise"].toTable)
-grn_resp = session.browseService.GetRootNode(grn_req)
+grn_req = gdl.GetRootNode(table=groups["Training Exercise"].to_table)
+grn_resp = session.browse_service.get_root_node(grn_req)
now = datetime.now().strftime("%c")
-linkedRecordName = f"Scripting toolkit foundation layer example 09:{now}"
+linked_record_name = f"Scripting Toolkit Foundation Layer Example 9:{now}"
ir = gdl.ImportRecord(
- recordName=linkedRecordName,
- existingRecord=grn_resp.rootNode.recordReference,
+ record_name=linked_record_name,
+ existing_record=grn_resp.root_node.record_reference,
)
-req = gdl.SetRecordAttributesRequest(importRecords=[ir], importErrorMode=gdl.GRANTA_Constants.ImportErrorMode.Fault)
-resp = session.dataImportService.SetRecordAttributes(req)
-target = resp.recordsImported[0]
+req = gdl.SetRecordAttributesRequest(import_records=[ir], import_error_mode=gdl.GRANTA_Constants.ImportErrorMode.Fault)
+resp = session.data_import_service.set_record_attributes(req)
+target = resp.records_imported[0]
```
Set "PMMA (cast sheet)" in MaterialUniverse as the source record to create a link from.
@@ -67,16 +67,16 @@ Set "PMMA (cast sheet)" in MaterialUniverse as the source record to create a lin
```python
req = gdl.RecordNameSearchRequest(
- caseSensitiveNames=False,
- recordName="PMMA (cast sheet)",
- populateGUIDs=True,
- searchShortNames=True,
- searchFullNames=True,
+ case_sensitive_names=False,
+ record_name="PMMA (cast sheet)",
+ populate_guids=True,
+ search_short_names=True,
+ search_full_names=True,
+ table=gdl.TableReference(db_key=db_key, name=table_name)
)
-req.table = gdl.TableReference(DBKey=dbkey, name=tableName)
-resp = session.searchService.RecordNameSearch(req)
-sourceResult = resp.searchResults[0]
-source = sourceResult.recordReference
+resp = session.search_service.record_name_search(req)
+source_result = resp.search_results[0]
+source = source_result.record_reference
```
Use the ModifyRecordLinks operation to create a link called "Training Exercise" from "PMMA (cast sheet)" to the new
@@ -84,23 +84,23 @@ imported record.
```python
-destinationRec = gdl.NotatedTargetRecord(
- record=target.recordReference,
+destination_record = gdl.NotatedTargetRecord(
+ record=target.record_reference,
notes="This will work",
)
-mySourceRec = gdl.NotatedTargetedSourceRecord(
- sourceRecord=source,
- targetRecords=[destinationRec],
+source_record = gdl.NotatedTargetedSourceRecord(
+ source_record=source,
+ target_records=[destination_record],
)
-linkThisRecord = gdl.LinkRecords(sourceRecords=[mySourceRec])
-recordLinksMod = gdl.RecordLinkModifications(linkRecords=[linkThisRecord])
+link_records = gdl.LinkRecords(source_records=[source_record])
+record_link_modifications = gdl.RecordLinkModifications(link_records=[link_records])
req = gdl.ModifyRecordLinksRequest(
- recordLinkGroupReference=groups["Training Exercise"].reference,
- recordLinkModifications=recordLinksMod,
- importErrorMode=gdl.GRANTA_Constants.ImportErrorMode.Fault,
+ record_link_group_reference=groups["Training Exercise"].reference,
+ record_link_modifications=record_link_modifications,
+ import_error_mode=gdl.GRANTA_Constants.ImportErrorMode.Fault,
)
-mrlresp = session.dataImportService.ModifyRecordLinks(req)
+mrlresp = session.data_import_service.modify_record_links(req)
```
Print the record names and GUIDs for the newly-linked records. You can also check this new link in MI Viewer, by
@@ -108,17 +108,17 @@ viewing the link on the "PMMA (cast sheet)" datasheet.
```python
-print(f"Created {len(mrlresp.recordLinkChanges.linked)} link(s)")
+print(f"Created {len(mrlresp.record_link_changes.linked)} link(s)")
-change = mrlresp.recordLinkChanges.linked[0]
-source_guid = change.record.recordReference.recordGUID
-source_name = sourceResult.shortName
-target_guid = change.targetRecords[0].recordReference.recordGUID
-target_name = ir.recordName
+change = mrlresp.record_link_changes.linked[0]
+source_guid = change.record.record_reference.record_guid
+source_name = source_result.short_name
+target_guid = change.target_records[0].record_reference.record_guid
+target_name = ir.record_name
print(f"{source_guid} ({source_name}) -> {target_guid} ({target_name})")
```
*Previous cell output:*
```output
Created 1 link(s)
-000016f6-000e-4fff-8fff-dd92ffff0000 (Cast sheet) -> f630996a-c1f6-4840-8afe-a011f60c0d49 (Scripting toolkit foundation layer example 09:Mon May 12 16:21:51 2025)
+000016f6-000e-4fff-8fff-dd92ffff0000 (Cast sheet) -> 3481aff1-d5a8-4451-9e55-8557eed407fa (Scripting Toolkit Foundation Layer Example 9:Wed Jan 7 19:32:44 2026)
```
\ No newline at end of file
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/10_Resolve_references.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/10_Resolve_references.md
index 022b119dde..fcb3434a0e 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/10_Resolve_references.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/10_Resolve_references.md
@@ -4,20 +4,20 @@ Let's see if we can modify a record...
```python
-import GRANTA_MIScriptingToolkit as gdl
+import ansys.grantami.backend.soap as gdl
-session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer/", autoLogon=True, receiveTimeout=5000)
+session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer/", auto_logon=True, receive_timeout=5000)
db_key = "MI_Training"
table_name = "Tensile Test Data"
-browse_service = session.browseService
+browse_service = session.browse_service
-modfied_record_guid = "4269f1bc-df6b-4a6d-870c-ef931728f37b"
-modified_record_ref = gdl.RecordReference(DBKey=db_key, recordGUID=modfied_record_guid)
+modified_record_guid = "4269f1bc-df6b-4a6d-870c-ef931728f37b"
+modified_record_ref = gdl.RecordReference(db_key=db_key, record_guid=modified_record_guid)
resolve_refs_request = gdl.ResolveReferencesRequest(entities=[modified_record_ref])
-can_modify_int = browse_service.ResolveReferences(resolve_refs_request).entityResolutions[0].canWrite
+can_modify_int = browse_service.resolve_references(resolve_refs_request).entity_resolutions[0].can_write
if can_modify_int == 0:
print("Yes, we can edit this record.")
else:
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/11_Get_unit_conversions.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/11_Get_unit_conversions.md
index 99a6ce453f..271b33595e 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/11_Get_unit_conversions.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/foundation/11_Get_unit_conversions.md
@@ -2,61 +2,60 @@
Export the Young's Modulus in the Metric system for a record
+
```python
import pandas
-import GRANTA_MIScriptingToolkit as gdl
+import ansys.grantami.backend.soap as gdl
-session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer/", autoLogon=True, receiveTimeout=5000)
+session = gdl.GRANTA_MISession("http://my.server.name/mi_servicelayer/", auto_logon=True, receive_timeout=5000)
db_key = "MI_Training"
table_name = "Tensile Test Data"
-import_service = session.dataImportService
-browse_service = session.browseService
-export_service = session.dataExportService
+import_service = session.data_import_service
+browse_service = session.browse_service
+export_service = session.data_export_service
-partial_table_ref = gdl.PartialTableReference(tableName=table_name)
+partial_table_ref = gdl.PartialTableReference(table_name=table_name)
-modfied_record_guid = "4269f1bc-df6b-4a6d-870c-ef931728f37b"
-modified_record_ref = gdl.RecordReference(DBKey=db_key, recordGUID=modfied_record_guid)
+modified_record_guid = "4269f1bc-df6b-4a6d-870c-ef931728f37b"
+modified_record_ref = gdl.RecordReference(db_key=db_key, record_guid=modified_record_guid)
attribute_name = "Young's Modulus (11-axis)"
-unit_context_metric = gdl.UnitConversionContext(unitSystem="Metric")
+unit_context_metric = gdl.UnitConversionContext(unit_system=gdl.UnitSystemDetail(name="Metric"))
modulus_attribute_ref = gdl.AttributeReference(
name=attribute_name,
- DBKey=db_key,
- partialTableReference=partial_table_ref,
+ db_key=db_key,
+ partial_table_reference=partial_table_ref,
)
export_request = gdl.GetRecordAttributesByRefRequest(
- recordReferences=[modified_record_ref],
- attributeReferences=[modulus_attribute_ref],
+ record_references=[modified_record_ref],
+ attribute_references=[modulus_attribute_ref],
)
-exported_data = export_service.GetRecordAttributesByRef(export_request).recordData
-modulus_value = [[a.pointDataType.points[0].value for a in r.attributeValues] for r in exported_data][0][0]
-modulus_metric_symbol = [[a.pointDataType.unitSymbol for a in r.attributeValues] for r in exported_data][0][0]
+exported_data = export_service.get_record_attributes_by_ref(export_request).record_data
+modulus_value = [[a.point_data_value.points[0].value for a in r.attribute_values] for r in exported_data][0][0]
+modulus_metric_symbol = [[a.point_data_value.unit_symbol for a in r.attribute_values] for r in exported_data][0][0]
print(f"Young's modulus = {modulus_value} {modulus_metric_symbol}")
```
-
*Previous cell output:*
-
```output
Young's modulus = 174.0004272460938 GPa
```
-
Now let's convert its value with all available conversions in Granta MI
+
```python
unit_conversions_request = gdl.GetUnitConversionsRequest(
- DBKey=db_key,
- unitSymbols=[modulus_metric_symbol],
+ db_key=db_key,
+ unit_symbols=[modulus_metric_symbol],
)
-source_units = browse_service.GetUnitConversions(unit_conversions_request).sourceUnits
+source_units = browse_service.get_unit_conversions(unit_conversions_request).source_units
conversion_targets = [c.conversions for c in source_units]
factors_and_offsets = [[(c.factor, c.offset) for c in c_target] for c_target in conversion_targets][0]
-symbols = [[c.targetSymbol for c in c_target] for c_target in conversion_targets][0]
+symbols = [[c.target_symbol for c in c_target] for c_target in conversion_targets][0]
results = [modulus_value * factor + offset for factor, offset in factors_and_offsets]
equations = [f"{modulus_value} * {factor} + {offset}" for factor, offset in factors_and_offsets]
@@ -68,212 +67,218 @@ df_flipped.index = symbols
df_flipped.style
```
-
+
+
+
+
-
factor
-
offset
-
equation
-
converted result
+
factor
+
offset
+
equation
+
converted result
-
10^6 psi
-
0.145038
-
0.000000
-
174.0004272460938 * 0.14503773773039605 + 0.0
-
25.236628
+
10^6 psi
+
0.145038
+
0.000000
+
174.0004272460938 * 0.14503773773039605 + 0.0
+
25.236628
-
ksi
-
145.037738
-
0.000000
-
174.0004272460938 * 145.03773773039603 + 0.0
-
25236.628332
+
ksi
+
145.037738
+
0.000000
+
174.0004272460938 * 145.03773773039603 + 0.0
+
25236.628332
-
psi
-
145037.737730
-
0.000000
-
174.0004272460938 * 145037.73773039604 + 0.0
-
25236628.331896
+
psi
+
145037.737730
+
0.000000
+
174.0004272460938 * 145037.73773039604 + 0.0
+
25236628.331896
-
MGO
-
125663.706106
-
0.000000
-
174.0004272460938 * 125663.70610560982 + 0.0
-
21865538.551704
+
MGO
+
125663.706106
+
0.000000
+
174.0004272460938 * 125663.70610560982 + 0.0
+
21865538.551704
-
Pa
-
1000000000.000000
-
0.000000
-
174.0004272460938 * 1000000000.0 + 0.0
-
174000427246.093811
+
Pa
+
1000000000.000000
+
0.000000
+
174.0004272460938 * 1000000000.0 + 0.0
+
174000427246.093811
-
MPa
-
1000.000000
-
0.000000
-
174.0004272460938 * 1000.0 + 0.0
-
174000.427246
+
MPa
+
1000.000000
+
0.000000
+
174.0004272460938 * 1000.0 + 0.0
+
174000.427246
-
J/m^3
-
1000000000.000000
-
0.000000
-
174.0004272460938 * 1000000000.0 + 0.0
-
174000427246.093811
+
J/m^3
+
1000000000.000000
+
0.000000
+
174.0004272460938 * 1000000000.0 + 0.0
+
174000427246.093811
-
MJ/m^3
-
1000.000000
-
0.000000
-
174.0004272460938 * 1000.0 + 0.0
-
174000.427246
+
MJ/m^3
+
1000.000000
+
0.000000
+
174.0004272460938 * 1000.0 + 0.0
+
174000.427246
-
erg/cm^3
-
10000000000.000002
-
0.000000
-
174.0004272460938 * 10000000000.000002 + 0.0
-
1740004272460.938477
+
erg/cm^3
+
10000000000.000002
+
0.000000
+
174.0004272460938 * 10000000000.000002 + 0.0
+
1740004272460.938477
-
ft.lbf/in^3
-
12086.478144
-
0.000000
-
174.0004272460938 * 12086.478144199671 + 0.0
-
2103052.360991
+
ft.lbf/in^3
+
12086.478144
+
0.000000
+
174.0004272460938 * 12086.478144199671 + 0.0
+
2103052.360991
-
kJ/m^3
-
1000000.000000
-
0.000000
-
174.0004272460938 * 1000000.0 + 0.0
-
174000427.246094
+
kJ/m^3
+
1000000.000000
+
0.000000
+
174.0004272460938 * 1000000.0 + 0.0
+
174000427.246094
-
inHg
-
295299.714445
-
0.000000
-
174.0004272460938 * 295299.7144451761 + 0.0
-
51382276.479110
+
inHg
+
295299.714445
+
0.000000
+
174.0004272460938 * 295299.7144451761 + 0.0
+
51382276.479110
-
Ba
-
10000000000.000000
-
0.000000
-
174.0004272460938 * 10000000000.0 + 0.0
-
1740004272460.937988
+
Ba
+
10000000000.000000
+
0.000000
+
174.0004272460938 * 10000000000.0 + 0.0
+
1740004272460.937988
-
hPa
-
10000000.000000
-
0.000000
-
174.0004272460938 * 10000000.0 + 0.0
-
1740004272.460938
+
hPa
+
10000000.000000
+
0.000000
+
174.0004272460938 * 10000000.0 + 0.0
+
1740004272.460938
-
mb
-
10000000.000000
-
0.000000
-
174.0004272460938 * 10000000.0 + 0.0
-
1740004272.460938
+
mb
+
10000000.000000
+
0.000000
+
174.0004272460938 * 10000000.0 + 0.0
+
1740004272.460938
-
bar
-
10000.000000
-
0.000000
-
174.0004272460938 * 10000.0 + 0.0
-
1740004.272461
+
bar
+
10000.000000
+
0.000000
+
174.0004272460938 * 10000.0 + 0.0
+
1740004.272461
-
atm
-
9869.232667
-
0.000000
-
174.0004272460938 * 9869.232667160128 + 0.0
-
1717250.700677
+
atm
+
9869.232667
+
0.000000
+
174.0004272460938 * 9869.232667160128 + 0.0
+
1717250.700677
-
torr
-
7500637.554192
-
0.000000
-
174.0004272460938 * 7500637.554192106 + 0.0
-
1305114139.047523
+
torr
+
7500637.554192
+
0.000000
+
174.0004272460938 * 7500637.554192106 + 0.0
+
1305114139.047523
-
lbf/ft^2
-
20885434.233177
-
0.000000
-
174.0004272460938 * 20885434.233177025 + 0.0
-
3634074479.792996
+
lbf/ft^2
+
20885434.233177
+
0.000000
+
174.0004272460938 * 20885434.233177025 + 0.0
+
3634074479.792996
-
HV
-
101.971621
-
0.000000
-
174.0004272460938 * 101.97162129779282 + 0.0
-
17743.105673
+
HV
+
101.971621
+
0.000000
+
174.0004272460938 * 101.97162129779282 + 0.0
+
17743.105673
-
kgf/mm^2
-
101.971621
-
0.000000
-
174.0004272460938 * 101.97162129779282 + 0.0
-
17743.105673
+
kgf/mm^2
+
101.971621
+
0.000000
+
174.0004272460938 * 101.97162129779282 + 0.0
+
17743.105673
-
dyn/cm^2
-
10000000000.000000
-
0.000000
-
174.0004272460938 * 10000000000.0 + 0.0
-
1740004272460.937988
+
dyn/cm^2
+
10000000000.000000
+
0.000000
+
174.0004272460938 * 10000000000.0 + 0.0
+
1740004272460.937988
-
ft.lbf/ft^3
-
20885434.233177
-
0.000000
-
174.0004272460938 * 20885434.23317702 + 0.0
-
3634074479.792995
+
ft.lbf/ft^3
+
20885434.233177
+
0.000000
+
174.0004272460938 * 20885434.23317702 + 0.0
+
3634074479.792995
-
in.lbf/in^3
-
145037.737730
-
0.000000
-
174.0004272460938 * 145037.73773039604 + 0.0
-
25236628.331896
+
in.lbf/in^3
+
145037.737730
+
0.000000
+
174.0004272460938 * 145037.73773039604 + 0.0
+
25236628.331896
-
J/cm^3
-
1000.000000
-
0.000000
-
174.0004272460938 * 1000.0000000000001 + 0.0
-
174000.427246
+
J/cm^3
+
1000.000000
+
0.000000
+
174.0004272460938 * 1000.0000000000001 + 0.0
+
174000.427246
-
kN/cm^2
-
100.000000
-
0.000000
-
174.0004272460938 * 100.0 + 0.0
-
17400.042725
+
kN/cm^2
+
100.000000
+
0.000000
+
174.0004272460938 * 100.0 + 0.0
+
17400.042725
-
Msi
-
0.145038
-
0.000000
-
174.0004272460938 * 0.14503773773039605 + 0.0
-
25.236628
+
Msi
+
0.145038
+
0.000000
+
174.0004272460938 * 0.14503773773039605 + 0.0
+
25.236628
-
N/mm^2
-
1000.000000
-
0.000000
-
174.0004272460938 * 1000.0 + 0.0
-
174000.427246
+
N/mm^2
+
1000.000000
+
0.000000
+
174.0004272460938 * 1000.0 + 0.0
+
174000.427246
+
+
+
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/00_Get_Started.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/00_Get_Started.md
index b1b2ad9f15..474963b466 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/00_Get_Started.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/00_Get_Started.md
@@ -1,4 +1,4 @@
-# Get Started
+# Get Started
Load MI Scripting Toolkit, connect to your MI Session, and select a database and table.
## Connect to MI
@@ -7,9 +7,9 @@ replacing `my.server.name` with the name of your Granta MI server.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
```
## Select a database
@@ -24,12 +24,12 @@ Set a unit system, and choose whether to use absolute or relative temperatures (
```python
-my_db.unit_system = 'UK Imperial'
+my_db.unit_system = "UK Imperial"
my_db.absolute_temperatures = False
```
## Select a table
-Select *MaterialUniverse* and print its number of attributes.
+Select *MaterialUniverse* and print its number of attributes.
```python
@@ -128,7 +128,7 @@ with data like this:
*Previous cell output:*
```output
-
+
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/01_Get_Attributes.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/01_Get_Attributes.md
index 16690edd96..0bb093228d 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/01_Get_Attributes.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/01_Get_Attributes.md
@@ -5,12 +5,12 @@ Find out about the database schema by accessing the `attributes` property of the
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
```
-## Get table
+## Get table
Get a database, then set the unit system for the **Database** object.
@@ -32,8 +32,8 @@ Get a table from the database.
```python
-tab = db.get_table("Training Exercise for Import")
-tab
+table = db.get_table("Training Exercise for Import")
+table
```
@@ -44,16 +44,16 @@ tab
```
-## Access the attribute definitions
+## Access the attribute definitions
These are associated with the **Table** object through the `attributes` property,
which returns a dictionary of **AttributeDefinition** objects.
```python
print(f"{'Name':30.30} - {'Type':^10.10} - {'Unit':^10.10} - {'Meta?':^10.10}")
-print("-"*70)
-for name, att in tab.attributes.items():
- print(f"{name:30.30} - {att.type:^10.10} - {att.unit:^10.10} - {str(att.is_meta):^10.10}")
+print("-" * 70)
+for name, att in table.attributes.items():
+ print(f"{name:30.30} - {att.type:^10.10} - {getattr(att, 'unit', ''):^10.10} - {str(att.is_meta):^10.10}")
```
*Previous cell output:*
```output
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/02_Browse_MI.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/02_Browse_MI.md
index 217787c4f5..a7fc6ed285 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/02_Browse_MI.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/02_Browse_MI.md
@@ -11,8 +11,9 @@ This notebook shows three methods of browsing for records in Granta MI:
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+import ansys.grantami.core as mpy
+
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
```
@@ -128,12 +129,12 @@ parent with the short name *Baryta*.
```python
-recs = material_universe.get_records_from_path(
+baryta_children = material_universe.get_records_from_path(
starting_node=None,
tree_path=["Ceramics and glasses", None, "Baryta"],
use_short_names=True,
)
-recs
+baryta_children
```
@@ -148,11 +149,11 @@ Get all records that are great-grandchildren of the folder *Ceramics and glasses
```python
-recs = material_universe.get_records_from_path(
+ceramics_great_grandchildren = material_universe.get_records_from_path(
starting_node=ceramics_and_glasses,
tree_path=[None, None],
)
-recs
+ceramics_great_grandchildren
```
@@ -196,7 +197,7 @@ Print the results and whether the object is a record or folder.
```python
print(f"{'Record Name':^30.30} | {'Short Name':^30.30} | {'Record / Folder?':^30.30}")
-print("-"*96)
+print("-" * 96)
for r in all_ceramics_and_glasses:
print(f"{r.name:^30.30} | {r.short_name:^30.30} | {r.type:^30.30}")
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/03_Search_MI.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/03_Search_MI.md
index 38c61fbe5b..9023ebd216 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/03_Search_MI.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/03_Search_MI.md
@@ -11,8 +11,9 @@ All three methods can be performed at either the Session, Database, or Table lev
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+import ansys.grantami.core as mpy
+
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
db.unit_system = "UK Imperial"
material_universe = db.get_table("MaterialUniverse")
@@ -216,8 +217,8 @@ legislations = db.get_table("Legislations and Lists")
effective_date_attribute = legislations.attributes["Effective date"]
import datetime
-start_date = datetime.datetime(1970, 1, 1)
-end_date = datetime.datetime(2000, 1, 1)
+start_date = datetime.date(1970, 1, 1)
+end_date = datetime.date(2000, 1, 1)
effective_date_1970_2000 = effective_date_attribute.search_criterion(between_dates=(start_date, end_date))
legislations_1970_2000 = legislations.search_for_records_where([effective_date_1970_2000])
legislations_1970_2000
@@ -342,7 +343,7 @@ Print the results of the tabular search.
```python
print(f"{'Record Name':^55.55} | {'Short Name':^55.55}")
-print("-"*113)
+print("-" * 113)
for r in affected_materials:
print(f"{r.name:^55.55} | {r.short_name:^55.55}")
```
@@ -366,20 +367,18 @@ tensile_test_table = db.get_table("Tensile Test Data")
name_criterion = mpy.SearchCriterion(mpy.RecordProperties.name, "CONTAINS", "MTS")
-start_datetime = datetime.datetime(year=2023, month=9, day=1)
-end_datetime = datetime.datetime(year=2023, month=9, day=30)
-created_criterion = mpy.SearchCriterion(
- mpy.RecordProperties.created_on, "BETWEEN", (start_datetime, end_datetime)
-)
+start_datetime = datetime.datetime(year=2023, month=9, day=1, hour=0, minute=0, second=0)
+end_datetime = datetime.datetime(year=2023, month=10, day=1, hour=0, minute=0, second=0)
+created_criterion = mpy.SearchCriterion(mpy.RecordProperties.created_on, "BETWEEN", (start_datetime, end_datetime))
created_records = tensile_test_table.search_for_records_where([name_criterion, created_criterion])
print(f"{len(created_records)} records found. Displaying first 5...")
print()
print(f"{'Record Name':^55.55} | {'Created Date':^55.55}")
-print("-"*113)
+print("-" * 113)
for r in created_records[:5]:
- created_on = r.created_on.strftime('%Y/%m/%d %H:%M:%S')
+ created_on = r.created_on.strftime("%Y/%m/%d %H:%M:%S")
print(f"{r.name:^55.55} | {created_on:^55.55}")
```
*Previous cell output:*
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/04_Fetch_Attribute_Data_in_Bulk.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/04_Fetch_Attribute_Data_in_Bulk.md
index 56c7ba8a54..99df62fe6f 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/04_Fetch_Attribute_Data_in_Bulk.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/04_Fetch_Attribute_Data_in_Bulk.md
@@ -5,20 +5,20 @@ and as export requests are performed for each individual record.
By grouping records into fewer requests through batching, and allowing the export of only a subset of attributes,
`bulk_fetch()` can be used to enhance performance.
-## Connect to MI
+## Connect to MI
Specify a database and table.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
db.unit_system = "Metric"
db.absolute_temperatures = True
-tab = db.get_table("MaterialUniverse")
+table = db.get_table("MaterialUniverse")
```
## Define a list of records to fetch
@@ -40,7 +40,7 @@ Get each record using its Record GUID, using the `get_records_by_ids` method.
```python
-records = tab.get_records_by_ids([{"vguid": guid} for guid in guids])
+records = table.get_records_by_ids([{"vguid": guid} for guid in guids])
records
```
@@ -57,31 +57,31 @@ records
```
-## Fetch attribute data values
+## Fetch attribute data values
Fetch the *Base*, *Density* and *Young's modulus* attribute values for each record, and print the results.
Default units can be overridden before export using the `table.set_display_unit()` method.
```python
-tab.set_display_unit("Young's modulus", "ksi")
-tab.bulk_fetch(records=records, attributes=["Base", "Density", "Young's modulus"])
+table.set_display_unit("Young's modulus", "ksi")
+table.bulk_fetch(records=records, attributes=["Base", "Density", "Young's modulus"])
-density_unit = tab.attributes["Density"].unit
+density_unit = table.attributes["Density"].unit
density_header = f"Density / {density_unit}"
-youngs_mod_unit = tab.attributes["Young's modulus"].unit
+youngs_mod_unit = table.attributes["Young's modulus"].unit
youngs_mod_header = f"Young's modulus / {youngs_mod_unit}"
print(f"{'Name':50.50} | {density_header:^21} | {youngs_mod_header:^21} | {'Base':^18}")
-print("-"*120)
+print("-" * 120)
for record in records:
formatted_name = f"{record.name:50.50}"
density = record.attributes["Density"].value
- formatted_density = f"{density['low']:^10.2f}-{density['high']:^10.2f}"
+ formatted_density = f"{density.low:^10.2f}-{density.high:^10.2f}"
youngs_mod = record.attributes["Young's modulus"].value
- formatted_youngs_mod = f"{youngs_mod['low']:^10.2f}-{youngs_mod['high']:^10.2f}"
+ formatted_youngs_mod = f"{youngs_mod.low:^10.2f}-{youngs_mod.high:^10.2f}"
base = record.attributes["Base"].value
formatted_base = f"{base:^20}"
@@ -110,13 +110,13 @@ Fetch the attribute *Food contact* and associated meta-attribute *Notes* for eac
```python
import textwrap
-food_contact = tab.attributes["Food contact"]
+food_contact = table.attributes["Food contact"]
food_contact_notes = food_contact.meta_attributes["Notes"]
-tab.bulk_fetch(records=records, attributes=[food_contact, food_contact_notes])
+table.bulk_fetch(records=records, attributes=[food_contact, food_contact_notes])
print(f"{'Name':50.50} | {'Food contact':^18} | {'Notes':^42}")
-print("-"*120)
+print("-" * 120)
for record in records:
formatted_name = f"{record.name:50.50}"
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/06_Create_Records.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/05_Create_Records.md
similarity index 64%
rename from 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/06_Create_Records.md
rename to 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/05_Create_Records.md
index 333d96adb2..b4cbf462d9 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/06_Create_Records.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/05_Create_Records.md
@@ -6,9 +6,9 @@ Create records and delete (or withdraw) them in bulk.
```python
from datetime import datetime
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
table = mi.get_db(db_key="MI_Training").get_table("Files for Training")
```
@@ -26,8 +26,8 @@ Create five new **Record** objects.
```python
now = datetime.now().strftime("%c")
-recordNames = [f"Scripting Toolkit Example 6:{now} - {i}" for i in range(5)]
-new_records = [table.create_record(n, parent=parent, subsets={"All files"}) for n in recordNames]
+record_names = [f"Scripting Toolkit Example 5:{now} - {i}" for i in range(5)]
+new_records = [table.create_record(n, parent=parent, subsets={"All files"}) for n in record_names]
new_records
```
@@ -35,15 +35,15 @@ new_records
*Previous cell output:*
```output
-[,
- ,
- ,
- ,
- ]
+[,
+ ,
+ ,
+ ,
+ ]
```
-## Write your changes to MI
+## Write your changes to MI
The new records are created on the server when update() is called.
@@ -57,11 +57,11 @@ for rec in recs:
*Previous cell output:*
```output
New records:
-http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=975bc163-8df2-4cd6-9421-9cf7ef83e8c9
-http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=e1abe509-f1b5-4a6a-9e3a-f6d2e9e7e5c8
-http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=65394190-e659-4950-99fd-df33af02e430
-http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=22bd9edf-6a76-417a-81a8-aee6dfdcaf6a
-http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=f9bbed4d-f9ce-4df8-be58-27eed426118a
+http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=8717b0ba-8696-4fda-991c-03bdc0f76781
+http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=33fbdbda-78ed-4862-98ec-2e7014f3fdcc
+http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=75557043-71d1-4cb3-9fd5-e575e952753a
+http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=107a6da1-5702-4161-bd25-c94a70b0e10c
+http://my.server.name/mi/datasheet.aspx?dbKey=MI_Training&recordHistoryGuid=1e07c4c4-ccb3-4e5d-9a58-f870acb30518
```
## Delete the records
``Session.bulk_delete_or_withdraw_records`` accepts any list of records (e.g. results of a search,
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/05_Edit_Data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/06_Edit_Text_Data.md
similarity index 77%
rename from 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/05_Edit_Data.md
rename to 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/06_Edit_Text_Data.md
index 5753265cd0..e72fae13b3 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/05_Edit_Data.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/06_Edit_Text_Data.md
@@ -1,14 +1,15 @@
-# Edit Data
-Create and edit a **Record** object and write your changes to the MI server.
+# Text Data
+Work with text data, including short text, long text, and discrete data.
-This notebook describes how to edit text-based attributes. See the following notebooks for additional attribute types:
+This notebook describes how to edit text-based data. See the following notebooks for additional data types:
-- [Point and range attributes](./12_Add_Point_Range_Data.ipynb)
-- [Date, integer, and logical attributes](./13_Add_Date_Integer_and_Logical_Data.ipynb)
-- [Functional attributes](./07_Import_Functional_Data.ipynb)
-- [Tabular attributes](./09_Edit_Tabular_Data.ipynb)
-- [File, picture, and hyperlink attributes](./11_Add_Files_Pictures_and_Hyperlinks.ipynb)
-- [Pseudo-attributes](./10_Edit_Pseudo-attributes.ipynb)
+- [Point and range data](./07_Edit_Point_Range_Data.ipynb)
+- [Date, integer, and logical data](./08_Edit_Date_Integer_and_Logical_Data.ipynb)
+- [File, picture, and hyperlink data](./09_Edit_Files_Pictures_and_Hyperlinks.ipynb)
+- [Float functional data](./10_Edit_Float_Functional_Data.ipynb)
+- [Local tabular data](./11_Edit_Local_Tabular_Data.ipynb)
+- [Linked tabular data](./12_Edit_Linked_Tabular_Data.ipynb)
+- [Pseudo-attributes](./13_Edit_Pseudo-attributes.ipynb)
## Connect to MI
Get a database and table.
@@ -16,15 +17,15 @@ Get a database and table.
```python
from datetime import datetime
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
db.unit_system = "SI (Consistent)"
db.absolute_temperatures = True
-tab = db.get_table("Design Data")
+table = db.get_table("Design Data")
```
## Create a new record and path
@@ -34,9 +35,9 @@ Create a new **Record** object at the end of the path.
```python
now = datetime.now().strftime("%c")
-record_name = f"Scripting Toolkit Example 5:{now}"
-folder = tab.path_from(None, tree_path=["High Alloy Steel", "AMS 6520"])
-record = tab.create_record(name=record_name, parent=folder)
+record_name = f"Scripting Toolkit Example 6:{now}"
+folder = table.path_from(None, tree_path=["High Alloy Steel", "AMS 6520"])
+record = table.create_record(name=record_name, parent=folder)
record, folder
```
@@ -44,7 +45,7 @@ record, folder
*Previous cell output:*
```output
-(,
+(,
)
```
@@ -64,7 +65,7 @@ Edit their data values.
```python
-common_name.value = "Scripting Toolkit Example 5 Test Material"
+common_name.value = "Scripting Toolkit Example 6 Test Material"
product_form.value = "Plate"
```
@@ -79,13 +80,13 @@ statistical_basis.value = "S basis"
```output
Statistical Basis supports multivalued data? False
```
-*Available mechanical properties* is a multivalued discrete attribute. It can be set either with a string or a list of
-strings for each value.
+*Available mechanical properties* is a multivalued discrete attribute. It can be set either with a string or a tuple
+of strings for each value.
```python
print(f"{available_properties.name} supports multivalued data? {available_properties.is_multivalued}")
-available_properties.value = ["Tensile", "Compression"]
+available_properties.value = ("Tensile", "Compression")
```
*Previous cell output:*
```output
@@ -119,7 +120,7 @@ print(f"Record Name: {record.name}, State: {record.release_state}")
```
*Previous cell output:*
```output
-Record Name: Scripting Toolkit Example 5:Mon May 12 16:11:34 2025, State: Unreleased
+Record Name: Scripting Toolkit Example 6:Wed Jan 7 19:24:46 2026, State: Unreleased
```
## 'Not Applicable' flag
Further edits can be made to the same **Record** object. In this case, the *Condition* attribute is not relevant,
@@ -143,7 +144,7 @@ print(f'Record Name: "{record.name}", State: "{record.release_state}"')
```
*Previous cell output:*
```output
-Record Name: "Scripting Toolkit Example 5:Mon May 12 16:11:34 2025", State: "Released"
+Record Name: "Scripting Toolkit Example 6:Wed Jan 7 19:24:46 2026", State: "Released"
```
Check the `Record.all_versions` property for a dictionary of all versions of the record. The dictionary
contains a single version, confirming that only a single version was created in Granta MI.
@@ -157,7 +158,7 @@ record.all_versions
*Previous cell output:*
```output
-{'v1': }
+{'v1': }
```
@@ -200,7 +201,7 @@ print(f'"Record Name: {record.name}", State: "{record.release_state}"')
```
*Previous cell output:*
```output
-"Record Name: Scripting Toolkit Example 5:Mon May 12 16:11:34 2025", State: "Released"
+"Record Name: Scripting Toolkit Example 6:Wed Jan 7 19:24:46 2026", State: "Released"
```
Check the `Record.all_versions` property again. The dictionary contains two versions, confirming that updating the
Mooney-Rivlin attribute has created and released a second version of the record.
@@ -214,8 +215,8 @@ record.all_versions
*Previous cell output:*
```output
-{'v1': ,
- 'v2': }
+{'v1': ,
+ 'v2': }
```
@@ -251,7 +252,7 @@ print(f"Mooney-Rivlin: {result}, comments: {mooney_rivlin_comment.value}")
```
*Previous cell output:*
```output
-Common Name: Scripting Toolkit Example 5 Test Material
+Common Name: Scripting Toolkit Example 6 Test Material
Product Form: Plate
Statistical Basis: S basis
Available mechanical properties: Tensile, Compression
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/12_Add_Point_Range_Data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/07_Edit_Point_Range_Data.md
similarity index 65%
rename from 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/12_Add_Point_Range_Data.md
rename to 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/07_Edit_Point_Range_Data.md
index 8e3d03c616..15fc5ba68e 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/12_Add_Point_Range_Data.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/07_Edit_Point_Range_Data.md
@@ -1,5 +1,5 @@
-# Add Point and Range data
-Work with point and range attribute types, including multi-valued points and open-ended ranges.
+# Point and Range data
+Work with point and range data, including multi-valued points and open-ended ranges.
## Connect to MI
Get a database and table.
@@ -7,15 +7,15 @@ Get a database and table.
```python
from datetime import datetime
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
db.unit_system = "Metric"
db.absolute_temperatures = False
-tab = db.get_table("Composite Design Data")
+table = db.get_table("Composite Design Data")
```
## Create a new record and path
@@ -26,9 +26,9 @@ Create a new **Record** object at the end of the path.
```python
now = datetime.now().strftime("%c")
-record_name = f"Scripting Toolkit Example 12:{now}"
-folder = tab.path_from(None, tree_path=["Epoxy / Glass", "3M, S-Glass Unitape S2/SP381", "[0]"])
-record = tab.create_record(name=record_name, parent=folder)
+record_name = f"Scripting Toolkit Example 7:{now}"
+folder = table.path_from(None, tree_path=["Epoxy / Glass", "3M, S-Glass Unitape S2/SP381", "[0]"])
+record = table.create_record(name=record_name, parent=folder)
record, folder
```
@@ -36,7 +36,7 @@ record, folder
*Previous cell output:*
```output
-(,
+(,
)
```
@@ -53,33 +53,42 @@ fiber_volume = record.attributes["Fiber volume"]
```
### Point attributes
-Assign a list of numeric values to the `points` property.
+Schema Administrators can set whether point attributes accept multiple values or a single value. In Scripting
+Toolkit, these attribute values are represented via ``AttributePointMulti`` or ``AttributePointSingle``.
-If multiple values are assigned, you must also assign a list of dictionaries containing the parameter values to the
-`parameters` property. (The two lists must be the same length.)
-Here, a single parameter called *Basis* is used to discriminate between the two point values.
+Single-valued attributes must be set to a single float or integer value.
```python
test_temperature.value = 23
test_temperature.unit = "°C"
+```
+
+To define a value with parameters, set the ``.value`` property to a tuple of ``ParameterizedPointValue``.
-modulus.value = [8, 7.5]
+
+```python
modulus.unit = "GPa"
-modulus.parameters = [{"Basis": "Mean"}, {"Basis": "A-basis"}]
+modulus.value = (
+ mpy.ParameterizedPointValue(
+ value=8.0,
+ parameters=(mpy.PointParameterValue("Basis", "Mean"),)
+ ),
+ mpy.ParameterizedPointValue(
+ value=7.5,
+ parameters=(mpy.PointParameterValue("Basis", "A-basis"),)
+ )
+)
```
### Range attributes
-Access the `value` property directly and assign either a dictionary or tuple for high and low values.
+Access the `value` property directly and assign a ``Range`` instance.
Omitting either the 'low' or 'high' value creates an open-ended range.
```python
-resin_content.value = {"low": 28, "high": 30}
-resin_content.unit = 'wt%'
-
-fiber_volume.value = (None, 62.0)
-fiber_volume.unit = "%"
+resin_content.value = mpy.Range(low=28.0, high=30.0)
+resin_content.unit = "wt%"
```
The high and low values can separately be flagged as either inclusive (≤ and ≥) or exclusive
@@ -87,7 +96,12 @@ The high and low values can separately be flagged as either inclusive (≤ and
```python
-fiber_volume.high_value_is_inclusive = False
+fiber_volume.value = mpy.Range(
+ low=None,
+ high=62.0,
+ high_value_is_inclusive=False,
+)
+fiber_volume.unit = "%"
print(fiber_volume.high_value_is_inclusive)
```
*Previous cell output:*
@@ -115,8 +129,8 @@ print(f"Test temperature: {test_temperature.value} {test_temperature.unit}")
modulus = record.attributes["0° tension modulus - measured"]
print("0° tension modulus: ", end="")
formatted_points = [
- f"{point} {modulus.unit} ({modulus.parameters[idx]['Basis']})"
- for idx, point in enumerate(modulus.value)
+ f"{point.value} {modulus.unit} ({point.parameters_by_name['Basis']})"
+ for point in modulus.value
]
print(", ".join(formatted_points))
```
@@ -131,14 +145,14 @@ symbols.
```python
def format_range(range_value):
- low_value = range_value.value["low"]
+ low_value = range_value.value.low
if low_value is not None:
low_inequality = "≤" if range_value.low_value_is_inclusive else "<"
else:
low_inequality = ""
low_range = f"{low_value} {low_inequality}" if low_value else ""
- high_value = range_value.value["high"]
+ high_value = range_value.value.high
if high_value is not None:
high_inequality = "≤" if range_value.high_value_is_inclusive else "<"
else:
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/07_Import_Functional_Data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/07_Import_Functional_Data.md
deleted file mode 100644
index 549a581291..0000000000
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/07_Import_Functional_Data.md
+++ /dev/null
@@ -1,258 +0,0 @@
-# Import Functional Data
-Import CSV data into a functional attribute and update the parameters and header units.
-
-## Import required libraries
-Connect to MI and specify a table.
-
-
-```python
-import csv
-from datetime import datetime
-
-from GRANTA_MIScriptingToolkit import granta as mpy
-
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
-db = mi.get_db(db_key="MI_Training")
-
-tab = db.get_table("Design Data")
-```
-
-## Create a new record to store your data
-Define names for a new record, and an attribute on that record.
-
-
-```python
-now = datetime.now().strftime("%c")
-recordName = f"Scripting Toolkit Example 7:{now}"
-funcAttributeName = "Tensile Stress/Strain, L"
-```
-
-Create the new **Record** object.
-
-
-```python
-rec = tab.create_record(recordName, subsets={"Design Data"})
-rec
-```
-
-
-
-*Previous cell output:*
-```output
-
-```
-
-
-Get the unpopulated functional attribute for the new record, so we can populate it.
-
-
-```python
-func = rec.attributes[funcAttributeName]
-func
-```
-
-
-
-*Previous cell output:*
-```output
-
-```
-
-
-## Import test data
-The tensile test data to import is stored in `example.csv`.
-Read in each row of the CSV data, and add the data to the functional attribute point-by-point.
-
-
-```python
-with open("supporting_files/07_example_data_for_import.csv") as csvfile:
- reader = csv.DictReader(csvfile, delimiter=",")
- for row in reader:
- point = {
- "y": float(row["Tensile Stress [ksi]"]),
- "Strain": float(row["Strain [%]"]),
- "Temperature": float(row["Temperature [Celsius]"]),
- "Stress/Strain Curve Type": str(row["Curve Type"]),
- "Estimated?": bool(row["Estimated?"])
- }
- func.add_point(point)
-```
-
-Access the `func.value` property to see the underlying data structure of the attribute represented as a list of lists.
-`func.data` shows all parameters supported by the attribute. Parameters that were not populated during the import have
-been set to **None**.
-
-
-```python
-func.value
-```
-
-
-
-*Previous cell output:*
-```output
-[['Y min (Tensile Stress/Strain, L [ksi])',
- 'Y max (Tensile Stress/Strain, L [ksi])',
- 'Strain [% strain]',
- 'Temperature [°C]',
- 'Time [hr]',
- 'Other []',
- 'Stress/Strain Curve Type []',
- 'Estimated point?'],
- [0.0, 0.0, 0.0, -73.0, None, None, 'Yield', True],
- [396.0, 396.0, 0.209, -73.0, None, None, 'Yield', True],
- [714.0, 714.0, 0.376, -73.0, None, None, 'Yield', True],
- [1031.0, 1031.0, 0.544, -73.0, None, None, 'Yield', True],
- [1269.0, 1269.0, 0.669, -73.0, None, None, 'Yield', True],
- [1427.0, 1427.0, 0.753, -73.0, None, None, 'Yield', True],
- [1507.0, 1507.0, 0.795, -73.0, None, None, 'Yield', True],
- [1570.0, 1570.0, 0.83, -73.0, None, None, 'Yield', True],
- [1633.0, 1633.0, 0.867, -73.0, None, None, 'Yield', True],
- [1681.0, 1681.0, 0.897, -73.0, None, None, 'Yield', True],
- [1721.0, 1721.0, 0.925, -73.0, None, None, 'Yield', True],
- [1752.0, 1752.0, 0.952, -73.0, None, None, 'Yield', True],
- [1784.0, 1784.0, 0.983, -73.0, None, None, 'Yield', True],
- [1808.0, 1808.0, 1.012, -73.0, None, None, 'Yield', True],
- [1824.0, 1824.0, 1.034, -73.0, None, None, 'Yield', True],
- [1840.0, 1840.0, 1.059, -73.0, None, None, 'Yield', True],
- [1855.0, 1855.0, 1.087, -73.0, None, None, 'Yield', True],
- [1871.0, 1871.0, 1.121, -73.0, None, None, 'Yield', True],
- [1887.0, 1887.0, 1.159, -73.0, None, None, 'Yield', True],
- [1903.0, 1903.0, 1.204, -73.0, None, None, 'Yield', True],
- [1919.0, 1919.0, 1.256, -73.0, None, None, 'Yield', True],
- [1935.0, 1935.0, 1.318, -73.0, None, None, 'Yield', True],
- [1951.0, 1951.0, 1.39, -73.0, None, None, 'Yield', True],
- [1958.0, 1958.0, 1.432, -73.0, None, None, 'Yield', True],
- [1966.0, 1966.0, 1.476, -73.0, None, None, 'Yield', True],
- [0.0, 0.0, 0.0, 27.0, None, None, 'Yield', True],
- [371.0, 371.0, 0.203, 27.0, None, None, 'Yield', True],
- [667.0, 667.0, 0.365, 27.0, None, None, 'Yield', True],
- [964.0, 964.0, 0.527, 27.0, None, None, 'Yield', True],
- [1186.0, 1186.0, 0.649, 27.0, None, None, 'Yield', True],
- [1334.0, 1334.0, 0.73, 27.0, None, None, 'Yield', True],
- [1408.0, 1408.0, 0.771, 27.0, None, None, 'Yield', True],
- [1468.0, 1468.0, 0.805, 27.0, None, None, 'Yield', True],
- [1527.0, 1527.0, 0.839, 27.0, None, None, 'Yield', True],
- [1571.0, 1571.0, 0.868, 27.0, None, None, 'Yield', True],
- [1608.0, 1608.0, 0.895, 27.0, None, None, 'Yield', True],
- [1638.0, 1638.0, 0.92, 27.0, None, None, 'Yield', True],
- [1668.0, 1668.0, 0.95, 27.0, None, None, 'Yield', True],
- [1690.0, 1690.0, 0.978, 27.0, None, None, 'Yield', True],
- [1705.0, 1705.0, 0.999, 27.0, None, None, 'Yield', True],
- [1720.0, 1720.0, 1.024, 27.0, None, None, 'Yield', True],
- [1734.0, 1734.0, 1.053, 27.0, None, None, 'Yield', True],
- [1749.0, 1749.0, 1.087, 27.0, None, None, 'Yield', True],
- [1764.0, 1764.0, 1.126, 27.0, None, None, 'Yield', True],
- [1779.0, 1779.0, 1.174, 27.0, None, None, 'Yield', True],
- [1794.0, 1794.0, 1.23, 27.0, None, None, 'Yield', True],
- [1808.0, 1808.0, 1.297, 27.0, None, None, 'Yield', True],
- [1823.0, 1823.0, 1.378, 27.0, None, None, 'Yield', True],
- [1831.0, 1831.0, 1.424, 27.0, None, None, 'Yield', True],
- [1838.0, 1838.0, 1.475, 27.0, None, None, 'Yield', True],
- [0.0, 0.0, 0.0, 149.0, None, None, 'Yield', True],
- [328.0, 328.0, 0.187, 149.0, None, None, 'Yield', True],
- [590.0, 590.0, 0.337, 149.0, None, None, 'Yield', True],
- [852.0, 852.0, 0.486, 149.0, None, None, 'Yield', True],
- [1048.0, 1048.0, 0.598, 149.0, None, None, 'Yield', True],
- [1179.0, 1179.0, 0.673, 149.0, None, None, 'Yield', True],
- [1245.0, 1245.0, 0.711, 149.0, None, None, 'Yield', True],
- [1297.0, 1297.0, 0.741, 149.0, None, None, 'Yield', True],
- [1349.0, 1349.0, 0.773, 149.0, None, None, 'Yield', True],
- [1389.0, 1389.0, 0.798, 149.0, None, None, 'Yield', True],
- [1421.0, 1421.0, 0.822, 149.0, None, None, 'Yield', True],
- [1448.0, 1448.0, 0.845, 149.0, None, None, 'Yield', True],
- [1474.0, 1474.0, 0.872, 149.0, None, None, 'Yield', True],
- [1493.0, 1493.0, 0.898, 149.0, None, None, 'Yield', True],
- [1507.0, 1507.0, 0.918, 149.0, None, None, 'Yield', True],
- [1520.0, 1520.0, 0.943, 149.0, None, None, 'Yield', True],
- [1533.0, 1533.0, 0.971, 149.0, None, None, 'Yield', True],
- [1546.0, 1546.0, 1.006, 149.0, None, None, 'Yield', True],
- [1559.0, 1559.0, 1.047, 149.0, None, None, 'Yield', True],
- [1572.0, 1572.0, 1.098, 149.0, None, None, 'Yield', True],
- [1585.0, 1585.0, 1.16, 149.0, None, None, 'Yield', True],
- [1598.0, 1598.0, 1.236, 149.0, None, None, 'Yield', True],
- [1611.0, 1611.0, 1.329, 149.0, None, None, 'Yield', True],
- [1618.0, 1618.0, 1.384, 149.0, None, None, 'Yield', True],
- [0.0, 0.0, 0.0, 316.0, None, None, 'Yield', True],
- [307.0, 307.0, 0.182, 316.0, None, None, 'Yield', True],
- [553.0, 553.0, 0.328, 316.0, None, None, 'Yield', True],
- [799.0, 799.0, 0.473, 316.0, None, None, 'Yield', True],
- [984.0, 984.0, 0.582, 316.0, None, None, 'Yield', True],
- [1107.0, 1107.0, 0.655, 316.0, None, None, 'Yield', True],
- [1168.0, 1168.0, 0.692, 316.0, None, None, 'Yield', True],
- [1217.0, 1217.0, 0.722, 316.0, None, None, 'Yield', True],
- [1266.0, 1266.0, 0.753, 316.0, None, None, 'Yield', True],
- [1303.0, 1303.0, 0.78, 316.0, None, None, 'Yield', True],
- [1334.0, 1334.0, 0.804, 316.0, None, None, 'Yield', True],
- [1359.0, 1359.0, 0.828, 316.0, None, None, 'Yield', True],
- [1383.0, 1383.0, 0.856, 316.0, None, None, 'Yield', True],
- [1402.0, 1402.0, 0.882, 316.0, None, None, 'Yield', True],
- [1414.0, 1414.0, 0.903, 316.0, None, None, 'Yield', True],
- [1426.0, 1426.0, 0.927, 316.0, None, None, 'Yield', True],
- [1439.0, 1439.0, 0.955, 316.0, None, None, 'Yield', True],
- [1451.0, 1451.0, 0.988, 316.0, None, None, 'Yield', True],
- [1463.0, 1463.0, 1.027, 316.0, None, None, 'Yield', True],
- [1475.0, 1475.0, 1.073, 316.0, None, None, 'Yield', True],
- [1488.0, 1488.0, 1.129, 316.0, None, None, 'Yield', True],
- [1500.0, 1500.0, 1.195, 316.0, None, None, 'Yield', True],
- [1512.0, 1512.0, 1.275, 316.0, None, None, 'Yield', True],
- [1519.0, 1519.0, 1.321, 316.0, None, None, 'Yield', True],
- [1525.0, 1525.0, 1.372, 316.0, None, None, 'Yield', True],
- [0.0, 0.0, 0.0, 427.0, None, None, 'Yield', True],
- [303.0, 303.0, 0.192, 427.0, None, None, 'Yield', True],
- [545.0, 545.0, 0.345, 427.0, None, None, 'Yield', True],
- [787.0, 787.0, 0.499, 427.0, None, None, 'Yield', True],
- [969.0, 969.0, 0.617, 427.0, None, None, 'Yield', True],
- [1090.0, 1090.0, 0.704, 427.0, None, None, 'Yield', True],
- [1151.0, 1151.0, 0.753, 427.0, None, None, 'Yield', True],
- [1199.0, 1199.0, 0.798, 427.0, None, None, 'Yield', True],
- [1247.0, 1247.0, 0.85, 427.0, None, None, 'Yield', True],
- [1284.0, 1284.0, 0.895, 427.0, None, None, 'Yield', True],
- [1314.0, 1314.0, 0.938, 427.0, None, None, 'Yield', True],
- [1338.0, 1338.0, 0.977, 427.0, None, None, 'Yield', True],
- [1362.0, 1362.0, 1.02, 427.0, None, None, 'Yield', True],
- [1381.0, 1381.0, 1.056, 427.0, None, None, 'Yield', True],
- [1393.0, 1393.0, 1.082, 427.0, None, None, 'Yield', True],
- [1405.0, 1405.0, 1.11, 427.0, None, None, 'Yield', True],
- [1417.0, 1417.0, 1.139, 427.0, None, None, 'Yield', True],
- [1429.0, 1429.0, 1.171, 427.0, None, None, 'Yield', True],
- [1441.0, 1441.0, 1.204, 427.0, None, None, 'Yield', True],
- [1453.0, 1453.0, 1.24, 427.0, None, None, 'Yield', True],
- [1465.0, 1465.0, 1.278, 427.0, None, None, 'Yield', True],
- [1478.0, 1478.0, 1.319, 427.0, None, None, 'Yield', True],
- [1490.0, 1490.0, 1.363, 427.0, None, None, 'Yield', True],
- [1496.0, 1496.0, 1.386, 427.0, None, None, 'Yield', True]]
-```
-
-
-The example data uses Celsius for temperature, but the database default is Kelvin.
-Change the parameter unit before import to take account of this.
-
-
-```python
-func.parameters["Temperature"].unit = "°C"
-```
-
-After changing the units, it is good practice to update the header units in `func.data` so that the units displayed in
-MI applications are correct.
-
-
-```python
-func.update_header_units()
-```
-
-## Write your changes to MI
-
-
-```python
-rec.set_attributes([func])
-mi.update([rec])
-```
-
-
-
-*Previous cell output:*
-```output
-[]
-```
-
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/08_Create_Functional_Data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/08_Create_Functional_Data.md
deleted file mode 100644
index fad669bed2..0000000000
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/08_Create_Functional_Data.md
+++ /dev/null
@@ -1,426 +0,0 @@
-# Create Functional Data
-Populate a functional attribute with data fitted using the Python `numpy` library.
-
-## Import libraries and define a polynomial fit function
-This example populates a functional attribute for *Ultimate Tensile Strength vs Temperature* in one table from a
-polynomial fit of the individual attributes in another table.
-
-
-```python
-from datetime import datetime
-import numpy as np
-from GRANTA_MIScriptingToolkit import granta as mpy
-
-def My4degPolyFitFunc(x, a, b, c, d, e):
- return a*np.power(x, 4) + b*np.power(x, 3) + c*np.power(x, 2) + d*x + e
-```
-
-## Specify database and table
-The source data will come from the *Tensile Statistical Data* table.
-
-
-```python
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
-
-db = mi.get_db(db_key="MI_Training")
-db.unit_system ="Metric"
-db.absolute_temperatures = True
-
-table = db.get_table("Tensile Statistical Data")
-```
-
-## Export test data
-Find *High Alloy Steel* > *AMS 6520* > *Plate* records in which both the *Ultimate Tensile Strength* and *Test
-Temperature* attributes are populated.
-
-
-```python
-records = table.get_records_from_path(
- starting_node=None,
- tree_path=["High Alloy Steel", "AMS 6520", "Plate"],
-)
-```
-
-Extract the attribute values from the returned records into x and y values.
-
-
-```python
-table.bulk_fetch(records, attributes=["Test Temperature", "Ultimate Tensile Strength"])
-populated_records = [
- r for r in records
- if not r.attributes["Test Temperature"].is_empty()
- and not r.attributes["Ultimate Tensile Strength"].is_empty()
-]
-
-x_values = [r.attributes["Test Temperature"].value for r in populated_records]
-y_values = [r.attributes["Ultimate Tensile Strength"].value for r in populated_records]
-```
-
-## Fit the test data
-Fit a fourth-order polynomial to your x and y data.
-
-
-```python
-coeffs = np.polyfit(x_values, y_values, 4)
-```
-
-Generate x and y values for the fitted equation, using the function you defined at the start.
-
-
-```python
-x_fit = np.linspace(np.amin(x_values), np.amax(x_values), 20)
-y_fit = My4degPolyFitFunc(x_fit, *coeffs)
-```
-
-## Create a record to store the data in
-The resulting functional data will be written into the *Metals* subset of the *Design Data* table,
-using the same unit system.
-
-
-```python
-design_data = db.get_table("Design Data")
-design_data.subsets.clear()
-design_data.subsets.add("Metals")
-```
-
-Create a new record to store your functional data.
-
-
-```python
-now = datetime.now().strftime("%c")
-record_name = f"Scripting Toolkit Example 8:{now}"
-record = design_data.create_record(record_name)
-record.color = mpy.RecordColor.Green
-```
-
-Access the (empty) functional attribute, and view its column headers.
-
-
-```python
-func = record.attributes["Tens. Ult. Stress (L-dir) with Temp."]
-func.column_headers
-```
-
-
-
-*Previous cell output:*
-```output
-['Y min (Tens. Ult. Stress (L-dir) with Temp. [MPa])',
- 'Y max (Tens. Ult. Stress (L-dir) with Temp. [MPa])',
- 'Temperature [K]',
- 'Time [hr]',
- 'Other []',
- 'Data Type Lab []',
- 'Estimated point?']
-```
-
-
-## Populate the functional attribute
-Add the test data to the functional attribute point-by-point, then view the attribute data. Column headers can be
-omitted if they aren't required to represent the data.
-
-
-```python
-for x, y in zip(x_values, y_values):
- point = {"Temperature": x, "y": y, "Data Type Lab": "Test Data"}
- func.add_point(point)
-func.value
-```
-
-
-
-*Previous cell output:*
-```output
-[['Y min (Tens. Ult. Stress (L-dir) with Temp. [MPa])',
- 'Y max (Tens. Ult. Stress (L-dir) with Temp. [MPa])',
- 'Temperature [K]',
- 'Time [hr]',
- 'Other []',
- 'Data Type Lab []',
- 'Estimated point?'],
- [1263.0048828125,
- 1263.0048828125,
- 810.9284057617188,
- None,
- None,
- 'Test Data',
- False],
- [2399.146240234375,
- 2399.146240234375,
- 194.2612762451172,
- None,
- None,
- 'Test Data',
- False],
- [2078.31, 2078.31, 422.0389938964844, None, None, 'Test Data', False],
- [1848.140014648438,
- 1848.140014648438,
- 588.7060546875,
- None,
- None,
- 'Test Data',
- False],
- [1734.37646484375,
- 1734.37646484375,
- 699.8172607421875,
- None,
- None,
- 'Test Data',
- False],
- [2189.89, 2189.89, 294.2613938964844, None, None, 'Test Data', False]]
-```
-
-
-Then add the fitted data to the functional attribute point-by-point, and view the attribute data with series number as
-an extra column.
-
-
-```python
-for x, y in zip(x_fit, y_fit):
- point = {"Temperature": x, "y": y, "Data Type Lab": "Fitted Data"}
- func.add_point(point)
-func.data_with_series_number
-```
-
-
-
-*Previous cell output:*
-```output
-[['Y min (Tens. Ult. Stress (L-dir) with Temp. [MPa])',
- 'Y max (Tens. Ult. Stress (L-dir) with Temp. [MPa])',
- 'Temperature [K]',
- 'Time [hr]',
- 'Other []',
- 'Data Type Lab []',
- 'Estimated point?',
- 'Series number'],
- [1263.0048828125,
- 1263.0048828125,
- 810.9284057617188,
- None,
- None,
- 'Test Data',
- False,
- 1],
- [2399.146240234375,
- 2399.146240234375,
- 194.2612762451172,
- None,
- None,
- 'Test Data',
- False,
- 1],
- [2078.31, 2078.31, 422.0389938964844, None, None, 'Test Data', False, 1],
- [1848.140014648438,
- 1848.140014648438,
- 588.7060546875,
- None,
- None,
- 'Test Data',
- False,
- 1],
- [1734.37646484375,
- 1734.37646484375,
- 699.8172607421875,
- None,
- None,
- 'Test Data',
- False,
- 1],
- [2189.89, 2189.89, 294.2613938964844, None, None, 'Test Data', False, 1],
- [np.float64(2392.1796767662518),
- np.float64(2392.1796767662518),
- np.float64(194.2612762451172),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(2333.081679240432),
- np.float64(2333.081679240432),
- np.float64(226.71744095651727),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(2274.74066356839),
- np.float64(2274.74066356839),
- np.float64(259.17360566791734),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(2219.0030335134543),
- np.float64(2219.0030335134543),
- np.float64(291.62977037931745),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(2167.2202125230733),
- np.float64(2167.2202125230733),
- np.float64(324.0859350907175),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(2120.248643728818),
- np.float64(2120.248643728818),
- np.float64(356.5420998021176),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(2078.4497899463804),
- np.float64(2078.4497899463804),
- np.float64(388.9982645135177),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(2041.6901336755727),
- np.float64(2041.6901336755727),
- np.float64(421.4544292249178),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(2009.3411771003305),
- np.float64(2009.3411771003305),
- np.float64(453.91059393631787),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(1980.2794420887074),
- np.float64(1980.2794420887074),
- np.float64(486.366758647718),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(1952.8864701928812),
- np.float64(1952.8864701928812),
- np.float64(518.822923359118),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(1925.0488226491502),
- np.float64(1925.0488226491502),
- np.float64(551.2790880705181),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(1894.1580803779325),
- np.float64(1894.1580803779325),
- np.float64(583.7352527819182),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(1857.1108439837685),
- np.float64(1857.1108439837685),
- np.float64(616.1914174933183),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(1810.3087337553218),
- np.float64(1810.3087337553218),
- np.float64(648.6475822047184),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(1749.6583896653735),
- np.float64(1749.6583896653735),
- np.float64(681.1037469161184),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(1670.571471370828),
- np.float64(1670.571471370828),
- np.float64(713.5599116275185),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(1567.9646582127116),
- np.float64(1567.9646582127116),
- np.float64(746.0160763389187),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(1436.2596492161715),
- np.float64(1436.2596492161715),
- np.float64(778.4722410503188),
- None,
- None,
- 'Fitted Data',
- False,
- 2],
- [np.float64(1269.3831630904717),
- np.float64(1269.3831630904717),
- np.float64(810.9284057617188),
- None,
- None,
- 'Fitted Data',
- False,
- 2]]
-```
-
-
-Adjust the series linestyles (`series_linestyles` is a dictionary, indexed with integers).
-
-
-```python
-func.series_linestyles[1] = "Markers"
-func.series_linestyles[2] = "Lines"
-func.series_linestyles
-```
-
-
-
-*Previous cell output:*
-```output
-{1: 'Markers', 2: 'Lines'}
-```
-
-
-## Write your changes to MI
-Set the attributes you've modified to update, and write the new record to the server.
-
-
-```python
-record.set_attributes([func])
-mi.update([record])
-```
-
-
-
-*Previous cell output:*
-```output
-[]
-```
-
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/13_Add_Date_Integer_and_Logical_Data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/08_Edit_Date_Integer_and_Logical_Data.md
similarity index 71%
rename from 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/13_Add_Date_Integer_and_Logical_Data.md
rename to 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/08_Edit_Date_Integer_and_Logical_Data.md
index 123d340522..5f56c73ebd 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/13_Add_Date_Integer_and_Logical_Data.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/08_Edit_Date_Integer_and_Logical_Data.md
@@ -1,21 +1,21 @@
-# Add Date, Integer and Logical data
-Work with date, integer, and logical attribute types.
+# Date, Integer and Logical data
+Work with date, integer, and logical data.
## Connect to MI
Get a database and table.
```python
-from datetime import datetime
-from GRANTA_MIScriptingToolkit import granta as mpy
+from datetime import date, datetime
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
db.unit_system = "Metric"
db.absolute_temperatures = False
-tab = db.get_table("AM Builds")
+table = db.get_table("AM Builds")
```
## Create a new record and path
@@ -26,9 +26,9 @@ Create a new **Record** object at the end of the path.
```python
now = datetime.now().strftime("%c")
-record_name = f"Scripting Toolkit Example 13:{now}"
-folder = tab.path_from(None, tree_path=["Blown Powder (Laser beam)", "Ti-6Al-4V"])
-record = tab.create_record(name=record_name, parent=folder)
+record_name = f"Scripting Toolkit Example 8:{now}"
+folder = table.path_from(None, tree_path=["Blown Powder (Laser beam)", "Ti-6Al-4V"])
+record = table.create_record(name=record_name, parent=folder)
record, folder
```
@@ -36,7 +36,7 @@ record, folder
*Previous cell output:*
```output
-(,
+(,
)
```
@@ -53,13 +53,12 @@ closed_chamber = record.attributes["Built in Closed Chamber?"]
```
### Date attributes
-Use the `value` property to set the date value of the attribute with either a **datetime** object or a properly
-formatted string.
+Use the `value` property to set the date value of the attribute with a **date** object.
```python
-diagnostic_date.value = "2020-07-12"
-build_date.value = datetime.now()
+diagnostic_date.value = date(year=2020, month=7, day=12)
+build_date.value = date.today()
```
### Integer attributes
@@ -97,19 +96,19 @@ datetime_format = "%b %d %Y"
diagnostic_date = record.attributes["Date of Beam Profile Diagnostic"]
print(f"Date of Beam Profile Diagnostic: {diagnostic_date.value.strftime(datetime_format)}")
-build_date = record.attributes['Date of Build']
+build_date = record.attributes["Date of Build"]
print(f"Date of Build: {build_date.value.strftime(datetime_format)}")
-number_of_layers = record.attributes['Maximum Number of Layers']
+number_of_layers = record.attributes["Maximum Number of Layers"]
print(f"Maximum Number of Layers: {number_of_layers.value}")
-closed_chamber = record.attributes['Built in Closed Chamber?']
+closed_chamber = record.attributes["Built in Closed Chamber?"]
print(f"Built in Closed Chamber?: {'Yes' if closed_chamber.value else 'No'}")
```
*Previous cell output:*
```output
Date of Beam Profile Diagnostic: Jul 12 2020
-Date of Build: May 12 2025
+Date of Build: Jan 07 2026
Maximum Number of Layers: 5
Built in Closed Chamber?: Yes
```
\ No newline at end of file
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/11_Add_Files_Pictures_and_Hyperlinks.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/09_Edit_Files_Pictures_and_Hyperlinks.md
similarity index 63%
rename from 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/11_Add_Files_Pictures_and_Hyperlinks.md
rename to 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/09_Edit_Files_Pictures_and_Hyperlinks.md
index c3bd725f39..fc52cfcaca 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/11_Add_Files_Pictures_and_Hyperlinks.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/09_Edit_Files_Pictures_and_Hyperlinks.md
@@ -1,5 +1,5 @@
-# Add Files, Pictures, and Hyperlinks
-Add File, Picture, and Hyperlink attribute types to MI.
+# Files, Pictures, and Hyperlinks
+Work with File, Picture, and Hyperlink data.
## Connect to MI
Specify a database and table.
@@ -8,14 +8,14 @@ Specify a database and table.
```python
from datetime import datetime
import pathlib
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
-tab = db.get_table("Tensile Test Data")
+table = db.get_table("Tensile Test Data")
```
-## Create a new record
+## Create a new record
Define a path in the table from a starting folder (in this case the top level folder) using `path_from()`.
If the path does not exist, the required folders will be created.
Create a new **Record** object at the end of the path.
@@ -23,9 +23,9 @@ Create a new **Record** object at the end of the path.
```python
now = datetime.now().strftime("%c")
-record_name = f"Scripting Toolkit Example 11:{now}"
-folder = tab.path_from(None, tree_path=["High Alloy Steels", "AMS 6520", "Plate", "300°F"])
-record = tab.create_record(name=record_name, parent=folder)
+record_name = f"Scripting Toolkit Example 9:{now}"
+folder = table.path_from(None, tree_path=["High Alloy Steels", "AMS 6520", "Plate", "300°F"])
+record = table.create_record(name=record_name, parent=folder)
record, folder
```
@@ -33,7 +33,7 @@ record, folder
*Previous cell output:*
```output
-(,
+(,
)
```
@@ -42,10 +42,10 @@ Access the empty **AttributeFile**, **AttributePicture**, and **AttributeHyperli
```python
-new_file = record.attributes["Test File 1"]
-new_pict = record.attributes["Image 2"]
-test_method_link = record.attributes["Standard Tension Testing Method"]
-test_method_link
+file_attribute = record.attributes["Test File 1"]
+picture_attribute = record.attributes["Image 2"]
+hyperlink_attribute = record.attributes["Standard Tension Testing Method"]
+hyperlink_attribute
```
@@ -65,20 +65,20 @@ bytes object. (Useful when you have a file already loaded in your script.)
```python
file_object = mpy.File()
-file_path = pathlib.Path("supporting_files/11_example_file_for_import.txt")
+file_path = pathlib.Path("./supporting_files/09_example_file_for_import.txt")
with open(file_path, "rb") as file_buffer:
file_object.binary_data = file_buffer.read()
file_object.file_name = file_path.name
file_object.description = "This is an example file"
-new_file.object = file_object
-new_file
+file_attribute.object = file_object
+file_attribute
```
*Previous cell output:*
```output
-
+
```
@@ -87,9 +87,9 @@ a file saved to disk).
```python
-picture = pathlib.Path("supporting_files/11_example_image_for_import.jpg")
-new_pict.load(picture)
-new_pict
+picture = pathlib.Path("./supporting_files/09_example_image_for_import.jpg")
+picture_attribute.load(picture)
+picture_attribute
```
@@ -106,10 +106,10 @@ and/or `hyperlink_description` properties.
```python
-test_method_link.value = "https://www.astm.org/Standards/E8"
-test_method_link.hyperlink_display = "New"
-test_method_link.hyperlink_description = "Specification"
-test_method_link
+hyperlink_attribute.value = "https://www.astm.org/Standards/E8"
+hyperlink_attribute.hyperlink_display = "New"
+hyperlink_attribute.hyperlink_description = "Specification"
+hyperlink_attribute
```
@@ -126,7 +126,7 @@ picture data.
```python
-record.set_attributes([new_file, new_pict, test_method_link])
+record.set_attributes([file_attribute, picture_attribute, hyperlink_attribute])
record = mi.update([record], include_binary_data_in_refresh=True)[0]
```
@@ -140,7 +140,7 @@ was run previously that saved a file to disk.
```python
from pathlib import Path
-output_folder = Path("./output")
+output_folder = Path("output")
output_folder.mkdir(exist_ok=True)
```
@@ -148,21 +148,21 @@ Next, save the picture to disk.
```python
-new_pict = record.attributes["Image 2"]
+picture_attribute = record.attributes["Image 2"]
from IPython.display import Image
-Image(new_pict.value)
+Image(picture_attribute.value)
```
-
+
```python
-new_pict.save(path="output/11_exported_picture.jpg")
+picture_attribute.save(path="./output/09_exported_picture.jpg")
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/11_Add_Files_Pictures_and_Hyperlinks_files/11_Add_Files_Pictures_and_Hyperlinks_20_0.jpg b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/09_Edit_Files_Pictures_and_Hyperlinks_files/09_Edit_Files_Pictures_and_Hyperlinks_20_0.jpg
similarity index 100%
rename from 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/11_Add_Files_Pictures_and_Hyperlinks_files/11_Add_Files_Pictures_and_Hyperlinks_20_0.jpg
rename to 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/09_Edit_Files_Pictures_and_Hyperlinks_files/09_Edit_Files_Pictures_and_Hyperlinks_20_0.jpg
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/09_Edit_Tabular_Data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/09_Edit_Tabular_Data.md
deleted file mode 100644
index 9165b1ec50..0000000000
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/09_Edit_Tabular_Data.md
+++ /dev/null
@@ -1,172 +0,0 @@
-# Edit Tabular Data
-Edit and compare tabular data using the Python `numpy` library.
-
-In this example, there is some existing tensile data for a material (AMS 6520, Plate, 1000°F).
-Some of that data is of particular interest and we want to separate it from the old data and
-put it in a record of its own.
-
-## Connect to MI
-Specify a database and table.
-
-
-```python
-from datetime import datetime
-import numpy as np
-from GRANTA_MIScriptingToolkit import granta as mpy
-
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
-
-db = mi.get_db(db_key="MI_Training")
-table = db.get_table("Tensile Statistical Data")
-```
-
-## Locate existing data
-Find the record and attribute that contains the original data.
-
-
-```python
-record = table.search_for_records_by_name("AMS 6520, Plate, 1000°F")[0]
-samples = record.attributes["Tensile test data used in this rollup"]
-```
-
-Select some samples of interest.
-
-
-```python
-focus_samples = ["MTS-615731", "MTS-615741", "MTS-615771"]
-```
-
-Get their **Record** objects from the tabular attribute containing the tensile test data.
-
-
-```python
-focus_recs = [samples.linked_records[s][0] for s in focus_samples]
-```
-
-Get their row indices in the tabular data structure.
-
-
-```python
-focus_rows = [samples["Linking Value (Specimen ID)"].index(samp) for samp in focus_samples]
-```
-
-## Extract and analyse the data
-Extract the sample data, and establish how different these particular samples are from the remainder of the set.
-
-
-```python
-focus_youngs = [samples["Young's Modulus (11-axis)", i] for i in focus_rows]
-rmain_youngs = [samples["Young's Modulus (11-axis)", i] for i in range(6) if i not in focus_rows]
-
-rmain_mean = np.mean(rmain_youngs)
-focus_mean = np.mean(focus_youngs)
-rmain_mean, focus_mean
-```
-
-
-
-*Previous cell output:*
-```output
-(np.float64(142.74677022298178), np.float64(146.3169097900391))
-```
-
-
-
-```python
-percentage_diff = 100*abs(rmain_mean-focus_mean)/(0.5*(rmain_mean+focus_mean))
-print(f"Percentage difference between the two means is: {percentage_diff} %")
-```
-*Previous cell output:*
-```output
-Percentage difference between the two means is: 2.470140535743884 %
-```
-## Create a new record and tabular attribute
-Create a new record for your data of interest.
-
-
-```python
-now = datetime.now().strftime("%c")
-recordName = f"Scripting Toolkit Example 9:{now}"
-new_rec = table.create_record(recordName, parent=record.parent, subsets={"Statistical Test Data"})
-```
-
-Select the tabular attribute to write to.
-
-
-```python
-new_samples = new_rec.attributes["Tensile test data used in this rollup"]
-new_samples
-```
-
-
-
-*Previous cell output:*
-```output
-
-```
-
-
-Link the samples to the new tabular datum.
-
-
-```python
-for focus_sample in focus_samples:
- new_samples.add_row(linking_value=focus_sample)
-new_samples
-```
-
-
-
-*Previous cell output:*
-```output
-
-```
-
-
-Set the new tabular attribute to update, and write the new record to MI.
-
-
-```python
-new_rec.set_attributes([new_samples])
-new_rec = mi.update([new_rec])[0]
-```
-
-## Link to the original record
-The original record is linked to the records you just linked to the tabular data. Link the new record to the original,
-too.
-
-(Records must exist on the server to be linked together, which means the record must be pushed to the server before it
-can be linked to other records.)
-
-
-```python
-new_rec.set_links("Tensile Test Data", set(focus_recs))
-new_rec.links
-```
-
-
-
-*Previous cell output:*
-```output
-{'Tensile Test Data': {,
- ,
- }}
-```
-
-
-## Update the new record's links on the server
-Like changes to data, changes to links also need to be pushed to the server. Unlike attributes, links do not need to
-be flagged for update (there is no equivalent to `set_attributes()` for links).
-
-
-```python
-mi.update_links([new_rec])
-```
-
-
-
-*Previous cell output:*
-```output
-[]
-```
-
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/10_Edit_Float_Functional_Data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/10_Edit_Float_Functional_Data.md
new file mode 100644
index 0000000000..0a4eb1a38c
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/10_Edit_Float_Functional_Data.md
@@ -0,0 +1,388 @@
+# Float Functional Data
+
+Work with float functional data, including modifying parameter configurations.
+
+This example first introduces the different representations of float functional data in Granta MI, and then shows how
+to create and modify series float functional data, and then how to convert series float functional data into the
+corresponding grid representation.
+
+## Connect to MI
+Specify a database and table.
+
+
+```python
+import ansys.grantami.core as mpy
+
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
+db = mi.get_db(db_key="MI_Training")
+
+table = db.get_table("Design Data")
+```
+
+## Create a new record
+Define names for a new record, and an attribute on that record.
+
+
+```python
+from datetime import datetime
+
+now = datetime.now().strftime('%c')
+record_name = f"Scripting Toolkit Example 10:{now}"
+functional_attribute_name = "Tensile Stress/Strain, L"
+```
+
+Create the new **Record** object.
+
+
+```python
+record = table.create_record(record_name)
+record
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+Get the unpopulated functional attribute for the new record, so we can populate it.
+
+
+```python
+functional_attribute = record.attributes[functional_attribute_name]
+functional_attribute
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+## Types of functional data in Scripting Toolkit
+
+Granta MI represents float functional data as either series functional or grid functional. Additionally, the
+schema defines a float functional attribute as containing either point or range data. As a result, there are
+four possible representations of float functional data in Scripting Toolkit:
+
+* Point series functional data as an `AttributeFunctionalSeriesPoint` object
+* Range series functional data as an `AttributeFunctionalSeriesRange` object
+* Point grid functional data as an `AttributeFunctionalGridPoint` object
+* Range grid functional data as an `AttributeFunctionalGridRange` object
+
+These objects do not need to be instantiated manually. When exporting existing data, the appropriate object is
+chosen automatically based on the data. Empty functional attributes are set as series functional data by default,
+and the definition of the attribute in the database schema defines whether the point or range variant is chosen.
+Methods are provided to convert between series and grid representations of functional data.
+
+In this case, the "Tensile Stress/Strain, L" attribute is defined as a point attribute, and the `type()`
+function shows that a `AttributeFunctionalSeriesPoint` object has been created accordingly.
+
+
+```python
+type(functional_attribute)
+```
+
+
+
+*Previous cell output:*
+```output
+ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint
+```
+
+
+All float functional attribute values have a defined x-axis parameter. Check the current x-axis parameter with the
+`x_axis` property.
+
+
+```python
+functional_attribute.x_axis
+```
+
+
+
+*Previous cell output:*
+```output
+'Strain'
+```
+
+
+If the x-axis needs to be changed, use the `.with_new_x_axis()` method, with the name of the parameter to be used as
+the x-axis.
+
+
+```python
+stress_vs_temperature = functional_attribute.with_new_x_axis("Temperature")
+stress_vs_temperature.x_axis
+```
+
+
+
+*Previous cell output:*
+```output
+'Temperature'
+```
+
+
+## Create and import series functional data
+
+This section shows how to create and import series-based data. Since this is a point-based functional attribute,
+create `SeriesPoint` objects to create single-valued series functional data. This example imports stress-strain data
+as a function of temperature.
+
+A series functional attribute value is defined as a tuple of series objects. There are two series types available,
+`SeriesPoint` and `SeriesRange`. Use the appropriate object depending on the attribute value object type. For
+series data, each series must be created with two equal-length tuples of x values and y values. Each series may also
+have a tuple of parameter values and a decoration type.
+
+In this example, create two `SeriesPoint` objects for our two series, each with an additional 'Temperature' value.
+Assign both series to the functional attribute value.
+
+
+```python
+series_1 = mpy.SeriesPoint(
+ x=(0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2),
+ y=(0., 100., 200., 300., 400., 495., 585., 670., 750., 825., 895., 950., 1000.),
+ parameters=(mpy.SeriesParameterValue(name="Temperature", value=20.),), # Note: This is a 1-tuple
+ decoration=mpy.GraphDecoration.LINES,
+)
+series_2 = mpy.SeriesPoint(
+ x=(0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2),
+ y=(0., 75., 150., 225., 300., 370., 440., 500., 560., 620., 670., 710., 750.),
+ parameters=(mpy.SeriesParameterValue(name="Temperature", value=200.),), # Note: This is a 1-tuple
+ decoration=mpy.GraphDecoration.LINES,
+)
+
+functional_attribute.value = (series_1, series_2)
+```
+
+The y-axis unit is set with the `.unit` property
+
+
+```python
+functional_attribute.unit = "ksi"
+```
+
+Parameter units are set by modifying values returned by the `.parameters` property.
+
+
+```python
+functional_attribute.parameters["Temperature"].unit = "°C"
+```
+
+Additional parameter properties can also be modified. These do not affect the behavior of Scripting Toolkit
+operations, but may modify the behavior of other tools that interact with the data, for example MI Explore and MI
+Viewer.
+
+
+```python
+functional_attribute.parameters["Strain"].interpolation_type = "Cubic Spline"
+functional_attribute.parameters["Temperature"].interpolation_type = "None"
+```
+
+Access the `functional_attribute.table_view.table_view` property to see the underlying data structure of the attribute
+represented as a list of lists. It shows all parameters supported by the attribute. Parameters that were not
+populated during the import have been set to **None**.
+
+
+```python
+functional_attribute.table_view.table_view
+```
+
+
+
+*Previous cell output:*
+```output
+[['Y min (Tensile Stress/Strain, L [ksi])',
+ 'Y max (Tensile Stress/Strain, L [ksi])',
+ 'Strain [% strain]',
+ 'Temperature [°C]',
+ 'Time [hr]',
+ 'Other [None]',
+ 'Stress/Strain Curve Type [None]',
+ 'Estimated point?'],
+ [0.0, 0.0, 0.0, 20.0, None, None, None, False],
+ [100.0, 100.0, 0.1, 20.0, None, None, None, False],
+ [200.0, 200.0, 0.2, 20.0, None, None, None, False],
+ [300.0, 300.0, 0.3, 20.0, None, None, None, False],
+ [400.0, 400.0, 0.4, 20.0, None, None, None, False],
+ [495.0, 495.0, 0.5, 20.0, None, None, None, False],
+ [585.0, 585.0, 0.6, 20.0, None, None, None, False],
+ [670.0, 670.0, 0.7, 20.0, None, None, None, False],
+ [750.0, 750.0, 0.8, 20.0, None, None, None, False],
+ [825.0, 825.0, 0.9, 20.0, None, None, None, False],
+ [895.0, 895.0, 1.0, 20.0, None, None, None, False],
+ [950.0, 950.0, 1.1, 20.0, None, None, None, False],
+ [1000.0, 1000.0, 1.2, 20.0, None, None, None, False],
+ [0.0, 0.0, 0.0, 200.0, None, None, None, False],
+ [75.0, 75.0, 0.1, 200.0, None, None, None, False],
+ [150.0, 150.0, 0.2, 200.0, None, None, None, False],
+ [225.0, 225.0, 0.3, 200.0, None, None, None, False],
+ [300.0, 300.0, 0.4, 200.0, None, None, None, False],
+ [370.0, 370.0, 0.5, 200.0, None, None, None, False],
+ [440.0, 440.0, 0.6, 200.0, None, None, None, False],
+ [500.0, 500.0, 0.7, 200.0, None, None, None, False],
+ [560.0, 560.0, 0.8, 200.0, None, None, None, False],
+ [620.0, 620.0, 0.9, 200.0, None, None, None, False],
+ [670.0, 670.0, 1.0, 200.0, None, None, None, False],
+ [710.0, 710.0, 1.1, 200.0, None, None, None, False],
+ [750.0, 750.0, 1.2, 200.0, None, None, None, False]]
+```
+
+
+Use the `mi.update()` method to import the data into Granta MI.
+
+
+```python
+record.set_attributes([functional_attribute])
+record = mi.update([record])[0]
+functional_attribute = record.attributes[functional_attribute_name]
+```
+
+## Editing float functional data
+
+This section shows how to modify series functional data.
+
+`SeriesPoint` objects are immutable, so they cannot be modified. However, existing values can be used when creating a
+new series. The cell below adds two additional points to the `series_2` value.
+
+
+```python
+from math import isclose
+
+series_200_deg = next(
+ series for series in functional_attribute.value
+ if isclose(series.parameters_by_name["Temperature"], 200)
+)
+
+series_2_extra_points = mpy.SeriesPoint(
+ x=series_200_deg.x + (1.3, 1.4),
+ y=series_200_deg.y + (770., 785.),
+ parameters=series_200_deg.parameters,
+ decoration=series_200_deg.decoration,
+)
+```
+
+The `functional_attribute.value` attribute is a tuple, so it is also immutable. To update the series objects
+assigned to the value, all series objects must be provided. The cell below defines an entirely new series, and then
+adds the original first series, the modified second series, and the new third series to the attribute value.
+
+Using immutable values in this way provides greater validation, ensuring that any errors in the data are raised as
+exceptions as soon as they are associated with the attribute value.
+
+
+```python
+series_3 = mpy.SeriesPoint(
+ x=(0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2),
+ y=(0., 50., 100., 150., 200., 250., 290., 335., 375., 410., 450., 475., 500.),
+ parameters=(mpy.SeriesParameterValue(name="Temperature", value=400.),), # Note: This is a 1-tuple
+ decoration=mpy.GraphDecoration.LINES,
+)
+
+functional_attribute.value = (series_1, series_2_extra_points, series_3)
+```
+
+Use the `mi.update()` method to import the data into Granta MI.
+
+
+```python
+record.set_attributes([functional_attribute])
+record = mi.update([record])[0]
+functional_attribute = record.attributes[functional_attribute_name]
+```
+
+## Convert series data to grid data
+
+The final section shows how to convert between series and grid representations of float functional data.
+
+Use the `generate_grid_version()` method to convert the series functional attribute value to the equivalent grid
+functional attribute value object. In this case, our `AttributeFunctionalSeriesPoint` attribute value is converted
+to an `AttributeFunctionalGridPoint` object. This method raises a `ValueError` if the series functional data cannot
+be represented as grid functional data.
+
+
+```python
+grid_functional_attribute = functional_attribute.generate_grid_version()
+type(grid_functional_attribute)
+```
+
+
+
+*Previous cell output:*
+```output
+ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint
+```
+
+
+The collection of `SeriesPoint` objects has been converted to a single `GridPoint` object. This contains the same
+information, but note that the temperature values have been expanded to fully populate the grid.
+
+
+```python
+grid_value = grid_functional_attribute.value
+print(f"x values: {grid_value.x[:20]}...")
+print(f"y values: {grid_value.y[:20]}...")
+print(f"Temperature values: {grid_value.parameters_by_name['Temperature'][:20]}...")
+```
+*Previous cell output:*
+```output
+x values: (0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6)...
+y values: (0.0, 100.0, 200.0, 300.0, 400.0, 495.0, 585.0, 670.0, 750.0, 825.0, 895.0, 950.0, 1000.0, 0.0, 75.0, 150.0, 225.0, 300.0, 370.0, 440.0)...
+Temperature values: (20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0)...
+```
+The units and parameter configuration options are preserved by the transformation from series to grid representation.
+
+
+```python
+print(f"y unit: {grid_functional_attribute.unit}")
+
+print(f"Temperature unit: {grid_functional_attribute.parameters['Temperature'].unit}")
+
+print(f"Strain interpolation type: {grid_functional_attribute.parameters['Strain'].interpolation_type}")
+print(f"Temperature interpolation type: {grid_functional_attribute.parameters['Temperature'].interpolation_type}")
+```
+*Previous cell output:*
+```output
+y unit: ksi
+Temperature unit: °C
+Strain interpolation type: Cubic Spline
+Temperature interpolation type: None
+```
+Import the modified attribute.
+
+
+```python
+record.set_attributes([grid_functional_attribute])
+record.flag_for_release = False
+record = mi.update([record])[0]
+record
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+Since the attribute now contains grid functional data, the data is exported into a `AttributeFunctionalGridPoint`
+object.
+
+
+```python
+grid_functional_attribute = record.attributes[functional_attribute_name]
+type(grid_functional_attribute)
+```
+
+
+
+*Previous cell output:*
+```output
+ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint
+```
+
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/11_Edit_Local_Tabular_Data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/11_Edit_Local_Tabular_Data.md
new file mode 100644
index 0000000000..08e931e708
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/11_Edit_Local_Tabular_Data.md
@@ -0,0 +1,589 @@
+# Local Tabular Data
+
+Work with local tabular data, including how to add and delete local rows.
+
+In general, tabular attributes contain a combination of local and linked tabular columns. This example focuses on
+local tabular columns only. [Example 12](./12_Edit_Linked_Tabular_Data.ipynb) shows how to work with linked tabular
+data.
+
+## Create a new record
+Connect to MI and specify a database and table.
+
+
+```python
+from datetime import datetime, date
+from pathlib import Path
+
+import ansys.grantami.core as mpy
+
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
+db = mi.get_db(db_key="MI_Training")
+table = db.get_table("Training Exercise for Import")
+```
+
+Create a new record.
+
+
+```python
+now = datetime.now().strftime("%c")
+recordName = f"Scripting Toolkit Example 11:{now}"
+record = table.create_record(recordName)
+record
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+## Access a local tabular attribute
+
+Access the (empty) tabular attribute *Characterization of this material*.
+
+
+```python
+tabular_attribute = record.attributes["Characterization of this material"]
+tabular_attribute
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+The tabular attribute `__repr__` shows that the tabular attribute is not loaded yet, and so additional information
+about the number of rows and columns is not available.
+
+Tabular data is loaded on-demand to improve performance, and reading or modifying the data will load the data
+automatically. However, accessing the `__repr__` does not trigger the load operation. To load the data manually, use
+the `.load()` method.
+
+Once the attribute is loaded, the `__repr__` shows the number of rows and columns.
+
+
+```python
+tabular_attribute.load()
+tabular_attribute
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+The `.column_name`, `.column_types`, and `.linked_columns` properties list the tabular column names, types, and
+whether the column is linked. Each of these properties contain 11 entries, which corresponds to the number of columns
+in the tabular attribute, and the size printed in the tabular attribute `__repr__`.
+
+
+```python
+for column_name, column_type, is_linked in zip(
+ tabular_attribute.columns, tabular_attribute.column_types, tabular_attribute.linked_columns
+):
+ print(f"{column_name}: {column_type} ({'Linked' if is_linked else 'Local'})")
+```
+*Previous cell output:*
+```output
+Order: INPT (Local)
+Date: DTTM (Local)
+Technique: DISC (Local)
+Technique (other): STXT (Local)
+Non-destructive?: LOGI (Local)
+Image: PICT (Local)
+Raw data: FILE (Local)
+Data on server: HLNK (Local)
+Temperature: POIN (Local)
+Notes: LTXT (Local)
+Grain size: RNGE (Local)
+```
+The `.value` property contains an immutable representation of the current state of the tabular attribute
+value. Since the tabular attribute is empty, this returns an empty tuple.
+
+
+```python
+tabular_attribute.value
+```
+
+
+
+*Previous cell output:*
+```output
+()
+```
+
+
+The `.linking_table` and `.linking_attribute` properties contain the target table and target attribute. This is a
+local tabular attribute, so these properties both return `None`.
+
+
+```python
+print(f"Target table: {tabular_attribute.linking_table}")
+print(f"Target attribute: {tabular_attribute.linking_attribute}")
+```
+*Previous cell output:*
+```output
+Target table: None
+Target attribute: None
+```
+## Add rows and data
+
+Add a new row to the tabular attribute.
+
+
+```python
+tabular_attribute.append_row()
+tabular_attribute.rows
+```
+
+
+
+*Previous cell output:*
+```output
+(,)
+```
+
+
+An empty `TabularRow` object is created, which contains a blank cell for each local tabular column, stored in a tuple.
+The type of the cell object depends on the type of the column.
+
+Access the tuple of cell objects via the `.cells` property.
+
+
+```python
+row = tabular_attribute.rows[0]
+row.cells
+```
+
+
+
+*Previous cell output:*
+```output
+(LocalIntegerValue(value=None),
+ LocalDateValue(value=None),
+ LocalDiscreteValue(value=None, order=None),
+ LocalShortTextValue(value=None),
+ LocalLogicalValue(value=None),
+ LocalPictureValue(),
+ LocalFileValue(),
+ LocalHyperlinkValue(value=None, hyperlink_display=None, hyperlink_description=None),
+ LocalPointValue(value=None, unit="K"),
+ LocalLongTextValue(value=None),
+ LocalRangeValue(low=None, high=None, low_value_is_inclusive=True, high_value_is_inclusive=True, unit="µm"))
+```
+
+
+Often it is more convenient to access cells by their column name. The `.cells_by_column` property returns a mapping of
+column name to cell object.
+
+
+```python
+row.cells_by_column
+```
+
+
+
+*Previous cell output:*
+```output
+mappingproxy({'Order': LocalIntegerValue(value=None),
+ 'Date': LocalDateValue(value=None),
+ 'Technique': LocalDiscreteValue(value=None, order=None),
+ 'Technique (other)': LocalShortTextValue(value=None),
+ 'Non-destructive?': LocalLogicalValue(value=None),
+ 'Image': LocalPictureValue(),
+ 'Raw data': LocalFileValue(),
+ 'Data on server': LocalHyperlinkValue(value=None, hyperlink_display=None, hyperlink_description=None),
+ 'Temperature': LocalPointValue(value=None, unit="K"),
+ 'Notes': LocalLongTextValue(value=None),
+ 'Grain size': LocalRangeValue(low=None, high=None, low_value_is_inclusive=True, high_value_is_inclusive=True, unit="µm")})
+```
+
+
+Tabular cell classes have similar interfaces to their attribute value counterparts. For example, all tabular cell
+classes have a `.value` property, and picture and file tabular cell classes have a `.load()` method.
+
+The name of each cell type has a 'Local' prefix, which indicates that these are local columns and can be modified.
+
+Each tabular cell class also has a linked counterpart without the 'Local' prefix. These are shown in the linked
+tabular data example referenced in the introduction. These linked tabular cell classes are read-only and cannot be
+modified.
+
+### Text cells
+
+Long text cells can accept any string value. Short text cells can accept any string value less than 255 characters.
+
+Assign the string to the `.value` property.
+
+
+```python
+row.cells_by_column["Notes"].value = "Scripting Toolkit example #11 - This example shows how to import tabular data"
+row.cells_by_column["Technique (other)"].value = "Example"
+```
+
+### Integer cells
+
+Integer cells can accept any integer value. Assign the integer to the `.value` property.
+
+
+```python
+row.cells_by_column["Order"].value = 1
+```
+
+### Date cells
+
+Date cells accept a `datetime.date` object. Assign the date to the `.value` property.
+
+
+```python
+row.cells_by_column["Date"].value = date(2025, 10, 23)
+```
+
+### Logical cells
+
+Logical cells accept either `True` or `False`. Assign the boolean to the `.value` property.
+
+
+```python
+row.cells_by_column["Non-destructive?"].value = True
+```
+
+### Discrete cells
+
+Discrete cells accept a limited set of allowed strings. To see which values are allowed, use the
+`.possible_discrete_values` property.
+
+
+```python
+row.cells_by_column["Technique"].possible_discrete_values
+```
+
+
+
+*Previous cell output:*
+```output
+frozenset({'Electron microscopy', 'Light microscopy', 'Other'})
+```
+
+
+Use one of these for new value:
+
+
+```python
+row.cells_by_column["Technique"].value = "Other"
+```
+
+### Point cells
+
+Point cells accept a float value and a unit.
+
+In contrast to point attributes, point cells are always single-valued and may not contain parameter information.
+
+
+```python
+cell = row.cells_by_column["Temperature"]
+
+cell.value = 250.0
+cell.unit = "°C"
+```
+
+### Range cells
+
+Range cells are similar to point cells, except they accept high and low float values and a unit.
+
+Each high and low bound may be marked as inclusive or exclusive, using the `.low_value_is_inclusive` and
+`.high_value_is_inclusive` property.
+
+Range cell classes differ from range attribute classes in that they do not contain a `.value` property. Cell values
+are set using the `.low` and `.high` properties directly.
+
+
+```python
+cell = row.cells_by_column["Grain size"]
+
+cell.low = 1.
+cell.high = 2.
+cell.unit = "mil"
+cell.high_value_is_inclusive = False
+```
+
+### Picture cells
+
+Picture cells can be populated either by setting `.value` to a `bytes` object, or using the `.load()` method.
+
+
+```python
+image_path = Path("./supporting_files/09_example_image_for_import.jpg")
+
+row.cells_by_column["Image"].load(image_path)
+```
+
+### File cells
+
+File cells are similar to picture cells, and can also be populated either by setting `.value` to a `bytes` object, or
+using the `.load()` method. However, file cells also have a settable `.file_name` and `.description` field.
+
+
+```python
+file_path = Path("./supporting_files/09_example_file_for_import.txt")
+
+cell = row.cells_by_column["Raw data"]
+cell.load(file_path)
+cell.file_name = "Raw data file.txt"
+cell.description = "Plain text file containing raw data"
+```
+
+### Hyperlink cells
+
+Hyperlink cells accept a `.value` property which contains the link url, along with `.hyperlink_display` and
+`.hyperlink_description` properties which control how the hyperlink is displayed in MI Viewer.
+
+
+```python
+cell = row.cells_by_column["Data on server"]
+
+cell.value = "http://example.org/test_data_12345"
+cell.hyperlink_display = "New"
+cell.hyperlink_description = "Test data #12345"
+```
+
+Print the cells again to show the added values.
+
+
+```python
+row.cells_by_column
+```
+
+
+
+*Previous cell output:*
+```output
+mappingproxy({'Order': LocalIntegerValue(value=1),
+ 'Date': LocalDateValue(value="2025-10-23"),
+ 'Technique': LocalDiscreteValue(value="Other", order=2),
+ 'Technique (other)': LocalShortTextValue(value="Example"),
+ 'Non-destructive?': LocalLogicalValue(value=True),
+ 'Image': LocalPictureValue(binary_data=<224.69 KB>, mime_file_type="image/jpeg"),
+ 'Raw data': LocalFileValue(binary_data=<23 B>, mime_file_type=None, file_name="Raw data file.txt", description="Plain text file containing raw data"),
+ 'Data on server': LocalHyperlinkValue(value="http://example.org/test_dat...", hyperlink_display="New", hyperlink_description="Test data #12345"),
+ 'Temperature': LocalPointValue(value=250.0, unit="°C"),
+ 'Notes': LocalLongTextValue(value="Scripting Toolkit example #..."),
+ 'Grain size': LocalRangeValue(low=1, high=2, low_value_is_inclusive=True, high_value_is_inclusive=False, unit="mil")})
+```
+
+
+The data is also visible in the `AttributeTabular.value` property.
+
+This property is useful as a high-level summary of the data, but should not be used for processing. The `.rows`
+property provides a richer representation of the data.
+
+
+```python
+tabular_attribute.value
+```
+
+
+
+*Previous cell output:*
+```output
+((1,
+ datetime.datetime(2025, 10, 23, 0, 0),
+ ('Other',),
+ 'Example',
+ True,
+ PictureValue(binary_data=<224.69 KB>, mime_file_type="image/jpeg"),
+ FileValue(binary_data=<23 B>, mime_file_type=None, file_name="Raw data file.txt", description="Plain text file containing raw data"),
+ HyperlinkValue(value="http://example.org/test_dat...", hyperlink_display="New", hyperlink_description="Test data #12345"),
+ (250.0,),
+ 'Scripting Toolkit example #11 - This example shows how to import tabular data',
+ mappingproxy({'low': 1.0,
+ 'high': 2.0,
+ 'low_is_inclusive': True,
+ 'high_is_inclusive': False}),
+ ''),)
+```
+
+
+### Write changes to Granta MI
+
+Finally, write the changes to the server.
+
+
+```python
+record.set_attributes([tabular_attribute])
+record = mi.update([record])[0]
+```
+
+Check the content of the tabular attribute after the update.
+
+
+```python
+tabular_attribute = record.attributes["Characterization of this material"]
+tabular_attribute.rows
+```
+
+
+
+*Previous cell output:*
+```output
+(,)
+```
+
+
+## Edit tabular data
+
+Most modifications to tabular data can be made as updates to the data already in the database. For example, adding a
+new row only requires the new row to be uploaded to the database, any existing data is not re-transmitted.
+
+The next cell adds two new rows, and adds data to a subset of cells in each.
+
+
+```python
+tabular_attribute.append_row()
+tabular_attribute.append_row()
+
+new_row = tabular_attribute.rows[1]
+new_row.cells_by_column["Order"].value = 2
+new_row.cells_by_column["Date"].value = date(2025, 10, 29)
+new_row.cells_by_column["Notes"].value = "A new row can be appended to an existing tabular attribute"
+
+new_row = tabular_attribute.rows[2]
+new_row.cells_by_column["Order"].value = 3
+new_row.cells_by_column["Date"].value = date(2025, 10, 30)
+new_row.cells_by_column["Notes"].value = "Multiple rows can be added in the same operation"
+
+record.set_attributes([tabular_attribute])
+record = mi.update([record])[0]
+```
+
+Check the content of the tabular attribute after the update.
+
+
+```python
+tabular_attribute = record.attributes["Characterization of this material"]
+tabular_attribute.rows
+```
+
+
+
+*Previous cell output:*
+```output
+(,
+ ,
+ )
+```
+
+
+Rows can be deleted and modified in the same operation
+
+
+```python
+tabular_attribute.delete_row(1)
+tabular_attribute.rows[1].cells_by_column["Order"].value = 2
+tabular_attribute.rows[1].cells_by_column["Notes"].value = "Rows can be deleted and modified in the same operation"
+
+record.set_attributes([tabular_attribute])
+record = mi.update([record])[0]
+
+tabular_attribute = record.attributes["Characterization of this material"]
+tabular_attribute.rows
+```
+
+
+
+*Previous cell output:*
+```output
+(,
+ )
+```
+
+
+## Destructive operations
+
+Destructive operations cannot be completed by modifying data in-place, and can only be completed by overwriting all
+values.
+
+
+
+**Warning:**
+
+Destructive editing should be avoided because:
+
+* This can be slow for attributes with File or Picture attributes, especially if many rows are present.
+* Users of Data Updater will face conflicts when applying subsequent updates.
+
+
+Modifying the order of rows in a tabular attribute is a destructive operation, and by default raises a `ValueError`.
+
+
+```python
+try:
+ tabular_attribute.swap_rows(0, 1)
+except ValueError as e:
+ print("The previous operation caused an exception")
+ print(e)
+```
+*Previous cell output:*
+```output
+The previous operation caused an exception
+This action is considered destructive and is not allowed by default. Call the method 'enable_destructive_editing()' to allow it.
+```
+To check whether destructive editing is allowed, use the property `.is_destructive_editing_allowed`:
+
+
+```python
+print(f"Is destructive editing allowed? {tabular_attribute.is_destructive_editing_allowed}")
+```
+*Previous cell output:*
+```output
+Is destructive editing allowed? False
+```
+To allow destructive editing, call the method `.enable_destructive_editing()`. Re-export the tabular attribute with
+binary data enabled to avoid an exception when calling `mi.update()`.
+
+
+```python
+record.refresh_attributes()
+
+tabular_attribute = record.attributes["Characterization of this material"]
+
+tabular_attribute.enable_destructive_editing()
+print(f"Is destructive editing allowed? {tabular_attribute.is_destructive_editing_allowed}")
+```
+*Previous cell output:*
+```output
+Is destructive editing allowed? True
+```
+Swapping rows will now not raise an exception.
+
+
+```python
+tabular_attribute.swap_rows(0, 1)
+```
+
+Update the record in Granta MI. Note that this will re-import all data in the tabular attribute.
+
+
+```python
+record.set_attributes([tabular_attribute])
+record = mi.update([record])[0]
+
+tabular_attribute = record.attributes["Characterization of this material"]
+tabular_attribute.rows
+```
+
+
+
+*Previous cell output:*
+```output
+(,
+ )
+```
+
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/12_Edit_Linked_Tabular_Data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/12_Edit_Linked_Tabular_Data.md
new file mode 100644
index 0000000000..a388eb979b
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/12_Edit_Linked_Tabular_Data.md
@@ -0,0 +1,533 @@
+# Linked Tabular Data
+
+Work with linked tabular data, including how to access linked data within linked rows.
+
+In general, tabular attributes contain a combination of local and linked tabular columns. This example focuses on
+linked tabular rows and columns only. [Example 11](./11_Edit_Local_Tabular_Data.ipynb) shows how to work with local
+tabular data.
+
+## Access an existing record
+Connect to MI and specify a database and table.
+
+
+```python
+from datetime import datetime, date
+from pathlib import Path
+
+import ansys.grantami.core as mpy
+
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
+db = mi.get_db(db_key="MI_Training")
+table = db.get_table("Tensile Statistical Data")
+```
+
+Access an existing record by path.
+
+
+```python
+records = table.get_records_from_path(
+ starting_node=None,
+ tree_path=["Additive Manufacturing", "Titanium", "Ti-6Al-4V"],
+)
+record = next(r for r in records if r.name == "L13L12 - 9 Samples")
+record
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+## Access a linked tabular attribute
+
+Access the tabular attribute *Tensile test data used in this rollup*.
+
+
+```python
+tabular_attribute = record.attributes["Tensile test data used in this rollup"]
+tabular_attribute
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+The tabular attribute `__repr__` shows that the tabular attribute is not loaded yet, and so additional information
+about the number of rows and columns is not available.
+
+Tabular data is loaded on-demand to improve performance, and reading or modifying the data will load the data
+automatically. However, accessing the `__repr__` does not trigger the load operation. To load the data manually, use
+the `.load()` method.
+
+Once the attribute is loaded, the `__repr__` shows the number of rows and columns.
+
+
+```python
+tabular_attribute.load()
+tabular_attribute
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+The `.column_name`, `.column_types`, and `.linked_columns` properties list the tabular column names, types, and
+whether the column is linked. Each of these properties contain 8 entries, which corresponds to the number of columns
+in the tabular attribute, and the size printed in the tabular attribute `__repr__`.
+
+
+```python
+for column_name, column_type, is_linked in zip(
+ tabular_attribute.columns, tabular_attribute.column_types, tabular_attribute.linked_columns
+):
+ print(f"{column_name}: {column_type} ({'Linked' if is_linked else 'Local'})")
+```
+*Previous cell output:*
+```output
+Specimen ID: STXT (Linked)
+Date Test Performed: DTTM (Linked)
+Strain rate is equivalent: LOGI (Linked)
+Control mode: DISC (Linked)
+Test Temperature: POIN (Linked)
+Young's Modulus (11-axis): POIN (Linked)
+0.02% Offset yield stress: POIN (Linked)
+0.2% Offset yield stress: POIN (Linked)
+```
+The `.value` property contains an immutable representation of the current state of the tabular attribute
+value.
+
+This property is useful as a high-level summary of the data, but should not be used for processing. The `.rows`
+property described in the next section provides a richer representation of the data.
+
+
+```python
+tabular_attribute.value
+```
+
+
+
+*Previous cell output:*
+```output
+((('L13L12AA1T',), (), (), (), (), (), (), ((126.73,),), 'L13L12AA1T'),
+ (('L13L12AA3T',),
+ (),
+ (),
+ (),
+ (),
+ (),
+ (),
+ ((126.06499999999998,),),
+ 'L13L12AA3T'),
+ (('L13L12AA5T',), (), (), (), (), (), (), ((129.39,),), 'L13L12AA5T'),
+ (('L13L12AA7T',), (), (), (), (), (), (), ((132.43,),), 'L13L12AA7T'),
+ (('L13L12AA9T',), (), (), (), (), (), (), ((133.0,),), 'L13L12AA9T'),
+ (('L13L12AA11T',), (), (), (), (), (), (), ((127.3,),), 'L13L12AA11T'),
+ (('L13L12AA13T',), (), (), (), (), (), (), ((121.125,),), 'L13L12AA13T'),
+ (('L13L12AA15T',), (), (), (), (), (), (), ((121.315,),), 'L13L12AA15T'),
+ (('L13L12AA17T',), (), (), (), (), (), (), ((121.885,),), 'L13L12AA17T'))
+```
+
+
+The `.linking_table` and `.linking_attribute` properties contain the target table and target attribute. This is a
+linked tabular attribute, so these properties return `Table` and `AttributeValue` objects respectively.
+
+
+```python
+print(f"Target table: {tabular_attribute.linking_table}")
+print(f"Target attribute: {tabular_attribute.linking_attribute}")
+```
+*Previous cell output:*
+```output
+Target table:
+Target attribute:
+```
+### Tabular rows
+
+The `.rows` property lists all rows. There are 9 `TabularRow` objects shown, which corresponds with the size printed
+by the tabular attribute `__repr__`.
+
+
+```python
+tabular_attribute.rows
+```
+
+
+
+*Previous cell output:*
+```output
+(,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ )
+```
+
+
+Each individual tabular row `__repr__` contains the linking value and the row ID.
+
+
+```python
+for row in tabular_attribute.rows:
+ print(row.linking_value)
+```
+*Previous cell output:*
+```output
+L13L12AA1T
+L13L12AA3T
+L13L12AA5T
+L13L12AA7T
+L13L12AA9T
+L13L12AA11T
+L13L12AA13T
+L13L12AA15T
+L13L12AA17T
+```
+The linked records themselves are available by accessing the `AttributeTabular.linked_records` property. This returns
+a dictionary mapping the linking value to the list of resolved records in the target table. Each row has a single
+linking value, but in general a linking value may match zero or more records. In this example, each linking value
+matches one record.
+
+
+```python
+tabular_attribute.linked_records
+```
+
+
+
+*Previous cell output:*
+```output
+{'L13L12AA1T': [],
+ 'L13L12AA3T': [],
+ 'L13L12AA5T': [],
+ 'L13L12AA7T': [],
+ 'L13L12AA9T': [],
+ 'L13L12AA11T': [],
+ 'L13L12AA13T': [],
+ 'L13L12AA15T': [],
+ 'L13L12AA17T': []}
+```
+
+
+### Tabular cells
+
+The cells are available as a tuple of cell values via the `.cells` property, or by their column name via the
+`.cells_by_column` property.
+
+
+```python
+row = tabular_attribute.rows[0]
+
+row.cells
+```
+
+
+
+*Previous cell output:*
+```output
+((ShortTextValue(value="L13L12AA1T"),),
+ (),
+ (),
+ (),
+ (),
+ (),
+ (),
+ (PointValue(value=126.73, unit="MPa"),))
+```
+
+
+
+```python
+row.cells_by_column
+```
+
+
+
+*Previous cell output:*
+```output
+mappingproxy({'Specimen ID': (ShortTextValue(value="L13L12AA1T"),),
+ 'Date Test Performed': (),
+ 'Strain rate is equivalent': (),
+ 'Control mode': (),
+ 'Test Temperature': (),
+ "Young's Modulus (11-axis)": (),
+ '0.02% Offset yield stress': (),
+ '0.2% Offset yield stress': (PointValue(value=126.73, unit="MPa"),)})
+```
+
+
+Each cell in a linked tabular column is represented as a tuple of value objects. This is because each tabular row may
+link to zero or more records, and the target attribute may or may not be populated for each record.
+
+Tabular cell classes have similar interfaces to their attribute value counterparts. For example, all tabular cell
+classes have a `.value` property, and picture and file tabular cell classes have a `.save()` method.
+
+Linked tabular cell value objects differ from their local tabular cell value equivalents in that they are read-only.
+Local tabular cell values are shown in the local tabular data example referenced in the introduction.
+
+Short text cells have a `.value` property:
+
+
+```python
+row.cells_by_column["Specimen ID"][0].value
+```
+
+
+
+*Previous cell output:*
+```output
+'L13L12AA1T'
+```
+
+
+Attempting to modify the value of a linked tabular cell value raises an `AttributeError`:
+
+
+```python
+try:
+ row.cells_by_column["Specimen ID"][0].value = "New specimen ID"
+except AttributeError as e:
+ print(f'Raised AttributeError: "{e}"')
+```
+*Previous cell output:*
+```output
+Raised AttributeError: "property 'value' of 'ShortTextValue' object has no setter"
+```
+Point cells have a `.value` and a `.unit` property:
+
+
+```python
+point_cell = row.cells_by_column["0.2% Offset yield stress"]
+point_value = point_cell[0]
+
+print(f"{point_value.value} {point_value.unit}")
+```
+*Previous cell output:*
+```output
+126.73 MPa
+```
+Empty linked cells are represented as an empty tuple.
+
+
+```python
+row.cells_by_column["Strain rate is equivalent"]
+```
+
+
+
+*Previous cell output:*
+```output
+()
+```
+
+
+## Add a linked row
+
+The `.append_row()` method accepts an optional argument to specify a linking value. The cell below creates a row which
+link to all records in the target table with the value `L14L12HIP1T` in the target attribute.
+
+
+```python
+tabular_attribute.append_row(linking_value="L14L12HIP1T")
+```
+
+The new row's `__repr__` shows the linking value.
+
+
+```python
+new_linked_row = tabular_attribute.rows[-1]
+new_linked_row
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+However, the row does not contain any linked data until the row is imported and the tabular attribute is refreshed.
+
+
+```python
+new_linked_row.cells_by_column
+```
+
+
+
+*Previous cell output:*
+```output
+mappingproxy({'Specimen ID': (),
+ 'Date Test Performed': (),
+ 'Strain rate is equivalent': (),
+ 'Control mode': (),
+ 'Test Temperature': (),
+ "Young's Modulus (11-axis)": (),
+ '0.02% Offset yield stress': (),
+ '0.2% Offset yield stress': ()})
+```
+
+
+Write the changes to the server.
+
+
+```python
+record.set_attributes([tabular_attribute])
+record = mi.update([record])[0]
+```
+
+Check the content of the tabular attribute after the update. The linked row now contains values in the populated
+linked columns.
+
+
+```python
+tabular_attribute = record.attributes["Tensile test data used in this rollup"]
+refreshed_linked_row = tabular_attribute.rows[-1]
+refreshed_linked_row.cells_by_column
+```
+
+
+
+*Previous cell output:*
+```output
+mappingproxy({'Specimen ID': (ShortTextValue(value="L14L12HIP1T"),),
+ 'Date Test Performed': (),
+ 'Strain rate is equivalent': (),
+ 'Control mode': (),
+ 'Test Temperature': (),
+ "Young's Modulus (11-axis)": (),
+ '0.02% Offset yield stress': (),
+ '0.2% Offset yield stress': (PointValue(value=121.315, unit="MPa"),)})
+```
+
+
+## Add a local row
+
+The `.append_row()` `linking_value` argument is optional. The cell below creates a local row, which will not contain
+any linked data.
+
+
+```python
+tabular_attribute.append_row()
+```
+
+The new row's `__repr__` shows the lack of linking value.
+
+
+```python
+new_local_row = tabular_attribute.rows[-1]
+new_local_row
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+Write the changes to the server.
+
+
+```python
+record.set_attributes([tabular_attribute])
+record = mi.update([record])[0]
+```
+
+Check the content of the tabular attribute after the update. This row is not linked and there are no local columns in
+the tabular attribute, so all cells are empty.
+
+
+```python
+tabular_attribute = record.attributes["Tensile test data used in this rollup"]
+refreshed_local_row = tabular_attribute.rows[-1]
+refreshed_local_row.cells_by_column
+```
+
+
+
+*Previous cell output:*
+```output
+mappingproxy({'Specimen ID': (),
+ 'Date Test Performed': (),
+ 'Strain rate is equivalent': (),
+ 'Control mode': (),
+ 'Test Temperature': (),
+ "Young's Modulus (11-axis)": (),
+ '0.02% Offset yield stress': (),
+ '0.2% Offset yield stress': ()})
+```
+
+
+## Delete rows
+
+Delete rows by specifying the row index to delete.
+
+Use the length of the `.rows` tuple to get the number of rows, and delete the last two.
+
+
+```python
+number_of_rows = len(tabular_attribute.rows)
+tabular_attribute.delete_row(number_of_rows - 1)
+tabular_attribute.delete_row(number_of_rows - 2)
+tabular_attribute.rows
+```
+
+
+
+*Previous cell output:*
+```output
+(,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ )
+```
+
+
+Write the changes to the server, and check the content of the tabular attribute after the update.
+
+
+```python
+record.set_attributes([tabular_attribute])
+record = mi.update([record])[0]
+
+tabular_attribute = record.attributes["Tensile test data used in this rollup"]
+tabular_attribute.rows
+```
+
+
+
+*Previous cell output:*
+```output
+(,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ )
+```
+
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/10_Edit_Pseudo-attributes.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/13_Edit_Pseudo-attributes.md
similarity index 87%
rename from 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/10_Edit_Pseudo-attributes.md
rename to 2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/13_Edit_Pseudo-attributes.md
index 3cc1cee027..60ceefd801 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/10_Edit_Pseudo-attributes.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/13_Edit_Pseudo-attributes.md
@@ -1,17 +1,18 @@
-# Edit Pseudo-attributes
-This example illustrates how to view the pseudo-attributes values (also known as record properties)
-and how to modify the value of an editable pseudo-attribute.
+# Pseudo-attributes
+
+Work with pseudo-attributes values (also known as record properties) and how to modify the value of an editable
+pseudo-attribute.
## Connect to MI
Specify a database and table.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
-tab = db.get_table("Training Exercise for Import")
+table = db.get_table("Training Exercise for Import")
```
## Find a record and view its pseudo-attributes
@@ -19,8 +20,8 @@ Search for a record (use the first result returned).
```python
-recs = tab.search_for_records_by_name("Ti")
-record = recs[0]
+records = table.search_for_records_by_name("Ti")
+record = records[0]
record
```
@@ -108,13 +109,14 @@ Write your changes to MI (pseudo-attributes do not need to be flagged for update
```python
-mi.update([record])
+record = mi.update([record])[0]
+record
```
*Previous cell output:*
```output
-[]
+
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/14_Create_and_Edit_Tabular_Data.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/14_Create_and_Edit_Tabular_Data.md
deleted file mode 100644
index 3ef6770643..0000000000
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/14_Create_and_Edit_Tabular_Data.md
+++ /dev/null
@@ -1,293 +0,0 @@
-# Create and Edit Tabular Data
-Create a new tabular attribute, add, delete and swap rows, and edit the units.
-
-## Create a new record
-Connect to MI and specify a database and table.
-
-
-```python
-from datetime import datetime
-from GRANTA_MIScriptingToolkit import granta as mpy
-
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
-db = mi.get_db(db_key="MI_Training")
-tab = db.get_table("Tensile Test Data")
-```
-
-Create a new record.
-
-
-```python
-now = datetime.now().strftime("%c")
-recordName = f"Scripting Toolkit Example 14:{now}"
-rec = tab.create_record(recordName, subsets={"In Progress"})
-```
-
-## Access a Tabular attribute
-Access the (empty) Tabular attribute *Workflow history*.
-
-
-```python
-history = rec.attributes["Workflow history"]
-history
-```
-
-
-
-*Previous cell output:*
-```output
-
-```
-
-
-Inspect the tabular datum. Using the method `show()` shows the table in ASCII format.
-
-
-```python
-history.show()
-```
-*Previous cell output:*
-```output
- User | Date | Comments | Linking Value (None)
----------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------
-```
-Look at the `__repr__` of the attribute. There are currently no rows in the table.
-
-
-```python
-history
-```
-
-
-
-*Previous cell output:*
-```output
-
-```
-
-
-Tabular attributes can be loaded with the `load()` method (there is no data to load in this example):
-
-
-```python
-history.load()
-```
-
-## Add rows and data
-
-Add three (empty) rows to the Tabular object, and view the table in an ACSII-style format.
-
-
-```python
-history.add_row()
-history.add_row()
-history.add_row()
-history.show()
-```
-*Previous cell output:*
-```output
- User | Date | Comments | Linking Value (None)
----------------------------------------------------------------------------------------------------------------------------------
- None | None | None | ''
- None | None | None | ''
- None | None | None | ''
----------------------------------------------------------------------------------------------------------------------------------
-```
-Data is added by accessing the `tabular` property. The column name should be provided as a string followed by the
-index of the row. Start by populating the first row:
-
-
-```python
-history["User", 0] = "Your username"
-history["Date", 0] = "2019-01-01" # dates should always be provided in the format YYY-MM-DD
-history["Comments", 0] = "This is an example comment"
-history.value[:][0]
-```
-
-
-
-*Previous cell output:*
-```output
-['Your username',
- '2019-01-01',
- 'This is an example comment',
- '']
-```
-
-
-Populate the second row:
-
-
-```python
-history["User", 1] = "Another username"
-history["Date", 1] = "2019-01-02"
-history["Comments", 1] = "This is another example comment"
-history.value[:][1]
-```
-
-
-
-*Previous cell output:*
-```output
-['Another username',
- '2019-01-02',
- 'This is another example comment',
- '']
-```
-
-
-Then populate the third row. The data is stored locally, so the linking values are displayed as ``.
-
-
-```python
-history["User", 2] = "Another username"
-history["Date", 2] = "2019-01-02"
-history["Comments", 2] = "This is another example comment"
-history.value[:][2]
-```
-
-
-
-*Previous cell output:*
-```output
-['Another username',
- '2019-01-02',
- 'This is another example comment',
- '']
-```
-
-
-
-```python
-history.show()
-history.value
-```
-*Previous cell output:*
-```output
- User | Date | Comments | Linking Value (None)
----------------------------------------------------------------------------------------------------------------------------------
- 'Your username' | '2019-01-01' | 'This is an example comment' | ''
- 'Another username' | '2019-01-02' | 'This is another example c...' | ''
- 'Another username' | '2019-01-02' | 'This is another example c...' | ''
----------------------------------------------------------------------------------------------------------------------------------
-```
-
-
-*Previous cell output:*
-```output
-[['Your username',
- '2019-01-01',
- 'This is an example comment',
- ''],
- ['Another username',
- '2019-01-02',
- 'This is another example comment',
- ''],
- ['Another username',
- '2019-01-02',
- 'This is another example comment',
- '']]
-```
-
-
-## Edit the table
-Rows can be moved using the `swap_rows()` method.
-
-
-```python
-history.value[:][:2]
-```
-
-
-
-*Previous cell output:*
-```output
-[['Your username',
- '2019-01-01',
- 'This is an example comment',
- ''],
- ['Another username',
- '2019-01-02',
- 'This is another example comment',
- '']]
-```
-
-
-
-```python
-history.swap_rows(0, 1)
-```
-
-
-```python
-history.value[:][:2]
-```
-
-
-
-*Previous cell output:*
-```output
-[['Another username',
- '2019-01-02',
- 'This is another example comment',
- ''],
- ['Your username',
- '2019-01-01',
- 'This is an example comment',
- '']]
-```
-
-
-Rows can also be deleted; for example, one of the two duplicate rows in this table.
-
-
-```python
-history.delete_row(0)
-```
-
-## Access the units
-Each **Tabular** object is associated with a **TabularUnits** object which stores the units for the Tabular data. View
-(and edit) these units through the `tabular.units` property.
-
-
-```python
-history.units
-```
-
-
-
-*Previous cell output:*
-```output
-
-```
-
-
-Access the complete set of units for the tabular datum
-
-
-```python
-history.units.data
-```
-
-
-
-*Previous cell output:*
-```output
-[['', '', '', None], ['', '', '', None]]
-```
-
-
-## Write your changes to MI
-Set your new attribute to update, and write the changes to the server.
-
-
-```python
-rec.set_attributes([history])
-rec = mi.update([rec])[0]
-```
-
-## Notes about Tabular data:
- * Point-type values in Tabular cannot have parameters, and are always lists.
- * Any changes to linked data will be ignored on import.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/14_Data_with_Precision.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/14_Data_with_Precision.md
new file mode 100644
index 0000000000..7d2ef6c1bc
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/14_Data_with_Precision.md
@@ -0,0 +1,221 @@
+# Data with Precision
+
+Import numeric data with explicitly-specified precision information by specifying the number of significant figures.
+
+For example: the temperature during a test is measured using a thermocouple with an accuracy of 0.1 °C for
+measurements below 100 °C.
+Measures for multiple tests might be in the form: 90.6 °C, 90.0 °C, 89.9 °C. The trailing zeros in `90.0`
+are significant.
+
+Floating-point numbers in Python cannot provide exact decimal representation, so additional information is required to
+specify the precision of a floating-point value before importing it into Granta MI. This example illustrates how
+significant figures can be set when importing point and range attribute values, as well as how that information is
+represented when exporting attribute values which have significant figures information.
+
+## Connect to MI
+Get a database and table.
+
+
+```python
+from datetime import datetime
+import ansys.grantami.core as mpy
+
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
+
+db = mi.get_db(db_key="MI_Training")
+db.unit_system = "Metric"
+db.absolute_temperatures = False
+
+table = db.get_table("Composite Design Data")
+```
+
+## Create a new record
+Create a new ``Record`` object.
+
+
+```python
+now = datetime.now().strftime("%c")
+record_name = f"Scripting Toolkit Example 13:{now}"
+record = table.create_record(name=record_name)
+record
+```
+
+
+
+*Previous cell output:*
+```output
+
+```
+
+
+## Edit the record's attributes
+### Values with precision
+To add precision information to a floating-point value, use the ``ValueWithPrecision`` class. To simplify the import
+of values with similar resolution but different exponents, specifying significant digits is done by
+specifying a number of digits after the decimal point.
+
+
+```python
+temperature_value = mpy.ValueWithPrecision(value=90, number_of_digits=1)
+print("Decimal representation:", temperature_value.as_decimal)
+print("MI Significant figures:", temperature_value.significant_figures)
+```
+*Previous cell output:*
+```output
+Decimal representation: 90.0
+MI Significant figures: 3
+```
+### Point attributes
+To set significant figures on a single-valued point attribute, set the attribute ``.value`` property to an instance of
+``ValueWithPrecision``.
+
+
+```python
+test_temperature = record.attributes["Test temperature"]
+test_temperature.value = temperature_value
+test_temperature.unit = "°C"
+test_temperature.value.as_decimal
+```
+
+
+
+*Previous cell output:*
+```output
+Decimal('90.0')
+```
+
+
+To set significant figures on a multi-valued point attribute and assign parameter values, set the ``.value`` property
+to a tuple of ``ParameterizedPointValue`` with ``ValueWithPrecision`` values.
+
+
+```python
+modulus = record.attributes["0° tension modulus - measured"]
+modulus.unit = "GPa"
+modulus.value = (
+ mpy.ParameterizedPointValue(
+ value=mpy.ValueWithPrecision(value=40.7, number_of_digits=2),
+ parameters=(
+ mpy.PointParameterValue("Basis", "Mean"),
+ )
+ ),
+ mpy.ParameterizedPointValue(
+ value=mpy.ValueWithPrecision(value=41.46, number_of_digits=2),
+ parameters=(
+ mpy.PointParameterValue("Basis", "A-basis"),
+ )
+ )
+)
+```
+
+### Range attributes
+Set the ``.value`` property to a ``Range`` object, providing high and low values with precision.
+
+
+```python
+resin_content = record.attributes["Resin content"]
+fiber_volume = record.attributes["Fiber volume"]
+
+resin_content.value = mpy.Range(mpy.ValueWithPrecision(28, 0), mpy.ValueWithPrecision(30, 0))
+resin_content.unit = "wt%"
+
+fiber_volume.value = mpy.Range(
+ low=None,
+ high=mpy.ValueWithPrecision(62.0, 1),
+ high_value_is_inclusive=False
+)
+fiber_volume.unit = "%"
+```
+
+## Write your changes to MI
+First, specify the attributes on the record which you want to update on the server. Then write the changes to MI.
+The list of updated ``Record`` objects is returned.
+
+
+```python
+record.set_attributes([resin_content, test_temperature, fiber_volume, modulus])
+record = mi.update([record])[0]
+```
+
+## Output the record's attributes
+Access the attribute values via the same properties you used to assign them. Significant figures information is
+available via the ``.trailing_zero_information`` property.
+
+The test temperature has been stored with 1 digit of precision. The trailing zero information includes the entered
+value, the entered unit, as well as the number of significant figures stored with the value. The additional properties
+``as_decimal`` and ``number_of_digits`` help convert the information back to a more accessible representations:
+
+
+```python
+test_temperature = record.attributes["Test temperature"]
+print(f"Test temperature value: {test_temperature.value} {test_temperature.unit}")
+print("Test temperature precision information:", test_temperature.trailing_zero_information)
+print("Decimal representation:", test_temperature.trailing_zero_information.as_decimal)
+print("Number of digits:", test_temperature.trailing_zero_information.number_of_digits)
+```
+*Previous cell output:*
+```output
+Test temperature value: 90.0 °C
+Test temperature precision information: TrailingZeroInformation('90', '°C', 3)
+Decimal representation: 90.0
+Number of digits: 1
+```
+
+```python
+modulus = record.attributes["0° tension modulus - measured"]
+formatted_points = ", ".join([
+ f"{point.as_decimal} {modulus.unit} ({modulus.value[idx].parameters_by_name['Basis']})"
+ for idx, point in enumerate(modulus.trailing_zero_information)
+])
+print("0° tension modulus:", formatted_points)
+```
+*Previous cell output:*
+```output
+0° tension modulus: 40.70 GPa (Mean), 41.46 GPa (A-basis)
+```
+Define a function to format ranges as strings with the appropriate inclusive or exclusive inequality
+symbols and at the stored precision.
+
+
+```python
+def format_range_with_significant_figures(range_value):
+ low_value = range_value.value.low
+ if range_value.low_value_trailing_zero_information:
+ low_value = range_value.low_value_trailing_zero_information.as_decimal
+ if low_value is not None:
+ low_inequality = "≤" if range_value.low_value_is_inclusive else "<"
+ else:
+ low_inequality = ""
+ low_range = f"{low_value} {low_inequality}" if low_value else ""
+
+ high_value = range_value.value.high
+ if range_value.high_value_trailing_zero_information:
+ high_value = range_value.high_value_trailing_zero_information.as_decimal
+ if high_value is not None:
+ high_inequality = "≤" if range_value.high_value_is_inclusive else "<"
+ else:
+ high_inequality = ""
+ high_range = f"{high_inequality} {high_value}" if high_value else ""
+
+ unit_symbol = range_value.unit
+ return f"{low_range} x {high_range} {unit_symbol}".strip()
+```
+
+
+```python
+resin_content = record.attributes["Resin content"]
+print(format_range_with_significant_figures(resin_content))
+```
+*Previous cell output:*
+```output
+28 ≤ x ≤ 30 wt%
+```
+
+```python
+fiber_volume = record.attributes["Fiber volume"]
+print(format_range_with_significant_figures(fiber_volume))
+```
+*Previous cell output:*
+```output
+x < 62.0 %
+```
\ No newline at end of file
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/15_Use_Exporters_for_FEA_Export.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/15_Use_Exporters_for_FEA_Export.md
index f0cc22ce7f..db7bd958d9 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/15_Use_Exporters_for_FEA_Export.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/15_Use_Exporters_for_FEA_Export.md
@@ -6,9 +6,9 @@ Check which exporters are available for a specific table.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
table = db.get_table("Design Data")
@@ -23,17 +23,17 @@ for exporter in exporters_in_table:
Output of available ANSYS Workbench Exporters
458E9A7E-C268-4ED0-9CC1-FF7438521B4F (ANSYS Workbench) - Exports linear, temperature-independent, isotropic data to the Ansys Workbench format
-CE8DCFA2-B3EE-4545-8D3E-82810FA92AFC (ANSYS Workbench) - Exports linear, temperature-dependent, isotropic data to the Ansys Workbench format
4B0B1EA3-8760-43DF-8060-2C79CA471D4C (ANSYS Workbench) - Exports linear, temperature-independent, isotropic with simple failure data to the Ansys Workbench format
+CE8DCFA2-B3EE-4545-8D3E-82810FA92AFC (ANSYS Workbench) - Exports linear, temperature-dependent, isotropic data to the Ansys Workbench format
```
Check which exporters are applicable to a specific record.
```python
-rec = table.search_for_records_by_name(
+record = table.search_for_records_by_name(
"250 Grade Maraging, Maraged at 900F, Plate, Thickness: 0.1875 to 0.251 in, AMS 6520, S basis"
)[0]
-applicable_exporters = rec.get_available_exporters()
+applicable_exporters = record.get_available_exporters()
print("\nOutput of exporters for 250 Grade Maraging steel:")
for exporter in applicable_exporters:
@@ -43,15 +43,15 @@ for exporter in applicable_exporters:
```output
Output of exporters for 250 Grade Maraging steel:
-71CE1C21-FDEA-4119-B481-81BDC41BD900 (Abaqus 6) - Exports temperature dependent, isotropic data to the Abaqus format.
-5C560880-4FD3-4E5C-992B-4B6CEF6A055A (Abaqus 6) - Exports temperature independent, isotropic data to the Abaqus 6 format.
-911AF055-B388-439A-8AF6-EB18480E2D80 (Abaqus 6) - Linear, temperature-independent, isotropic, simple failure
3AE2BEA5-B1DB-45D3-A431-48915B8D1317 (Abaqus 6) - Linear, temperature-independent, isotropic, simple failure with thermal expansion
-722E5C46-3633-4B72-BF93-74E8112C20C3 (Abaqus 6) - Exports temperature dependent, isotropic data to the Abaqus 6 format.
B653C213-8BEB-42A7-8512-5F340EEBFAB4 (Abaqus 6) - Exports temperature independent, isotropic data to the Abaqus 6 format.
458E9A7E-C268-4ED0-9CC1-FF7438521B4F (ANSYS Workbench) - Exports linear, temperature-independent, isotropic data to the Ansys Workbench format
-CE8DCFA2-B3EE-4545-8D3E-82810FA92AFC (ANSYS Workbench) - Exports linear, temperature-dependent, isotropic data to the Ansys Workbench format
+71CE1C21-FDEA-4119-B481-81BDC41BD900 (Abaqus 6) - Exports temperature dependent, isotropic data to the Abaqus format.
+911AF055-B388-439A-8AF6-EB18480E2D80 (Abaqus 6) - Linear, temperature-independent, isotropic, simple failure
4B0B1EA3-8760-43DF-8060-2C79CA471D4C (ANSYS Workbench) - Exports linear, temperature-independent, isotropic with simple failure data to the Ansys Workbench format
+722E5C46-3633-4B72-BF93-74E8112C20C3 (Abaqus 6) - Exports temperature dependent, isotropic data to the Abaqus 6 format.
+5C560880-4FD3-4E5C-992B-4B6CEF6A055A (Abaqus 6) - Exports temperature independent, isotropic data to the Abaqus 6 format.
+CE8DCFA2-B3EE-4545-8D3E-82810FA92AFC (ANSYS Workbench) - Exports linear, temperature-dependent, isotropic data to the Ansys Workbench format
```
## Working with parameters
Some exporters support parameters. The exported parameters have default values but they can also be set manually.
@@ -60,13 +60,13 @@ Get the required parameters for an exporter.
```python
-all_exporters = rec.get_available_exporters(
+all_exporters = record.get_available_exporters(
package="Abaqus 6",
- model="Linear, temperature-dependent, isotropic, thermal, plastic"
+ model="Linear, temperature-dependent, isotropic, thermal, plastic",
)
exporter_to_use = all_exporters[0]
-parameters_required = exporter_to_use.get_parameters_required_for_export([rec])
+parameters_required = exporter_to_use.get_parameters_required_for_export([record])
print(parameters_required)
```
*Previous cell output:*
@@ -83,7 +83,7 @@ parameter_values = {"Time": 100.0}
for parameter_name in parameters_required.keys():
parameters_required[parameter_name].value_for_exporters = parameter_values[parameter_name]
-material_card = exporter_to_use.run_exporter([rec], parameter_defs=parameters_required)
+material_card = exporter_to_use.run_exporter([record], parameter_defs=parameters_required)
print(material_card)
```
*Previous cell output:*
@@ -93,7 +93,7 @@ print(material_card)
**Model Type: Linear, temperature-dependent, isotropic, thermal, plastic
**Unit System: SI (Consistent)
**Export User: ANSYS\mi-sw-admin
-**Export DateTime: 2025-05-12T12:17:04.8602976-04:00
+**Export DateTime: 2026-01-07T14:29:09.7626809-05:00
**Database Name: MI Training
**Table Name: Design Data
**Material Record History Id: 20673
@@ -281,13 +281,16 @@ are left as their defaults.
```python
-path_to_save = "./"
+from pathlib import Path
+
+path_to_save = "./output/"
+Path(path_to_save).mkdir(exist_ok=True)
file_name = "Example_Export"
exporter_to_use.save(path_to_save, file_name="Example_Export")
file_extension = exporter_to_use.default_file_extension
-print(f"Exporter output saved to \"{path_to_save}{file_name}.{file_extension}\"")
+print(f'Exporter output saved to "{path_to_save}{file_name}.{file_extension}"')
```
*Previous cell output:*
```output
-Exporter output saved to "./Example_Export.inp"
+Exporter output saved to "./output/Example_Export.inp"
```
\ No newline at end of file
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/16_Link_Records.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/16_Link_Records.md
index c13c03707b..2d90189050 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/16_Link_Records.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/16_Link_Records.md
@@ -7,11 +7,11 @@ Connect to MI and get a database and table.
```python
from datetime import datetime
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
-tab = db.get_table("Training Exercise for Import")
+table = db.get_table("Training Exercise for Import")
```
Create a new record in the subset *Materials*.
@@ -19,8 +19,8 @@ Create a new record in the subset *Materials*.
```python
now = datetime.now().strftime("%c")
-recordName = f"Scripting Toolkit Example 16:{now}"
-rec = tab.create_record(recordName, subsets={"Materials"})
+record_name = f"Scripting Toolkit Example 15:{now}"
+record = table.create_record(record_name, subsets={"Materials"})
```
## Smart links
@@ -32,17 +32,17 @@ server.
```python
-base = rec.attributes["Base"]
+base = record.attributes["Base"]
base.value = "Oxide"
-rec.set_attributes([base])
-rec = mi.update([rec])[0]
+record.set_attributes([base])
+record = mi.update([record])[0]
```
View the smart links that have just been created to the new record.
```python
-for link_group, records in rec.links.items():
+for link_group, records in record.links.items():
print(f'Link group "{link_group}" contains links to the following records:')
print(", ".join([r.name for r in records]))
```
@@ -51,7 +51,7 @@ for link_group, records in rec.links.items():
Link group "MaterialUniverse" contains links to the following records:
Link group "Smart Link to MaterialUniverse" contains links to the following records:
-Lithium aluminosilicate, Barium silicate, Alumino silicate - 1723, Alumino silicate - 1720, Soda barium glass
+Alumino silicate - 1720, Lithium aluminosilicate, Alumino silicate - 1723, Barium silicate, Soda barium glass
```
## Static links
A static link can be created between two existing records, including cross-database.
@@ -60,30 +60,30 @@ Get a record from *MaterialUniverse* to link to your newly-created record.
```python
-mu_rec = db.get_record_by_id(hguid="bf5e6054-6cad-4c9d-ad7a-adfa124c504b")
+mu_record = db.get_record_by_id(hguid="bf5e6054-6cad-4c9d-ad7a-adfa124c504b")
```
Add the *MaterialUniverse* record to the link group on the new record.
```python
-new_linked_recs = rec.links["MaterialUniverse"]
-new_linked_recs.add(mu_rec)
-rec.set_links(link_name="MaterialUniverse", records=new_linked_recs)
+new_linked_records = record.links["MaterialUniverse"]
+new_linked_records.add(mu_record)
+record.set_links(link_name="MaterialUniverse", records=new_linked_records)
```
Write your changes to MI (use `update_links()` for changes to links, not `update()`).
```python
-rec = mi.update_links([rec])[0]
+record = mi.update_links([record])[0]
```
View your new link on the list of record links.
```python
-for link_group, records in rec.links.items():
+for link_group, records in record.links.items():
print(f'Link group "{link_group}" contains links to the following records:')
print(", ".join([r.name for r in records]))
```
@@ -92,7 +92,7 @@ for link_group, records in rec.links.items():
Link group "MaterialUniverse" contains links to the following records:
Soda barium glass
Link group "Smart Link to MaterialUniverse" contains links to the following records:
-Lithium aluminosilicate, Alumino silicate - 1723, Soda barium glass, Barium silicate, Alumino silicate - 1720
+Alumino silicate - 1720, Lithium aluminosilicate, Barium silicate, Alumino silicate - 1723, Soda barium glass
```
## Associated Records
Associated Records are a way of traversing tabular links multiple steps at a time. This example finds all materials
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/17_Layouts.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/17_Layouts.md
index c131f0a736..d26795c131 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/17_Layouts.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/17_Layouts.md
@@ -6,8 +6,9 @@ This notebook shows how to access layouts through the Streamlined API.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
-mi = mpy.connect("http://my.server.name/mi_servicelayer", autologon=True)
+import ansys.grantami.core as mpy
+
+mi = mpy.SessionBuilder("http://my.server.name/mi_servicelayer").with_autologon()
db = mi.get_db(db_key="MI_Training")
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/18_Record_Lists_Interoperability.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/18_Record_Lists_Interoperability.md
index 92c991b29f..c7d8f43121 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/18_Record_Lists_Interoperability.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/18_Record_Lists_Interoperability.md
@@ -33,10 +33,10 @@ First create an MI Scripting Toolkit session.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
SERVICE_LAYER_URL = "http://my.server.name/mi_servicelayer"
-mi = mpy.connect(SERVICE_LAYER_URL, autologon=True)
+mi = mpy.SessionBuilder(SERVICE_LAYER_URL).with_autologon()
```
Search for all *MaterialUniverse* records with a density above a certain threshold. The
@@ -49,8 +49,8 @@ db.unit_system = "SI (Consistent)"
material_universe = db.get_table("MaterialUniverse")
criterion = material_universe.attributes["Density"].search_criterion(greater_than=7000.0)
-results = material_universe.search_for_records_where([criterion])
-results
+material_universe_results = material_universe.search_for_records_where([criterion])
+material_universe_results
```
@@ -97,7 +97,7 @@ items = [
table_guid=record.table.guid,
record_history_guid=record.history_guid,
)
- for record in results
+ for record in material_universe_results
]
```
@@ -196,7 +196,7 @@ Search for all *Design Data* records with a density above a certain threshold.
design_data = db.get_table("Design Data")
criterion = design_data.attributes["Density"].search_criterion(greater_than=7000.0)
-results = design_data.search_for_records_where([criterion])
+design_data_results = design_data.search_for_records_where([criterion])
```
Since the *Design Data* table is version-controlled, each `Record` object represents a particular
@@ -205,8 +205,8 @@ property.
```python
-for r in results:
- print(f"'{r.name}'", ", version: ", r.version_number)
+for r in design_data_results:
+ print(f"'{r.name}'", ", version: ", r.version_number)
```
*Previous cell output:*
```output
@@ -228,7 +228,7 @@ version_controlled_items = [
record_history_guid=record.history_guid,
record_version=record.version_number,
)
- for record in results
+ for record in design_data_results
]
record_list_items = api_client.add_items_to_list(record_list, version_controlled_items)
record_list_items
@@ -277,7 +277,7 @@ identifiers = [
{
"db_key": mi.dbs_by_guid[item.database_guid].db_key,
"hguid": item.record_history_guid,
- "vguid": item.record_guid
+ "vguid": item.record_guid,
}
for item in record_list_items
]
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/19_Job_Queue_Interoperability.md b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/19_Job_Queue_Interoperability.md
index b281b669a0..24c6513901 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/19_Job_Queue_Interoperability.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/samples/streamlined/19_Job_Queue_Interoperability.md
@@ -27,10 +27,10 @@ First create an MI Scripting Toolkit session.
```python
-from GRANTA_MIScriptingToolkit import granta as mpy
+import ansys.grantami.core as mpy
SERVICE_LAYER_URL = "http://my.server.name/mi_servicelayer"
-mi = mpy.connect(SERVICE_LAYER_URL, autologon=True)
+mi = mpy.SessionBuilder(SERVICE_LAYER_URL).with_autologon()
```
Next, access all records in a specific tree location. We will need the database key later, so
@@ -43,8 +43,7 @@ db = mi.get_db(db_key=DB_KEY)
tensile_test_data = db.get_table("Tensile Test Data")
records = tensile_test_data.get_records_from_path(
- starting_node=None,
- tree_path=["High Alloy Steels", "AMS 6520", "Plate", "300°F"]
+ starting_node=None, tree_path=["High Alloy Steels", "AMS 6520", "Plate", "300°F"]
)
records
```
@@ -123,7 +122,7 @@ from pathlib import Path
request = ExcelExportJobRequest(
name="Example export",
description="A demonstration of how to export data to Excel using Granta MI JobQueue",
- template_file=Path("supporting_files/23_Export_Template.xlsx"),
+ template_file=Path("supporting_files/18_Export_Template.xlsx"),
database_key=DB_KEY,
records=export_records,
)
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/attribute-definitions.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/attribute-definitions.md
new file mode 100644
index 0000000000..37a8fdf6eb
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/attribute-definitions.md
@@ -0,0 +1,826 @@
+# Attribute definitions
+
+
+
+
+
+
+
+### *class* PseudoAttributeDefinition
+
+Stores basic information about a pseudo-attribute.
+
+* **Parameters:**
+ **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Name of the pseudo-attribute.
+
+### Notes
+
+Supported names are:
+
+* `recordType`
+* `recordHistoryIdentity`
+* `recordColor`
+* `recordVersionNumber`
+* `tableName`
+* `writable`
+* `parentShortName`
+* `parentName`
+* `parentRecordHistoryIdentity`
+* `shortName`
+* `modifiedDate`
+* `createdDate`
+* `releasedDate`
+* `lastModifier`
+* `creator`
+* `subsets`
+* `name`
+
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the name is not a recognized pseudo-attribute name.
+
+
+
+#### *property* id *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Attribute identifier.
+
+Always 0 for pseudo-attributes.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the pseudo-attribute.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* read_only *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the current user has the correct permissions to edit the attribute.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* type *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Data type of the pseudo-attribute (four-character string).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+### *class* AttributeDefinition
+
+Base attribute definition class.
+
+Stores basic information about an attribute, such as data type or possible values. Contains information about
+the attribute itself, not the data. Cannot be used to set attribute values.
+
+### Notes
+
+Do not create instances of this class, it represents an abstract database structure.
+
+
+
+#### search_criterion(less_than=None, greater_than=None, contains=None, contains_any=None, contains_all=None, does_not_contain=None, exists=None, equal_to=None, between_dates=None, in_column=None)
+
+Creates a search criterion for use with [`Table.search_for_records_where()`](table.md#ansys.grantami.core.mi_tree_classes.Table.search_for_records_where) or
+[`Database.search_for_records_where()`](database.md#ansys.grantami.core.mi_tree_classes.Database.search_for_records_where).
+
+Operator priority is the same as the order of the arguments.
+
+* **Parameters:**
+ * **less_than** ([*float*](https://docs.python.org/3/library/functions.html#float) *,* *optional*) – Search for values less than this.
+ * **greater_than** ([*float*](https://docs.python.org/3/library/functions.html#float) *,* *optional*) – Search for values greater than this.
+ * **contains** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Search for values containing this.
+ * **contains_any** ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]* *,* *optional*) – Search for values containing any of these.
+ * **contains_all** ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]* *,* *optional*) – Search for values containing all of these.
+ * **does_not_contain** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Search for values not containing this.
+ * **exists** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Search for existence of attribute values.
+ * **equal_to** ([*int*](https://docs.python.org/3/library/functions.html#int) *or* [*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Search for values equal to this.
+ * **between_dates** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*datetime.date*](https://docs.python.org/3/library/datetime.html#datetime.date) *,* [*datetime.date*](https://docs.python.org/3/library/datetime.html#datetime.date) *]* *,* *optional*) – Two dates in chronological order to search between.
+ * **in_column** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Name of tabular column to search.
+* **Return type:**
+ [`SearchCriterion`](supporting.md#ansys.grantami.core.mi_meta_classes.SearchCriterion) or [`None`](https://docs.python.org/3/library/constants.html#None)
+* **Raises:**
+ * [**AssertionError**](https://docs.python.org/3/library/exceptions.html#AssertionError) – If the criterion type is incompatible with the attribute type.
+ * [**AssertionError**](https://docs.python.org/3/library/exceptions.html#AssertionError) – If required parameters are missing.
+
+### Notes
+
+To perform an exact search on a discrete attribute, use either the `contains_any` or `contains_all`
+parameters. In the case of searching for a single discrete value, the argument should be a list containing
+the search term.
+
+
+
+#### *property* history *: [ObjectHistory](supporting.md#ansys.grantami.core.mi_meta_classes.ObjectHistory)*
+
+Revision history of the attribute.
+
+* **Return type:**
+ [`ObjectHistory`](supporting.md#ansys.grantami.core.mi_meta_classes.ObjectHistory)
+
+
+
+#### *property* id *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Attribute identifier.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* is_meta *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the attribute is a meta-attribute or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* is_meta_for *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Parent attribute name.
+
+* **Returns:**
+ Name of the parent attribute, if the attribute is a meta-attribute. Returns [`None`](https://docs.python.org/3/library/constants.html#None) if not a
+ meta-attribute.
+* **Return type:**
+ str or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* meta_attributes *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [AttributeDefinition](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)]*
+
+Meta-attributes associated with this attribute, indexed by name.
+
+* **Return type:**
+ dict[str, [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)]
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Attribute name.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* order *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Display order in MI Viewer.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* table *: [Table](table.md#ansys.grantami.core.mi_tree_classes.Table)*
+
+Parent [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table) the attribute belongs to.
+
+* **Return type:**
+ [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table)
+
+
+
+#### *property* type *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Attribute data type, as a four-character string.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+### Notes
+
+* Numeric attributes: `POIN` (point), `RNGE` (range), `INPT` (integer).
+* Text attributes: `STXT` (short text), `LTXT` (long text), `DISC` (discrete).
+* Functional attributes: `FUNC` (float functional).
+* Media attributes: `HLNK` (hyperlink), `PICT` (picture), `FILE` (file).
+* Other attributes: `LOGI` (logical), `DTTM` (date time), `TABL` (tabular).
+
+`DSFN` (discrete functional) attributes are not fully supported by the MI Scripting Toolkit. Definitions can
+be obtained but attribute values are exported as `UNSUPPORTED DATA TYPE` and contain no data.
+
+`MAFN` (maths functional) attribute definitions cannot be obtained via the MI Scripting Toolkit.
+
+
+
+### *class* AttributeDefinitionDate
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for date attributes.
+
+Provides properties to view the table-wide minimum and maximum values for this attribute.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+#### *property* max *: [date](https://docs.python.org/3/library/datetime.html#datetime.date) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Maximum value of the data attribute.
+
+Affected by user read permissions.
+
+* **Return type:**
+ datetime.date or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* min *: [date](https://docs.python.org/3/library/datetime.html#datetime.date) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Minimum value of the data attribute.
+
+Affected by user read permissions.
+
+* **Return type:**
+ datetime.date or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+### *class* AttributeDefinitionDiscrete
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for discrete attributes.
+
+Provides a method to view the possible discrete values of an attribute.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+#### *property* discrete_values *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+All possible discrete values of the attribute, in the order defined by the associated discrete type.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* is_multivalued *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether this attribute allows multiple values to be set.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* is_ordered *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the discrete type associated with the discrete attribute is ordered.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+### *class* AttributeDefinitionFile
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for file attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+### *class* AttributeDefinitionHyperlink
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for hyperlink attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+### *class* AttributeDefinitionInteger
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for integer attributes.
+
+Provides properties to view the table-wide minimum and maximum values for this attribute.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+#### *property* is_unique *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether this attribute is defined as unique.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* max *: [int](https://docs.python.org/3/library/functions.html#int) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Maximum value of the data attribute.
+
+Affected by user read permissions.
+
+* **Return type:**
+ int or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* min *: [int](https://docs.python.org/3/library/functions.html#int) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Minimum value of the data attribute.
+
+Affected by user read permissions.
+
+* **Return type:**
+ int or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+### *class* AttributeDefinitionLogical
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for logical attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+### *class* AttributeDefinitionLongText
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for long text attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+### *class* AttributeDefinitionPicture
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for picture attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+### *class* AttributeDefinitionRange
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for range attributes.
+
+Provides access to range-specific information and methods.
+
+
+
+#### *property* database_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The database unit for this attribute.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* default_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Attribute database unit in the active unit system.
+
+The unit used by MI Viewer or MI Explore to display this attribute in the active unit system. This
+property is only affected by the unit system choice, and is not affected by [`Table.set_display_unit()`](table.md#ansys.grantami.core.mi_tree_classes.Table.set_display_unit).
+
+* **Returns:**
+ [`None`](https://docs.python.org/3/library/constants.html#None) if the attribute is dimensionless.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* max *: [float](https://docs.python.org/3/library/functions.html#float) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Maximum value of the data attribute.
+
+Affected by user read permissions.
+
+* **Return type:**
+ float or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* min *: [float](https://docs.python.org/3/library/functions.html#float) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Minimum value of the data attribute.
+
+Affected by user read permissions.
+
+* **Return type:**
+ float or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+### *class* AttributeDefinitionShortText
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for short text attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+#### *property* is_unique *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether this attribute is defined as unique.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+### *class* AttributeDefinitionTabular
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for tabular data attributes.
+
+Provides access to tabular-specific information and methods, such as columns, linking attribute and
+cross-table links.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+#### *property* column_database_units *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)]*
+
+Database unit symbols for each column.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) | None]
+
+
+
+#### *property* column_histories *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[ObjectHistory](supporting.md#ansys.grantami.core.mi_meta_classes.ObjectHistory) | [None](https://docs.python.org/3/library/constants.html#None)]*
+
+The revision histories of each column.
+
+* **Returns:**
+ List of equal length to the number of columns. Each item is either an object history, or [`None`](https://docs.python.org/3/library/constants.html#None) for
+ unavailable columns. Use [`column_targets`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionTabular.column_targets) to identify unavailable columns.
+* **Return type:**
+ list[[`ObjectHistory`](supporting.md#ansys.grantami.core.mi_meta_classes.ObjectHistory) or [`None`](https://docs.python.org/3/library/constants.html#None)]
+
+
+
+#### *property* column_targets *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+Column meta-types.
+
+Possible column targets are:
+
+* `Local`: Contains local data..
+* `TargetAttribute`: Contains data from a linked attribute.
+* `TargetRecord`: Contains the records that the rows link to.
+* `TargetTabularColumn`: Contains data from a linked tabular column.
+* `Unavailable`: Data cannot be viewed, usually due to version control or permissions.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* column_types *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)]*
+
+Data type for each column.
+
+* **Returns:**
+ List of equal length to the number of columns. Each item is one of a type codes for local tabular columns,
+ an empty string for linked columns, or [`None`](https://docs.python.org/3/library/constants.html#None) for unavailable columns. Use [`column_targets`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionTabular.column_targets) to
+ identify unavailable columns.
+* **Return type:**
+ list[str or [`None`](https://docs.python.org/3/library/constants.html#None)]
+
+### Examples
+
+```pycon
+>>> tabular_attribute.column_types
+['STXT', 'POIN', 'DISC', '', '']
+```
+
+#### SEE ALSO
+[`AttributeDefinition.type`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition.type)
+: List of type codes.
+
+
+
+#### *property* column_units *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)]*
+
+Unit symbols for each column.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) | None]
+
+
+
+#### *property* columns *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+Column names (headers).
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* columns_to_process *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+Columns to be included when populating an AttributeTabular object.
+
+Defaults to all columns, which will fully populate the AttributeTabular object. The content of unprocessed
+columns depends on the column type:
+
+* Ignored linked columns contain the value `` in all cells.
+* Ignored local tabular columns contain instances of [`IgnoredLocalTabularCell`](tabular.md#ansys.grantami.core._mi_tabular_value_classes.IgnoredLocalTabularCell). These objects contain no
+ accessible data, and they cannot be modified.
+
+Ignoring columns that aren’t required by the script can significantly improve performance for operations with
+large amounts of tabular data.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+### Notes
+
+This property must be set on the AttributeDefinitionTabular object associated with the Table object
+*before* data export for the setting to have an effect.
+
+
+
+#### *property* discrete_values *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]]*
+
+All possible discrete values, for all columns with the discrete data type.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]]
+
+
+
+#### *property* ignore_linked_records *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether to ignore linked records when creating Record objects.
+
+Defaults to [`False`](https://docs.python.org/3/library/constants.html#False). Even when set to [`True`](https://docs.python.org/3/library/constants.html#True), linking values are still available if populated.
+
+Ignoring linked records if they aren’t required can significantly improve performance for operations with large
+amounts of tabular data.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+### Notes
+
+This property must be set on the AttributeDefinitionTabular object associated with the Table object
+*before* data export for the setting to have an effect.
+
+
+
+#### *property* linking_attribute *: [None](https://docs.python.org/3/library/constants.html#None) | [AttributeDefinition](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)*
+
+Short text-type attribute used to link rows in the tabular data attribute to records.
+
+* **Returns:**
+ The attribute definition of the linking attribute. Returns [`None`](https://docs.python.org/3/library/constants.html#None) for purely local tabular data or if the
+ user annot access the table in Granta MI.
+* **Return type:**
+ [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* linking_table *: [None](https://docs.python.org/3/library/constants.html#None) | [Table](table.md#ansys.grantami.core.mi_tree_classes.Table)*
+
+[`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table) object which the linking attribute belongs to.
+
+* **Returns:**
+ The table object that the tabular attribute is linked to. Returns [`None`](https://docs.python.org/3/library/constants.html#None) for purely local tabular data or
+ if the user cannot access the table in Granta MI.
+* **Return type:**
+ [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table) or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+### *class* AttributeDefinitionMultiValue
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for functional and point data attributes.
+
+Provides access to functional data parameters.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+#### *property* parameters *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [AttributeParameter](supporting.md#ansys.grantami.core.mi_attribute_classes.AttributeParameter)]*
+
+Parameters associated with the attribute, indexed by name.
+
+* **Return type:**
+ dict[str, [`AttributeParameter`](supporting.md#ansys.grantami.core.mi_attribute_classes.AttributeParameter)]
+
+
+
+### *class* AttributeDefinitionFloatFunctional
+
+Extended [`AttributeDefinitionMultiValue`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionMultiValue) class for float functional attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+#### *property* axis_name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Y-axis label.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* database_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The database unit for this attribute.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* parameters *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [AttributeParameter](supporting.md#ansys.grantami.core.mi_attribute_classes.AttributeParameter)]*
+
+Parameters associated with the attribute, indexed by name.
+
+* **Return type:**
+ dict[str, [`AttributeParameter`](supporting.md#ansys.grantami.core.mi_attribute_classes.AttributeParameter)]
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+### *class* AttributeDefinitionPoint
+
+Extended [`AttributeDefinitionMultiValue`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionMultiValue) class for point attributes.
+
+Provides access to point-specific information and methods.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+#### *property* database_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The database unit for this attribute.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* default_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Attribute database unit in the active unit system.
+
+The unit used by MI Viewer or MI Explore to display this attribute in the active unit system. This
+property is only affected by the unit system choice, and is not affected by [`Table.set_display_unit()`](table.md#ansys.grantami.core.mi_tree_classes.Table.set_display_unit).
+
+* **Returns:**
+ [`None`](https://docs.python.org/3/library/constants.html#None) if the attribute is dimensionless.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* is_multivalued *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether this attribute allows multiple values to be set.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* max *: [float](https://docs.python.org/3/library/functions.html#float) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Maximum value of the data attribute.
+
+Affected by user read permissions.
+
+* **Return type:**
+ float or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* min *: [float](https://docs.python.org/3/library/functions.html#float) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Minimum value of the data attribute.
+
+Affected by user read permissions.
+
+* **Return type:**
+ float or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* parameters *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [AttributeParameter](supporting.md#ansys.grantami.core.mi_attribute_classes.AttributeParameter)]*
+
+Parameters associated with the attribute, indexed by name.
+
+* **Return type:**
+ dict[str, [`AttributeParameter`](supporting.md#ansys.grantami.core.mi_attribute_classes.AttributeParameter)]
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+### *class* AttributeDefinitionUnsupported
+
+Extended [`AttributeDefinition`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class for unsupported attribute types (discrete functional).
+
+Provides access to the limited information available for unsupported attribute types (name, type and unit, if
+present).
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
+
+
+
+### *class* AttributeDefinitionDiscreteFunctional
+
+Extended [`AttributeDefinitionUnsupported`](#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionUnsupported) class for discrete functional attributes.
+
+Provides access to the limited information available (name, type and unit, if present).
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Table.attributes`](table.md#ansys.grantami.core.mi_tree_classes.Table.attributes) to access instances of this class.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/attribute-values.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/attribute-values.md
new file mode 100644
index 0000000000..649513c2e2
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/attribute-values.md
@@ -0,0 +1,2258 @@
+# Attribute values
+
+
+
+
+
+
+
+### *class* AttributeValue
+
+Stores and provides access to attribute data values.
+
+The attributes in a [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) are represented in the MI Scripting Toolkit by [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)
+objects, with an associated [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) object containing the attribute’s data.
+[`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) is the base class, and each attribute type has a specialised class that inherits from it.
+
+### Notes
+
+Do not create instances of this class; it represents an abstract database structure.
+
+The ‘Notes’ field, available for all attributes, is a property of the update operation. Use the
+[`update()`](session.md#ansys.grantami.core.mi.Session.update) `notes` argument to provide revision notes.
+
+
+
+#### is_empty()
+
+Checks whether the attribute value is populated.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* definition *: [AttributeDefinition](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)*
+
+The attribute definition associated with this attribute value.
+
+* **Return type:**
+ [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)
+
+
+
+#### *property* id *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Attribute identifier.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* is_applicable *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the attribute is applicable to the current record.
+
+Setting this to [`False`](https://docs.python.org/3/library/constants.html#False) will clear any data values on the attribute on import.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+* **Raises:**
+ [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If attempting to set a non-boolean value.
+
+
+
+#### *property* is_meta *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the attribute is a meta-attribute.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* is_meta_for *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Name of the parent attribute.
+
+* **Returns:**
+ Name of the parent attribute, or [`None`](https://docs.python.org/3/library/constants.html#None) if not a meta-attribute.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* meta_attributes *: [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [AttributeValue](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue)]*
+
+Meta-attributes associated with this attribute.
+
+Does not make calls to the Service Layer.
+
+* **Return type:**
+ dict[str, [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue)]
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Attribute name.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* record *: [Record](record.md#ansys.grantami.core.mi_record_classes.Record)*
+
+Record in which the attribute value is defined.
+
+* **Return type:**
+ [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the AttributeValue is not associated with a record.
+
+
+
+#### *property* type *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Attribute data type, as a four-character string.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+### Notes
+
+* Numeric attributes: `POIN` (point), `RNGE` (range), `INPT` (integer).
+* Text attributes: `STXT` (short text), `LTXT` (long text), `DISC` (discrete).
+* Functional attributes: `FUNC` (float functional).
+* Media attributes: `HLNK` (hyperlink), `PICT` (picture), `FILE` (file).
+* Other attributes: `LOGI` (logical), `DTTM` (date time), `TABL` (tabular).
+
+`DSFN` and `MAFN` data values are not supported by the MI Scripting Toolkit, and appear as UNSUPPORTED DATA
+TYPE.
+
+
+
+#### *abstract property* value *: [Any](https://docs.python.org/3/library/typing.html#typing.Any)*
+
+Current value of the attribute.
+
+Can be modified.
+
+* **Return type:**
+ Any
+
+
+
+### *class* AttributeBinary
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class to handle [`BinaryType`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType) objects as attribute data values.
+
+Base class for [`AttributePicture`](#ansys.grantami.core.mi_attribute_value_classes.AttributePicture) and [`AttributeFile`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFile).
+
+### Notes
+
+Do not create instances of this class; it represents an abstract database structure.
+
+
+
+#### is_empty()
+
+Checks if the [`BinaryType`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType) object is populated by checking if it contains any binary data.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* binary_data *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The binary data for the file.
+
+Binary data can be set with a bytes object or file buffer.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If binary data is available on the server but has not been exported.
+
+
+
+#### *property* mime_file_type *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+MIME (Multipurpose Internet Mail Extensions) file type.
+
+If this object is populated via export, the `mime_file_type` property returns the MIME file type stored in
+Granta MI.
+
+Setting this attribute value (via either `.load()`, setting the [`binary_data`](#ansys.grantami.core.mi_attribute_value_classes.AttributeBinary.binary_data) property, or
+setting the underlying `.object.binary_data`) will update the `mime_file_type` property using the
+`filetype` library. If `filetype` cannot determine the MIME file type, the `mime_file_type` property is
+set to [`None`](https://docs.python.org/3/library/constants.html#None) and Granta MI determines the MIME file type during import.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+The [filetype PyPI page](https://pypi.org/project/filetype) lists supported MIME types.
+
+
+
+#### *property* url *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+URL of the hosted file.
+
+In a future version this property will raise an exception if the attribute is exported with
+`include_binary_data = True`. See [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+* **Returns:**
+ URL to the file stored in the parent Granta MI attribute, or [`None`](https://docs.python.org/3/library/constants.html#None) if the URL was not populated.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+The data can be retrieved by using a Python HTTP library (e.g. Requests, HTTPX) and by supplying the
+appropriate authentication for your Granta MI server.
+
+To populate this property, the [`Table.bulk_fetch()`](table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) method must be used with
+`include_binary_data = False` (default). If `include_binary_data = True` is specified, or if the attribute
+is fetched on-demand by accessing the `attributes` dictionary without performing a bulk fetch, this property
+will always return [`None`](https://docs.python.org/3/library/constants.html#None).
+
+
+
+#### *property* value *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The binary data of the hosted file, if exported.
+
+* **Return type:**
+ bytes or [`None`](https://docs.python.org/3/library/constants.html#None)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If binary data is available on the server but has not been exported. In the next release, this behavior will
+ be deprecated. A later release will not raise an exception if the attribute is exported with
+ `include_binary_data = False`. Instead, the URL will be returned if the attribute is populated. See
+ [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+
+
+### *class* AttributePicture
+
+Extended [`AttributeBinary`](#ansys.grantami.core.mi_attribute_value_classes.AttributeBinary) class for handling [`Picture`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.Picture) objects.
+
+Provides access to [`Picture`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.Picture) save/load methods.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+Pictures of up to 500 MB in size may be stored in Granta MI databases. To upload pictures larger than 20 Mb using
+Scripting Toolkit:
+
+* Granta MI Service Layer must be configured to allow large requests. If this is not configured,
+ [`Session.update()`](session.md#ansys.grantami.core.mi.Session.update) will raise a [`GRANTA_ServiceLayerError`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_ServiceLayerError) for a “413 Request Entity Too Large” HTTP
+ response. For more information, contact your Ansys Technical Representative.
+* The Python client environment must have sufficient system resources to load and Base64-encode the binary data. If
+ there are insufficient system resources, unhandled Python exceptions may be raised.
+
+
+
+#### is_empty()
+
+Checks if the [`BinaryType`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType) object is populated by checking if it contains any binary data.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### load(path)
+
+Wraps the [`Picture.load()`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.Picture.load) method (populates the [`Picture`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.Picture) object with the specified image file).
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to the image file to load.
+ Takes the form `C:\\Users\\yourname\\Pictures\\image.jpg` or
+ `/home/username/Pictures/image.jpg`.
+
+
+
+#### save(path)
+
+Wraps the [`Picture.save()`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.Picture.save) method.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path where the image should be saved.
+ Takes the form `C:\\Users\\yourname\\Pictures\\image.jpg` or
+ `/home/username/Pictures/image.jpg`.
+
+
+
+#### *property* binary_data *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The binary data for the file.
+
+Binary data can be set with a bytes object or file buffer.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If binary data is available on the server but has not been exported.
+
+
+
+#### *property* mime_file_type *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+MIME (Multipurpose Internet Mail Extensions) file type.
+
+If this object is populated via export, the `mime_file_type` property returns the MIME file type stored in
+Granta MI.
+
+Setting this attribute value (via either `.load()`, setting the [`binary_data`](#ansys.grantami.core.mi_attribute_value_classes.AttributePicture.binary_data) property, or
+setting the underlying `.object.binary_data`) will update the `mime_file_type` property using the
+`filetype` library. If `filetype` cannot determine the MIME file type, the `mime_file_type` property is
+set to [`None`](https://docs.python.org/3/library/constants.html#None) and Granta MI determines the MIME file type during import.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+The [filetype PyPI page](https://pypi.org/project/filetype) lists supported MIME types.
+
+
+
+#### *property* url *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+URL of the hosted file.
+
+In a future version this property will raise an exception if the attribute is exported with
+`include_binary_data = True`. See [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+* **Returns:**
+ URL to the file stored in the parent Granta MI attribute, or [`None`](https://docs.python.org/3/library/constants.html#None) if the URL was not populated.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+The data can be retrieved by using a Python HTTP library (e.g. Requests, HTTPX) and by supplying the
+appropriate authentication for your Granta MI server.
+
+To populate this property, the [`Table.bulk_fetch()`](table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) method must be used with
+`include_binary_data = False` (default). If `include_binary_data = True` is specified, or if the attribute
+is fetched on-demand by accessing the `attributes` dictionary without performing a bulk fetch, this property
+will always return [`None`](https://docs.python.org/3/library/constants.html#None).
+
+
+
+#### *property* value *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The binary data of the hosted file, if exported.
+
+* **Return type:**
+ bytes or [`None`](https://docs.python.org/3/library/constants.html#None)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If binary data is available on the server but has not been exported. In the next release, this behavior will
+ be deprecated. A later release will not raise an exception if the attribute is exported with
+ `include_binary_data = False`. Instead, the URL will be returned if the attribute is populated. See
+ [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+
+
+### *class* AttributeFile
+
+Extended [`AttributeBinary`](#ansys.grantami.core.mi_attribute_value_classes.AttributeBinary) class to handle [`File`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.File) objects.
+
+Provides access to [`File`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.File) object save/load methods, file name, and description.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+Files of up to 500 MB in size may be stored in Granta MI databases. To upload files larger than 20 Mb using
+Scripting Toolkit:
+
+* Granta MI Service Layer must be configured to allow large requests. If this is not configured,
+ [`Session.update()`](session.md#ansys.grantami.core.mi.Session.update) will raise a [`GRANTA_ServiceLayerError`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_ServiceLayerError) for a “413 Request Entity Too Large” HTTP
+ response. For more information, contact your Ansys Technical Representative.
+* The Python client environment must have sufficient system resources to load and Base64-encode the binary data. If
+ there are insufficient system resources, unhandled Python exceptions may be raised.
+
+
+
+#### is_empty()
+
+Checks if the [`BinaryType`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType) object is populated by checking if it contains any binary data.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### load(path)
+
+Wraps the [`File.load()`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.File.load) method (populates the [`File`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.File) object with the specified file).
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to the file to be imported.
+ Takes the form `C:\\Users\\yourname\\Documents\\file.pdf` or
+ `/home/username/Documents/file.pdf`.
+
+
+
+#### save(path)
+
+Wraps the [`File.save()`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.File.save) method.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path where the file should be saved.
+ Takes the form `C:\\Users\\yourname\\Documents\\file.pdf` or
+ `/home/username/Documents/file.pdf`.
+
+
+
+#### *property* binary_data *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The binary data for the file.
+
+Binary data can be set with a bytes object or file buffer.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If binary data is available on the server but has not been exported.
+
+
+
+#### *property* description *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Description of the file displayed in MI applications.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) | None
+
+
+
+#### *property* file_name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the file associated with the [`File`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.File) object.
+
+Displayed in MI applications.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* mime_file_type *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+MIME (Multipurpose Internet Mail Extensions) file type.
+
+If this object is populated via export, the `mime_file_type` property returns the MIME file type stored in
+Granta MI.
+
+Setting this attribute value (via either `.load()`, setting the [`binary_data`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFile.binary_data) property, or
+setting the underlying `.object.binary_data`) will update the `mime_file_type` property using the
+`filetype` library. If `filetype` cannot determine the MIME file type, the `mime_file_type` property is
+set to [`None`](https://docs.python.org/3/library/constants.html#None) and Granta MI determines the MIME file type during import.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+The [filetype PyPI page](https://pypi.org/project/filetype) lists supported MIME types.
+
+
+
+#### *property* url *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+URL of the hosted file.
+
+In a future version this property will raise an exception if the attribute is exported with
+`include_binary_data = True`. See [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+* **Returns:**
+ URL to the file stored in the parent Granta MI attribute, or [`None`](https://docs.python.org/3/library/constants.html#None) if the URL was not populated.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+The data can be retrieved by using a Python HTTP library (e.g. Requests, HTTPX) and by supplying the
+appropriate authentication for your Granta MI server.
+
+To populate this property, the [`Table.bulk_fetch()`](table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) method must be used with
+`include_binary_data = False` (default). If `include_binary_data = True` is specified, or if the attribute
+is fetched on-demand by accessing the `attributes` dictionary without performing a bulk fetch, this property
+will always return [`None`](https://docs.python.org/3/library/constants.html#None).
+
+
+
+#### *property* value *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The binary data of the hosted file, if exported.
+
+* **Return type:**
+ bytes or [`None`](https://docs.python.org/3/library/constants.html#None)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If binary data is available on the server but has not been exported. In the next release, this behavior will
+ be deprecated. A later release will not raise an exception if the attribute is exported with
+ `include_binary_data = False`. Instead, the URL will be returned if the attribute is populated. See
+ [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+
+
+### *class* AttributeDate
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for date attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### *property* value *: [date](https://docs.python.org/3/library/datetime.html#datetime.date) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Return the value of the date attribute as a [`datetime.date`](https://docs.python.org/3/library/datetime.html#datetime.date) object.
+
+Can be modified. Use [`datetime.date.fromisoformat()`](https://docs.python.org/3/library/datetime.html#datetime.date.fromisoformat) to create a date object from a string before
+assigning to this property.
+
+* **Return type:**
+ [datetime.date](https://docs.python.org/3/library/datetime.html#datetime.date) or None
+* **Raises:**
+ [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a non-date value.
+
+
+
+### *class* AttributeDiscrete
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for discrete attributes.
+
+Base class for [`AttributeDiscreteSingle`](#ansys.grantami.core.mi_attribute_value_classes.AttributeDiscreteSingle) and [`AttributeDiscreteMulti`](#ansys.grantami.core.mi_attribute_value_classes.AttributeDiscreteMulti).
+
+### Notes
+
+Do not create instances of this class; it represents an abstract database structure.
+
+
+
+#### *property* is_multivalued *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether this attribute allows multiple values to be set.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* possible_discrete_values *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+List of the attribute’s possible discrete data values.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+### *class* AttributeDiscreteSingle
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for discrete attributes.
+
+Provides access to the attribute’s data value as a string, and the order.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### *property* order *: [int](https://docs.python.org/3/library/functions.html#int) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Position of the current discrete value in the discrete type.
+
+Relevant for ordered discrete types. Read-only property. Index starts at 1.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int) or None
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Discrete value associated with this attribute.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a non-string value.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the value is not in the list of possible discrete values.
+
+
+
+### *class* AttributeDiscreteMulti
+
+Extended [`AttributeDiscrete`](#ansys.grantami.core.mi_attribute_value_classes.AttributeDiscrete) class for multivalued discrete attributes.
+
+Provides access to the tuple of strings that store the attribute’s data values, and their order.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### is_empty()
+
+Checks whether the attribute value is populated.
+
+[`AttributeDiscreteMulti`](#ansys.grantami.core.mi_attribute_value_classes.AttributeDiscreteMulti) objects are empty if [`AttributeDiscreteMulti.value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeDiscreteMulti.value) is [`None`](https://docs.python.org/3/library/constants.html#None) or an
+empty tuple.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* order *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[int](https://docs.python.org/3/library/functions.html#int)] | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Positions of the current discrete values in the discrete type.
+
+Relevant for ordered discrete types. Read-only property. Index starts at 1.
+
+* **Return type:**
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[int](https://docs.python.org/3/library/functions.html#int)] or None
+
+
+
+#### *property* value *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str)] | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Discrete value(s) associated with this attribute.
+
+To set to a single value, use a tuple with one item, such as `('item',)`.
+
+* **Return type:**
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str)] or None
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a string, a non-tuple value, or if any element in the tuple is not a string.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If one or more values are not in the list of possible discrete values.
+
+
+
+### *class* AttributeHyperlink
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for hyperlink attributes.
+
+Provides access to the `hyperlink_description` and `hyperlink_display` text properties.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### *property* hyperlink_description *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Text which displays instead of the URL in MI applications.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* hyperlink_display *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Indicates how the hyperlink should be opened when clicked on in MI applications.
+
+Takes one of the following values:
+
+* `New`: Open in a new window or tab.
+* `Top`: Open in the current window or tab.
+* `Content`: Open within the current MI application (for example, in a frame or dialog).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If providing an invalid hyperlink display style.
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Returns the URL as a string, or None if unset.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+### *class* AttributeInteger
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for integer attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### *property* value *: [int](https://docs.python.org/3/library/functions.html#int) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Current value of the attribute.
+
+Can be modified.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int) or None
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a non-integer value.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the value is too large (must be between -2,147,483,648 and 2,147,483,647).
+
+
+
+### *class* AttributeLogical
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for logical attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### *property* value *: [bool](https://docs.python.org/3/library/functions.html#bool) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Current value of the attribute.
+
+Can be modified.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool) or None
+
+
+
+### *class* AttributePoint
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for point data attributes.
+
+Base class for [`AttributePointSingle`](#ansys.grantami.core.mi_attribute_value_classes.AttributePointSingle) and [`AttributePointMulti`](#ansys.grantami.core.mi_attribute_value_classes.AttributePointMulti).
+
+### Notes
+
+Do not create instances of this class; it represents an abstract database structure.
+
+
+
+#### *property* is_estimated *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the value has been estimated.
+
+Defaults to [`False`](https://docs.python.org/3/library/constants.html#False) for new attribute values.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* is_multivalued *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether this attribute allows multiple values to be set.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+### *class* AttributePointSingle
+
+Extended [`AttributePoint`](#ansys.grantami.core.mi_attribute_value_classes.AttributePoint) class for single-valued point data attributes.
+
+Provides access to the single scalar value.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### set_value(value)
+
+Sets the attribute value.
+
+This method is an alternative to setting the [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributePointSingle.value) property directly. It accepts any object that
+implements the [`SupportsFloat`](https://docs.python.org/3/library/typing.html#typing.SupportsFloat) protocol and sets the attribute value to the result of the
+conversion of the input value to a float.
+
+* **Parameters:**
+ **value** ([`SupportsFloat`](https://docs.python.org/3/library/typing.html#typing.SupportsFloat)) – Value to set.
+
+
+
+#### *property* default_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Attribute database unit in the active unit system.
+
+The unit used by MI Viewer or MI Explore to display this attribute in the active unit system. This
+property is only affected by the unit system choice, and is not affected by [`Table.set_display_unit()`](table.md#ansys.grantami.core.mi_tree_classes.Table.set_display_unit).
+
+* **Returns:**
+ [`None`](https://docs.python.org/3/library/constants.html#None) if the attribute is dimensionless.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* trailing_zero_information *: [TrailingZeroInformation](supporting.md#ansys.grantami.core.mi_meta_classes.TrailingZeroInformation) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Trailing zero information associated with the attribute value.
+
+This property is only populated for exported attribute values which include trailing zero information. To
+include trailing zero information in an attribute value during import with the Scripting Toolkit, use a
+[`ValueWithPrecision`](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) to set the [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributePointSingle.value).
+
+* **Return type:**
+ [`TrailingZeroInformation`](supporting.md#ansys.grantami.core.mi_meta_classes.TrailingZeroInformation) or None
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol of the attribute.
+
+Can be modified. [`None`](https://docs.python.org/3/library/constants.html#None) if the attribute is dimensionless.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [float](https://docs.python.org/3/library/functions.html#float) | [int](https://docs.python.org/3/library/functions.html#int) | [ValueWithPrecision](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Point values associated with this attribute.
+
+* **Return type:**
+ float or int or [`ValueWithPrecision`](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) or None
+* **Raises:**
+ [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a value that is not a float, int, or [`ValueWithPrecision`](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision).
+
+
+
+### *class* AttributePointMulti
+
+Extended [`AttributePoint`](#ansys.grantami.core.mi_attribute_value_classes.AttributePoint) class for multi-valued point data attributes.
+
+Multi-valued points are represented in the Streamlined API as tuples of [`ParameterizedPointValue`](supporting.md#ansys.grantami.core._mi_value_classes.ParameterizedPointValue) objects.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### is_empty()
+
+Checks whether the attribute value is populated.
+
+[`AttributePointMulti`](#ansys.grantami.core.mi_attribute_value_classes.AttributePointMulti) objects are empty if [`AttributePointMulti.value`](#ansys.grantami.core.mi_attribute_value_classes.AttributePointMulti.value) is [`None`](https://docs.python.org/3/library/constants.html#None) or an empty
+tuple.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### set_value(values, parameters=None)
+
+Sets the [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributePointMulti.value) to a tuple of [`ParameterizedPointValue`](supporting.md#ansys.grantami.core._mi_value_classes.ParameterizedPointValue) built from values and parameters.
+
+Arguments `values` and `parameters` must be Sequences of equal lengths.
+
+* **Parameters:**
+ * **values** (Sequence[SupportsFloat | [`ValueWithPrecision`](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision)]) – Point values.
+ * **parameters** (*Sequence* *[**Mapping* *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* [*str*](https://docs.python.org/3/library/stdtypes.html#str) *|* [*float*](https://docs.python.org/3/library/functions.html#float) *]* *] or* *None* *,* *optional*) – Parameter values for each point in values. If [`None`](https://docs.python.org/3/library/constants.html#None), values are set without parameter values.
+
+### Examples
+
+Attribute value without parameter values:
+
+```pycon
+>>> multivalued_point_attribute: AttributePointMulti
+>>> multivalued_point_attribute.set_value([1.0, 2, 3.0])
+>>> multivalued_point_attribute.value
+(ParameterizedPointValue(value=1.0, parameters=()),
+ParameterizedPointValue(value=2.0, parameters=()),
+ParameterizedPointValue(value=3.0, parameters=()))
+```
+
+Attribute value with parameter values for the first value only:
+
+```pycon
+>>> multivalued_point_attribute: AttributePointMulti
+>>> multivalued_point_attribute.set_value([1.0, 2, 3.0], [{"Temperature": 25.0, "Statistical basis": "A-basis"}, {}, {}])
+>>> multivalued_point_attribute.value
+(ParameterizedPointValue(value=1.0, parameters=(PointParameterValue(name='Temperature', value=25.0), PointParameterValue(name='Statistical basis', value='A-basis'))),
+ParameterizedPointValue(value=2.0, parameters=()),
+ParameterizedPointValue(value=3.0, parameters=()))
+```
+
+
+
+#### *property* default_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Attribute database unit in the active unit system.
+
+The unit used by MI Viewer or MI Explore to display this attribute in the active unit system. This
+property is only affected by the unit system choice, and is not affected by [`Table.set_display_unit()`](table.md#ansys.grantami.core.mi_tree_classes.Table.set_display_unit).
+
+* **Returns:**
+ [`None`](https://docs.python.org/3/library/constants.html#None) if the attribute is dimensionless.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* parameters *: mappingproxy[[str](https://docs.python.org/3/library/stdtypes.html#str), [PointValueParameter](supporting.md#ansys.grantami.core.mi_attribute_value_classes.PointValueParameter)]*
+
+Parameters associated with the point data attribute, indexed by name.
+
+Modify the [`PointValueParameter.unit`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.PointValueParameter.unit) property on the returned objects to specify a different unit for
+import.
+
+* **Returns:**
+ Read-only mapping of parameters
+* **Return type:**
+ [`MappingProxyType`](https://docs.python.org/3/library/types.html#types.MappingProxyType) [str, [`PointValueParameter`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.PointValueParameter)]
+
+
+
+#### *property* points *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...]*
+
+Read-only view of point values currently set on the attribute value.
+
+The returned value does not include parameter values and converts [`ValueWithPrecision`](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) to float.
+
+* **Return type:**
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), …]
+
+### Examples
+
+For a multi-valued point attribute named `Modulus`, with parameters `Temperature` and `Statistical basis`:
+
+```pycon
+>>> multivalued_point_attribute: AttributePointMulti
+>>> multivalued_point_attribute.value = (
+... ParameterizedPointValue(
+... value=1.0,
+... parameters=(
+... PointParameterValue("Temperature", 25.0),
+... PointParameterValue("Statistical basis", "A-basis"),
+... ),
+... ),
+... ParameterizedPointValue(value=2.0),
+... )
+>>> multivalued_point_attribute.points
+(1.0, 2.0)
+```
+
+
+
+#### *property* trailing_zero_information *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[TrailingZeroInformation](supporting.md#ansys.grantami.core.mi_meta_classes.TrailingZeroInformation) | [None](https://docs.python.org/3/library/constants.html#None), ...] | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Trailing zero information associated with the attribute value.
+
+This property is only populated for exported attribute values which include trailing zero information. To
+include trailing zero information in an attribute value during import with the Scripting Toolkit, use
+[`ValueWithPrecision`](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) in [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributePointMulti.value).
+
+* **Return type:**
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[*TrailingZeroInformation*](supporting.md#ansys.grantami.core.mi_meta_classes.TrailingZeroInformation) | None] | None
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol of the attribute.
+
+Can be modified. [`None`](https://docs.python.org/3/library/constants.html#None) if the attribute is dimensionless.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[ParameterizedPointValue](supporting.md#ansys.grantami.core._mi_value_classes.ParameterizedPointValue), ...]*
+
+Point values associated with this attribute.
+
+* **Return type:**
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[ParameterizedPointValue](supporting.md#ansys.grantami.core._mi_value_classes.ParameterizedPointValue), …]
+
+### Examples
+
+For a multi-valued point attribute named `Modulus`, with parameters `Temperature` and `Statistical basis`:
+
+```pycon
+>>> multivalued_point_attribute: AttributePointMulti
+>>> multivalued_point_attribute.value = (
+... ParameterizedPointValue(
+... value=1.0,
+... parameters=(
+... PointParameterValue("Temperature", 25.0),
+... PointParameterValue("Statistical basis", "A-basis"),
+... ),
+... ),
+... ParameterizedPointValue(value=2.0),
+... )
+>>> multivalued_point_attribute.value
+(ParameterizedPointValue(value=1.0, parameters=(PointParameterValue(name='Temperature', value=25.0), PointParameterValue(name='Statistical basis', value='A-basis'))),
+ParameterizedPointValue(value=2.0, parameters=()))
+```
+
+
+
+### *class* AttributeRange
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for range data attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### *property* default_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Attribute database unit in the active unit system.
+
+The unit used by MI Viewer or MI Explore to display this attribute in the active unit system. This
+property is only affected by the unit system choice, and is not affected by [`Table.set_display_unit()`](table.md#ansys.grantami.core.mi_tree_classes.Table.set_display_unit).
+
+* **Returns:**
+ [`None`](https://docs.python.org/3/library/constants.html#None) if the attribute is dimensionless.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* high *: [float](https://docs.python.org/3/library/functions.html#float) | [ValueWithPrecision](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+High value of the range.
+
+Read-only property. Proxies to [`Range.high`](supporting.md#ansys.grantami.core._mi_value_classes.Range.high) on the attribute [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeRange.value).
+
+* **Return type:**
+ float or [`ValueWithPrecision`](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) or None
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the attribute value is empty.
+
+
+
+#### *property* high_value_is_inclusive *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the high value is included in the range.
+
+Read-only property. Proxies to [`Range.high_value_is_inclusive`](supporting.md#ansys.grantami.core._mi_value_classes.Range.high_value_is_inclusive) on the attribute [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeRange.value).
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the attribute value is empty.
+
+
+
+#### *property* high_value_trailing_zero_information *: [TrailingZeroInformation](supporting.md#ansys.grantami.core.mi_meta_classes.TrailingZeroInformation) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Trailing zero information associated with the high value.
+
+This property is only populated for exported attribute values which include trailing zero information. To
+include trailing zero information in an attribute value during import with the Scripting Toolkit, use a
+[`ValueWithPrecision`](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) object to set the [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeRange.value).
+
+* **Return type:**
+ [`TrailingZeroInformation`](supporting.md#ansys.grantami.core.mi_meta_classes.TrailingZeroInformation) or None
+
+
+
+#### *property* is_estimated *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the value has been estimated.
+
+Defaults to [`False`](https://docs.python.org/3/library/constants.html#False) for new attribute values.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* low *: [float](https://docs.python.org/3/library/functions.html#float) | [ValueWithPrecision](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Low value of the range.
+
+Read-only property. Proxies to [`Range.low`](supporting.md#ansys.grantami.core._mi_value_classes.Range.low) on the attribute [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeRange.value).
+
+* **Return type:**
+ float or [`ValueWithPrecision`](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) or None
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the attribute value is empty.
+
+
+
+#### *property* low_value_is_inclusive *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the low value is included in the range.
+
+Read-only property. Proxies to [`Range.low_value_is_inclusive`](supporting.md#ansys.grantami.core._mi_value_classes.Range.low_value_is_inclusive) on the attribute [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeRange.value).
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the attribute value is empty.
+
+
+
+#### *property* low_value_trailing_zero_information *: [TrailingZeroInformation](supporting.md#ansys.grantami.core.mi_meta_classes.TrailingZeroInformation) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Trailing zero information associated with the low value.
+
+This property is only populated for exported attribute values which include trailing zero information. To
+include trailing zero information in an attribute value during import with the Scripting Toolkit, use a
+[`ValueWithPrecision`](supporting.md#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) object to set the [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeRange.value).
+
+* **Return type:**
+ [`TrailingZeroInformation`](supporting.md#ansys.grantami.core.mi_meta_classes.TrailingZeroInformation) or None
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol of the attribute.
+
+Can be modified. [`None`](https://docs.python.org/3/library/constants.html#None) if the attribute is dimensionless.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [Range](supporting.md#ansys.grantami.core._mi_value_classes.Range) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Current value of the attribute.
+
+Can be modified.
+
+* **Return type:**
+ [`Range`](supporting.md#ansys.grantami.core._mi_value_classes.Range) or None
+* **Raises:**
+ [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a value that is not a Range instance.
+
+
+
+### *class* AttributeTabular
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for tabular data attributes.
+
+Provides access to tabular data and its properties, such as linking attribute and table, and methods for
+adding, deleting or swapping rows.
+
+#### WARNING
+Linked functional columns are not supported in tabular attributes. Exported cells are represented as
+[`UnsupportedType`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.UnsupportedType)
+
+Importing an empty tabular attribute is deprecated. Instead:
+
+* To delete all rows in an existing tabular attribute, use the [`Record.clear_attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.clear_attributes) method to delete
+ the attribute value.
+* To mark the attribute as Not Applicable, set the [`AttributeValue.is_applicable`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue.is_applicable) property to `False`.
+
+Use the [`AttributeTabular.shape`](#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.shape) property to determine the current number of rows in the tabular
+attribute.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### append_row(linking_value=None)
+
+Appends a new unpopulated row, and sets the linking value for that row if one is provided.
+
+* **Parameters:**
+ **linking_value** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Linking value for the new row.
+
+
+
+#### delete_row(index)
+
+Removes the row at the specified index.
+
+* **Parameters:**
+ **index** ([*int*](https://docs.python.org/3/library/functions.html#int)) – Index of the row to delete.
+
+### Examples
+
+`delete_row(0)` deletes the first row.
+
+
+
+#### enable_destructive_editing()
+
+Enable destructive editing of the tabular data.
+
+* **Warns:**
+ **UserWarning** – If unexported binary data is present in any of the tabular cells.
+
+#### WARNING
+Destructive editing removes existing rows and creates new ones. Destructive editing should be avoided because:
+
+* This can be slow for attributes with File or Picture attributes, especially if many rows are present.
+* Users of Data Updater will face conflicts when applying subsequent updates.
+
+If destructive editing is performed while unexported binary data is present, a
+[`UnexportedBinaryDataError`](exceptions.md#ansys.grantami.core.mi_meta_classes.UnexportedBinaryDataError) is raised on import. See [`Table.bulk_fetch()`](table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) for more information.
+
+#### SEE ALSO
+[`is_destructive_editing_allowed`](#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.is_destructive_editing_allowed)
+: Whether destructive editing of the tabular attribute value is allowed.
+
+[`destructively_edited`](#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.destructively_edited)
+: Whether destructive editing has been performed.
+
+### Notes
+
+The following actions are considered destructive:
+
+* [`AttributeTabular.swap_rows()`](#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.swap_rows)
+* [`TabularRow.set_linking_value()`](tabular.md#ansys.grantami.core.mi_attribute_value_classes.TabularRow.set_linking_value) for an exported row
+
+Destructive editing may be forced for a tabular attribute by calling [`force_destructive_editing()`](#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.force_destructive_editing) before
+importing the data.
+
+
+
+#### force_destructive_editing()
+
+Force destructive editing of the tabular data.
+
+See [`enable_destructive_editing()`](#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.enable_destructive_editing) for warnings associated with destructive editing. This method should
+only be used for cases where destructive editing is absolutely necessary and is not triggered automatically.
+
+* **Warns:**
+ **UserWarning** – If unexported binary data is present in any of the tabular cells.
+
+### Notes
+
+If destructive editing is performed while unexported binary data is present, a
+[`UnexportedBinaryDataError`](exceptions.md#ansys.grantami.core.mi_meta_classes.UnexportedBinaryDataError) is raised on import. See [`Table.bulk_fetch()`](table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) for more information.
+
+
+
+#### is_empty()
+
+Checks whether the attribute value is populated.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### load()
+
+Loads exported tabular data.
+
+Exported data is generally lazily loaded by any property of the tabular that requires it. This method can be
+used to explicitly load the exported data or to discard staged user modifications and reset the attribute value
+to the exported data.
+
+
+
+#### show()
+
+Displays the data as an ascii-art style table.
+
+
+
+#### swap_rows(row1, row2)
+
+Change the positions of two rows with indices `row1` and `row2`.
+
+* **Parameters:**
+ * **row1** ([*int*](https://docs.python.org/3/library/functions.html#int)) – Index of the first row.
+ * **row2** ([*int*](https://docs.python.org/3/library/functions.html#int)) – Index of the second row.
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If destructive editing is not enabled.
+
+#### WARNING
+The swap_rows operation is considered destructive and will trigger a complete re-import of the tabular data
+which may be slow, and will prevent Data Updater from tracking row-level updates to the tabular data. It is
+disabled by default. To enable this action, call the method [`enable_destructive_editing()`](#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.enable_destructive_editing) before calling
+this method.
+
+#### SEE ALSO
+[`is_destructive_editing_allowed`](#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.is_destructive_editing_allowed)
+: Whether destructive editing of the tabular attribute value is allowed.
+
+### Examples
+
+Swap the first and fifth rows in the Tabular data structure `my_data`:
+
+```python
+my_data.swap_rows(0, 4)
+```
+
+
+
+#### *property* column_types *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+Data type in each column.
+
+* **Returns:**
+ Only populated for local, linked attribute, or linked column tabular columns. The element will be an empty
+ string otherwise.
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+### Examples
+
+`['STXT', 'POIN', 'DISC', '', '']`
+
+
+
+#### *property* columns *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+List of columns in the tabular data.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* definition *: [AttributeDefinitionTabular](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionTabular)*
+
+The attribute definition associated with this attribute value.
+
+* **Return type:**
+ [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)
+
+
+
+#### *property* destructively_edited *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular data has been destructively edited.
+
+If the value of this property is [`False`](https://docs.python.org/3/library/constants.html#False) then imports will be safe to use with Data Updater.
+
+#### SEE ALSO
+[`enable_destructive_editing()`](#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.enable_destructive_editing)
+: Enable destructive editing of the tabular data.
+
+* **Returns:**
+ [`True`](https://docs.python.org/3/library/constants.html#True) if destructive editing is enabled and any actions have been taken that require destructive
+ editing. [`False`](https://docs.python.org/3/library/constants.html#False) if no destructive actions have been taken or if destructive editing is not
+ enabled.
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* is_destructive_editing_allowed *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether destructive editing of the tabular data is allowed.
+
+By default, destructive editing is not allowed.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+#### SEE ALSO
+[`enable_destructive_editing()`](#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.enable_destructive_editing)
+: Enable destructive editing of the tabular data.
+
+
+
+#### *property* linked_columns *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[bool](https://docs.python.org/3/library/functions.html#bool)]*
+
+Whether each column is linked or not.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[bool](https://docs.python.org/3/library/functions.html#bool)]
+
+
+
+#### *property* linked_records *: [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[Record](record.md#ansys.grantami.core.mi_record_classes.Record)]]*
+
+The records linked to each row, indexed by the linking value of each row at loading.
+
+These links are calculated in Granta MI, and therefore cannot be edited by the user. The dictionary is
+unaffected by local changes to the tabular data, and the data must be re-imported to reflect local changes.
+
+This property will be empty if the user cannot access the linked table, or if
+[`AttributeDefinitionTabular.ignore_linked_records`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionTabular.ignore_linked_records) was set to [`True`](https://docs.python.org/3/library/constants.html#True) before data export.
+
+* **Return type:**
+ dict[str, list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]]
+
+
+
+#### *property* linking_attribute *: [AttributeDefinition](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Short text-type attribute used to link rows in the tabular data attribute to records.
+
+* **Returns:**
+ [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) object. [`None`](https://docs.python.org/3/library/constants.html#None) for purely local tabular data.
+* **Return type:**
+ [AttributeDefinition](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) or None
+
+
+
+#### *property* linking_table *: [Table](table.md#ansys.grantami.core.mi_tree_classes.Table) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+[`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table) object which the linking attribute belongs to.
+
+* **Returns:**
+ [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table) object. [`None`](https://docs.python.org/3/library/constants.html#None) for purely local tabular data.
+* **Return type:**
+ [Table](table.md#ansys.grantami.core.mi_tree_classes.Table) or None
+
+
+
+#### *property* rows *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[TabularRow](tabular.md#ansys.grantami.core.mi_attribute_value_classes.TabularRow), ...]*
+
+Returns a tuple of [`TabularRow`](tabular.md#ansys.grantami.core.mi_attribute_value_classes.TabularRow) objects representing each row in the tabular data.
+
+* **Return type:**
+ tuple[[`TabularRow`](tabular.md#ansys.grantami.core.mi_attribute_value_classes.TabularRow), …]
+
+
+
+#### *property* shape *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[int](https://docs.python.org/3/library/functions.html#int), [int](https://docs.python.org/3/library/functions.html#int)]*
+
+Number of rows by number of columns.
+
+* **Return type:**
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[int](https://docs.python.org/3/library/functions.html#int), [int](https://docs.python.org/3/library/functions.html#int)]
+
+
+
+#### *property* value *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [int](https://docs.python.org/3/library/functions.html#int) | [bool](https://docs.python.org/3/library/functions.html#bool) | [date](https://docs.python.org/3/library/datetime.html#datetime.date) | [MappingProxyType](https://docs.python.org/3/library/types.html#types.MappingProxyType) | [HyperlinkValue](tabular.md#ansys.grantami.core._mi_tabular_value_classes.HyperlinkValue) | [PictureValue](tabular.md#ansys.grantami.core._mi_tabular_value_classes.PictureValue) | [FileValue](tabular.md#ansys.grantami.core._mi_tabular_value_classes.FileValue) | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float)] | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str)] | [None](https://docs.python.org/3/library/constants.html#None) | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [int](https://docs.python.org/3/library/functions.html#int) | [bool](https://docs.python.org/3/library/functions.html#bool) | [date](https://docs.python.org/3/library/datetime.html#datetime.date) | [MappingProxyType](https://docs.python.org/3/library/types.html#types.MappingProxyType) | [HyperlinkValue](tabular.md#ansys.grantami.core._mi_tabular_value_classes.HyperlinkValue) | [PictureValue](tabular.md#ansys.grantami.core._mi_tabular_value_classes.PictureValue) | [FileValue](tabular.md#ansys.grantami.core._mi_tabular_value_classes.FileValue) | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float)] | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str)] | [None](https://docs.python.org/3/library/constants.html#None)]]]*
+
+Raw data for the attribute.
+
+Data is organized as a tuple of tuples:
+
+* The items in the outer tuple represent a row, and so the length of the outer tuple corresponds to the number
+ of rows in the tabular attribute.
+* The items in each inner tuple represent a cell, and so the lengths of the inner tuples correspond to the
+ number of columns in the tabular attribute.
+
+* **Return type:**
+ tuple[tuple[str | int | bool | datetime.date | MappingProxyType | [`HyperlinkValue`](tabular.md#ansys.grantami.core._mi_tabular_value_classes.HyperlinkValue) | [`PictureValue`](tabular.md#ansys.grantami.core._mi_tabular_value_classes.PictureValue) | [`FileValue`](tabular.md#ansys.grantami.core._mi_tabular_value_classes.FileValue) | tuple | None]]
+
+### Notes
+
+When exporting data as a read user, this property may omit rows for the following reasons:
+
+* If a row is completely empty.
+* If a row contains no local data and has a linking value which does not exist in the target table.
+* If a row contains no local data and has a linking value which exists in the target table, but all linked
+ records are inaccessible to the user because of version control or access control.
+
+When exporting data as a write user or above, this property will include all rows.
+
+
+
+### *class* AttributeShortText
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for short text attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Current value of the attribute.
+
+Can be modified. Short text values can be at most 255 characters long.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the value is too long.
+
+
+
+### *class* AttributeLongText
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for long text attributes.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Current value of the attribute.
+
+Can be modified.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+### *class* AttributeFunctionalSeriesPoint
+
+Attribute value class for point series functional data.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### generate_grid_version(create_empty=False)
+
+Convert this object to the equivalent grid functional attribute value object and return the result.
+
+* **Parameters:**
+ **create_empty** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether to create an empty object. Default is [`False`](https://docs.python.org/3/library/constants.html#False).
+* **Returns:**
+ New instance of a grid functional attribute value.
+* **Return type:**
+ [`AttributeFunctionalGridPoint`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If data cannot be represented as grid functional data.
+
+### Notes
+
+If `create_empty` is [`True`](https://docs.python.org/3/library/constants.html#True), an empty functional attribute value is returned.
+
+If `create_empty` is [`False`](https://docs.python.org/3/library/constants.html#False), the following information is copied to the new functional attribute value:
+
+* [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.value) (converted to [`GridPoint`](supporting.md#ansys.grantami.core._mi_value_classes.GridPoint))
+* [`unit`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.unit)
+* [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.parameters)
+* [`is_applicable`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue.is_applicable)
+
+If this method is used with data that cannot be represented as grid functional data, conversion will fail with
+a [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError).
+
+Series functional data can be defined with multiple points sharing the same set of parameter values. These may
+occur with hysteresis curves or multiple series without distinguishing parameters. Such data cannot be
+represented as grid data.
+
+Series with identical parameter values, or with no parameter values, can be converted to grid functional data as
+long as all points have unique x-axis values. However, information about which series the points used to belong
+to will be lost.
+
+
+
+#### is_empty()
+
+Checks whether the attribute value is populated.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### set_value(value)
+
+Set the current value of the attribute.
+
+This method is an alternative to setting the [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.value) property directly, and accepts any sequence type.
+
+* **Parameters:**
+ **value** (Sequence[[`SeriesPoint`](supporting.md#ansys.grantami.core._mi_value_classes.SeriesPoint)]) – New value for the attribute.
+
+
+
+#### with_new_x_axis(parameter_name, create_empty=False)
+
+Generate an empty attribute value of the same type with another parameter as X-axis.
+
+* **Parameters:**
+ * **parameter_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Name of the parameter to use as X-axis.
+ * **create_empty** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether to create an empty attribute value or copy existing data. Default is [`False`](https://docs.python.org/3/library/constants.html#False).
+* **Returns:**
+ New instance of functional attribute of identical type.
+* **Return type:**
+ [`AttributeFunctionalSeriesPoint`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the name is not a valid parameter.
+
+### Notes
+
+If `create_empty` is [`True`](https://docs.python.org/3/library/constants.html#True), an empty functional attribute value is returned.
+
+If `create_empty` is [`False`](https://docs.python.org/3/library/constants.html#False), the following information is copied to the new functional attribute value:
+
+* [`unit`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.unit)
+* [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.parameters)
+* [`is_applicable`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue.is_applicable)
+* [`show_as_table`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.show_as_table)
+* [`log_yaxis`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.log_yaxis)
+
+
+
+#### *property* log_yaxis *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the Y axis is using a logarithmic scale.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* parameters *: mappingproxy[[str](https://docs.python.org/3/library/stdtypes.html#str), [FunctionalValueParameter](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter)]*
+
+Parameters associated with the functional data attribute, indexed by name.
+
+Modify the [`FunctionalValueParameter.unit`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.unit) property on the returned objects to specify a different unit
+for import.
+
+* **Returns:**
+ Read-only mapping of parameters associated with this functional value.
+* **Return type:**
+ [`MappingProxyType`](https://docs.python.org/3/library/types.html#types.MappingProxyType) [str, [`FunctionalValueParameter`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter)]
+
+
+
+#### *property* show_as_table *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the attribute should be displayed as a table.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* table_view *: [FunctionalSeriesPointTableView](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalSeriesPointTableView)*
+
+Supports additional read-only views of the attribute value.
+
+* **Return type:**
+ [`FunctionalSeriesPointTableView`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalSeriesPointTableView)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Unit symbol for the y-axis.
+
+For the x-axis parameter or constraint parameters, use [`unit`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.unit) on
+`FunctionalValueParameter` objects provided by the [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.parameters) property.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[SeriesPoint](supporting.md#ansys.grantami.core._mi_value_classes.SeriesPoint), ...]*
+
+Current value of the attribute.
+
+Can be modified.
+
+#### Versionchanged
+Changed in version 5.0: This property now accepts as input and returns a structured representation of a functional attribute value.
+[`table_view`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.table_view) provides properties to obtain the value in the format
+previously returned by this property.
+
+* **Return type:**
+ tuple[[`SeriesPoint`](supporting.md#ansys.grantami.core._mi_value_classes.SeriesPoint), …]
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a value that is not a tuple of SeriesPoint objects.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the value defines series with incompatible parameters or invalid parameter names.
+
+
+
+#### *property* x_axis *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the parameter used as the x-axis for the attribute value.
+
+Data exported from Granta MI may define a different x-axis parameter than the default x-axis parameter set in
+the attribute definition. To import data with a different x-axis parameter, use [`with_new_x_axis()`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.with_new_x_axis).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+### *class* AttributeFunctionalSeriesRange
+
+Attribute value class for series range functional data.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### generate_grid_version(create_empty=False)
+
+Convert this object to the equivalent grid functional attribute value object and return the result.
+
+* **Parameters:**
+ **create_empty** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether to create an empty object. Default is [`False`](https://docs.python.org/3/library/constants.html#False).
+* **Returns:**
+ New instance of a grid functional attribute value.
+* **Return type:**
+ [`AttributeFunctionalGridRange`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If data cannot be represented as grid functional data.
+
+### Notes
+
+If `create_empty` is [`True`](https://docs.python.org/3/library/constants.html#True), an empty functional attribute value is returned.
+
+If `create_empty` is [`False`](https://docs.python.org/3/library/constants.html#False), the following information is copied to the new functional attribute value:
+
+* [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.value) (converted to [`GridRange`](supporting.md#ansys.grantami.core._mi_value_classes.GridRange))
+* [`unit`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.unit)
+* [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.parameters)
+* [`is_applicable`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue.is_applicable)
+
+Series functional data can be defined with multiple points sharing the same set of parameter values. These may
+occur with hysteresis curves or multiple series without distinguishing parameters. Such data cannot be
+represented as grid data. If this method is used with data that cannot be represented as grid functional data,
+conversion will fail with a [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError).
+
+Series with identical parameter values, or with no parameter values can be converted to grid functional as long
+as all points have unique x-axis values.
+
+
+
+#### is_empty()
+
+Checks whether the attribute value is populated.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### set_value(value)
+
+Set the current value of the attribute.
+
+This method is an alternative to setting the [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.value) property directly, and accepts any Sequence type.
+
+* **Parameters:**
+ **value** (Sequence[[`SeriesRange`](supporting.md#ansys.grantami.core._mi_value_classes.SeriesRange)]) – New value for the attribute.
+
+
+
+#### with_new_x_axis(parameter_name, create_empty=False)
+
+Generate an empty attribute value of the same type with another parameter as X-axis.
+
+* **Parameters:**
+ * **parameter_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Name of the parameter to use as X-axis.
+ * **create_empty** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether to create an empty attribute value or copy existing data. Default is [`False`](https://docs.python.org/3/library/constants.html#False).
+* **Returns:**
+ New instance of functional attribute of identical type.
+* **Return type:**
+ [`AttributeFunctionalSeriesRange`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the name is not a valid parameter.
+
+### Notes
+
+If `create_empty` is [`True`](https://docs.python.org/3/library/constants.html#True), an empty functional attribute value is returned.
+
+If `create_empty` is [`False`](https://docs.python.org/3/library/constants.html#False), the following information is copied to the new functional attribute value:
+
+* [`unit`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.unit)
+* [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.parameters)
+* [`is_applicable`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue.is_applicable)
+* [`show_as_table`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.show_as_table)
+* [`log_yaxis`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.log_yaxis)
+
+
+
+#### *property* log_yaxis *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the Y axis is using a logarithmic scale.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* parameters *: mappingproxy[[str](https://docs.python.org/3/library/stdtypes.html#str), [FunctionalValueParameter](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter)]*
+
+Parameters associated with the functional data attribute, indexed by name.
+
+Modify the [`FunctionalValueParameter.unit`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.unit) property on the returned objects to specify a different unit
+for import.
+
+* **Returns:**
+ Read-only mapping of parameters associated with this functional value.
+* **Return type:**
+ [`MappingProxyType`](https://docs.python.org/3/library/types.html#types.MappingProxyType) [str, [`FunctionalValueParameter`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter)]
+
+
+
+#### *property* show_as_table *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the attribute should be displayed as a table.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* table_view *: [FunctionalSeriesRangeTableView](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalSeriesRangeTableView)*
+
+Supports additional read-only views of the attribute value.
+
+* **Return type:**
+ [`FunctionalSeriesRangeTableView`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalSeriesRangeTableView)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Unit symbol for the y-axis.
+
+For the x-axis parameter or constraint parameters, use [`unit`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.unit) on
+`FunctionalValueParameter` objects provided by the [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.parameters) property.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[SeriesRange](supporting.md#ansys.grantami.core._mi_value_classes.SeriesRange), ...]*
+
+Current value of the attribute.
+
+Can be modified.
+
+#### Versionchanged
+Changed in version 5.0: This property now accepts as input and returns a structured representation of a functional attribute value.
+[`table_view`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.table_view) provides properties to obtain the value in the format
+previously returned by this property.
+
+* **Return type:**
+ tuple[[`SeriesRange`](supporting.md#ansys.grantami.core._mi_value_classes.SeriesRange), …]
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a value that is not a tuple of SeriesRange objects.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the value defines series with incompatible parameters or invalid parameter names.
+
+
+
+#### *property* x_axis *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the parameter used as the x-axis for the attribute value.
+
+Data exported from Granta MI may define a different x-axis parameter than the default x-axis parameter set in
+the attribute definition. To import data with a different x-axis parameter, use [`with_new_x_axis()`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.with_new_x_axis).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+### *class* AttributeFunctionalGridPoint
+
+Attribute value class for point grid functional data.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### generate_series_version(create_empty=False)
+
+Convert this object to the equivalent series functional attribute value object and return the result.
+
+* **Parameters:**
+ **create_empty** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether to create an empty object. Default is [`False`](https://docs.python.org/3/library/constants.html#False).
+* **Returns:**
+ New instance of a series functional attribute value.
+* **Return type:**
+ [`AttributeFunctionalSeriesPoint`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint)
+
+### Notes
+
+If `create_empty` is [`True`](https://docs.python.org/3/library/constants.html#True), an empty functional attribute value is returned.
+
+If `create_empty` is [`False`](https://docs.python.org/3/library/constants.html#False), the following information is copied to the new functional attribute value:
+
+* [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint.value) (converted to [`SeriesPoint`](supporting.md#ansys.grantami.core._mi_value_classes.SeriesPoint))
+* [`unit`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint.unit)
+* [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint.parameters)
+* [`is_applicable`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue.is_applicable)
+
+
+
+#### with_new_x_axis(parameter_name, create_empty=False)
+
+Generate an empty attribute value of the same type with another parameter as X-axis.
+
+* **Parameters:**
+ * **parameter_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Name of the parameter to use as X-axis.
+ * **create_empty** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether to create an empty attribute value or copy existing data. Default is [`False`](https://docs.python.org/3/library/constants.html#False).
+* **Returns:**
+ New instance of functional attribute of identical type.
+* **Return type:**
+ [`AttributeFunctionalGridPoint`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the name is not a valid parameter.
+
+### Notes
+
+If `create_empty` is [`True`](https://docs.python.org/3/library/constants.html#True), an empty functional attribute value is returned.
+
+If `create_empty` is [`False`](https://docs.python.org/3/library/constants.html#False), the following information is copied to the new functional attribute value:
+
+* [`unit`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint.unit)
+* [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint.parameters)
+* [`is_applicable`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue.is_applicable)
+
+
+
+#### *property* parameters *: mappingproxy[[str](https://docs.python.org/3/library/stdtypes.html#str), [FunctionalValueParameter](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter)]*
+
+Parameters associated with the functional data attribute, indexed by name.
+
+Modify the [`FunctionalValueParameter.unit`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.unit) property on the returned objects to specify a different unit
+for import.
+
+* **Returns:**
+ Read-only mapping of parameters associated with this functional value.
+* **Return type:**
+ [`MappingProxyType`](https://docs.python.org/3/library/types.html#types.MappingProxyType) [str, [`FunctionalValueParameter`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter)]
+
+
+
+#### *property* table_view *: [FunctionalGridPointTableView](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalGridPointTableView)*
+
+Supports additional read-only views of the attribute value.
+
+* **Return type:**
+ [`FunctionalGridPointTableView`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalGridPointTableView)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Unit symbol for the y-axis.
+
+For the x-axis parameter or constraint parameters, use [`unit`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.unit) on
+`FunctionalValueParameter` objects provided by the [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint.parameters) property.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [GridPoint](supporting.md#ansys.grantami.core._mi_value_classes.GridPoint)*
+
+Current value of the attribute.
+
+Can be modified.
+
+#### Versionchanged
+Changed in version 5.0: This property now accepts as input and returns a structured representation of a functional attribute value.
+[`table_view`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint.table_view) provides properties to obtain the value in the format
+previously returned by this property.
+
+* **Return type:**
+ [`GridPoint`](supporting.md#ansys.grantami.core._mi_value_classes.GridPoint)
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a value that is not a GridPoint object.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the value defines invalid parameter names.
+
+
+
+#### *property* x_axis *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the parameter used as the x-axis for the attribute value.
+
+Data exported from Granta MI may define a different x-axis parameter than the default x-axis parameter set in
+the attribute definition. To import data with a different x-axis parameter, use [`with_new_x_axis()`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint.with_new_x_axis).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+### *class* AttributeFunctionalGridRange
+
+Attribute value class for range grid functional data.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### generate_series_version(create_empty=False)
+
+Convert this object to the equivalent series functional attribute value object and return the result.
+
+* **Parameters:**
+ **create_empty** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether to create an empty object. Default is [`False`](https://docs.python.org/3/library/constants.html#False).
+* **Returns:**
+ New instance of a series functional attribute value.
+* **Return type:**
+ [`AttributeFunctionalSeriesRange`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange)
+
+### Notes
+
+If `create_empty` is [`True`](https://docs.python.org/3/library/constants.html#True), an empty functional attribute value is returned.
+
+If `create_empty` is [`False`](https://docs.python.org/3/library/constants.html#False), the following information is copied to the new functional attribute value:
+
+* [`value`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange.value) (converted to [`SeriesRange`](supporting.md#ansys.grantami.core._mi_value_classes.SeriesRange))
+* [`unit`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange.unit)
+* [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange.parameters)
+* [`is_applicable`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue.is_applicable)
+
+
+
+#### with_new_x_axis(parameter_name, create_empty=False)
+
+Generate an empty attribute value of the same type with another parameter as X-axis.
+
+* **Parameters:**
+ * **parameter_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Name of the parameter to use as X-axis.
+ * **create_empty** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether to create an empty attribute value or copy existing data. Default is [`False`](https://docs.python.org/3/library/constants.html#False).
+* **Returns:**
+ New instance of functional attribute of identical type.
+* **Return type:**
+ [`AttributeFunctionalGridRange`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the name is not a valid parameter.
+
+### Notes
+
+If `create_empty` is [`True`](https://docs.python.org/3/library/constants.html#True), an empty functional attribute value is returned.
+
+If `create_empty` is [`False`](https://docs.python.org/3/library/constants.html#False), the following information is copied to the new functional attribute value:
+
+* [`unit`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange.unit)
+* [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange.parameters)
+* [`is_applicable`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue.is_applicable)
+
+
+
+#### *property* parameters *: mappingproxy[[str](https://docs.python.org/3/library/stdtypes.html#str), [FunctionalValueParameter](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter)]*
+
+Parameters associated with the functional data attribute, indexed by name.
+
+Modify the [`FunctionalValueParameter.unit`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.unit) property on the returned objects to specify a different unit
+for import.
+
+* **Returns:**
+ Read-only mapping of parameters associated with this functional value.
+* **Return type:**
+ [`MappingProxyType`](https://docs.python.org/3/library/types.html#types.MappingProxyType) [str, [`FunctionalValueParameter`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter)]
+
+
+
+#### *property* table_view *: [FunctionalGridRangeTableView](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalGridRangeTableView)*
+
+Supports additional read-only views of the attribute value.
+
+* **Return type:**
+ [`FunctionalGridRangeTableView`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalGridRangeTableView)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Unit symbol for the y-axis.
+
+For the x-axis parameter or constraint parameters, use [`unit`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.unit) on
+`FunctionalValueParameter` objects provided by the [`parameters`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange.parameters) property.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [GridRange](supporting.md#ansys.grantami.core._mi_value_classes.GridRange)*
+
+Current value of the attribute.
+
+Can be modified.
+
+#### Versionchanged
+Changed in version 5.0: This property now accepts as input and returns a structured representation of a functional attribute value.
+[`table_view`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange.table_view) provides properties to obtain the value in the format
+previously returned by this property.
+
+* **Return type:**
+ [`GridRange`](supporting.md#ansys.grantami.core._mi_value_classes.GridRange)
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a value that is not a GridRange object.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the value defines invalid parameter names.
+
+
+
+#### *property* x_axis *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the parameter used as the x-axis for the attribute value.
+
+Data exported from Granta MI may define a different x-axis parameter than the default x-axis parameter set in
+the attribute definition. To import data with a different x-axis parameter, use [`with_new_x_axis()`](#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange.with_new_x_axis).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+### *class* AttributeUnsupported
+
+Extended [`AttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class for attributes with unsupported data types.
+
+### Notes
+
+Unsupported attribute data will not yield any information regarding its value in that record. However,
+some meta-data is still available through this class (such as the attribute’s name and data type).
+An unsupported attribute value remains unpopulated, and these objects cannot be edited.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) to access instances of this class.
+
+
+
+#### is_empty()
+
+Checks whether the attribute value is populated.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* is_applicable *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the attribute is applicable to the current record.
+
+Setting this to [`False`](https://docs.python.org/3/library/constants.html#False) will clear any data values on the attribute on import.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+* **Raises:**
+ [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If attempting to set a non-boolean value.
+
+
+
+#### *property* object *: [UnsupportedType](supporting.md#ansys.grantami.core.mi_attribute_value_classes.UnsupportedType)*
+
+Gets the underlying [`UnsupportedType`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.UnsupportedType) object representing the attribute value or the tabular cell.
+
+Does not allow access to the data.
+
+* **Return type:**
+ [`UnsupportedType`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.UnsupportedType)
+
+
+
+#### *property* value *: [None](https://docs.python.org/3/library/constants.html#None)*
+
+This property always returns None for unsupported attribute values.
+
+
+
+### *class* PseudoAttributeValue
+
+Stores and provides access to pseudo-attribute data values.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.get_attributes()`](record.md#ansys.grantami.core.mi_record_classes.Record.get_attributes) to generate instances of this class.
+
+
+
+#### is_empty()
+
+Checks whether the pseudo-attribute value is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* id *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Attribute identifier (this is always 0 for pseudo-attributes).
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the pseudo-attribute.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* record *: [Record](record.md#ansys.grantami.core.mi_record_classes.Record)*
+
+Parent [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) described by the [`PseudoAttributeValue`](#ansys.grantami.core.mi_attribute_value_classes.PseudoAttributeValue).
+
+* **Return type:**
+ [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)
+
+
+
+#### *property* type *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Data type of the pseudo-attribute value (four-character string).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* value *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)] | [str](https://docs.python.org/3/library/stdtypes.html#str) | [int](https://docs.python.org/3/library/functions.html#int) | [bool](https://docs.python.org/3/library/functions.html#bool) | [set](https://docs.python.org/3/library/stdtypes.html#set)[[str](https://docs.python.org/3/library/stdtypes.html#str)] | [datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime) | [RecordColor](constants.md#ansys.grantami.core.mi_constants.RecordColor)*
+
+Current value of the pseudo-attribute.
+
+Cannot be modified. Modification of editable pseudo-attributes must be done through the [`Record.color`](record.md#ansys.grantami.core.mi_record_classes.Record.color),
+[`Record.short_name`](record.md#ansys.grantami.core.mi_record_classes.Record.short_name) and [`Record.name`](record.md#ansys.grantami.core.mi_record_classes.Record.name) properties.
+
+* **Return type:**
+ list[str] or str or int or bool or set[str] or datetime.datetime or [`RecordColor`](constants.md#ansys.grantami.core.mi_constants.RecordColor)
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/constants.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/constants.md
new file mode 100644
index 0000000000..a72fd1d39a
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/constants.md
@@ -0,0 +1,204 @@
+# Constants
+
+
+
+
+
+### *class* RecordProperties
+
+Provides [`PseudoAttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.PseudoAttributeDefinition) for every supported pseudo-attribute.
+
+Attribute names match the corresponding property on [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record).
+
+
+
+#### *classmethod* all()
+
+All pseudo-attribute definitions.
+
+* **Return type:**
+ list[[`PseudoAttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.PseudoAttributeDefinition)]
+
+
+
+#### color *= *
+
+
+
+#### created_by *= *
+
+
+
+#### created_on *= *
+
+
+
+#### history_identity *= *
+
+
+
+#### is_writable *= *
+
+
+
+#### last_modified_by *= *
+
+
+
+#### last_modified_on *= *
+
+
+
+#### name *= *
+
+
+
+#### parent_record_history_identity *= *
+
+
+
+#### parent_record_name *= *
+
+
+
+#### parent_record_short_name *= *
+
+
+
+#### released_on *= *
+
+
+
+#### short_name *= *
+
+
+
+#### subsets *= *
+
+
+
+#### table_name *= *
+
+
+
+#### type *= *
+
+
+
+#### version_number *= *
+
+
+
+### *class* RecordColor(value)
+
+
+
+#### Red *= 0*
+
+
+
+#### Maroon *= 1*
+
+
+
+#### Fuchsia *= 2*
+
+
+
+#### Yellow *= 3*
+
+
+
+#### Black *= 4*
+
+
+
+#### Gray *= 5*
+
+
+
+#### Aqua *= 6*
+
+
+
+#### Green *= 7*
+
+
+
+#### Navy *= 8*
+
+
+
+#### Purple *= 9*
+
+
+
+#### Blue *= 10*
+
+
+
+#### Silver *= 11*
+
+
+
+#### Lime *= 12*
+
+
+
+#### Olive *= 13*
+
+
+
+#### Teal *= 14*
+
+
+
+#### White *= 15*
+
+
+
+#### InheritFromParent *= 16*
+
+
+
+#### *property* safe_name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+
+
+### *class* RecordType(value)
+
+
+
+#### Record *= 'Record'*
+
+
+
+#### Folder *= 'Folder'*
+
+
+
+#### Generic *= 'Generic'*
+
+
+
+### DATABASE_CURRENCY
+
+Value used to refer to the ‘Database currency’
+
+
+
+### DATABASE_UNIT_SYSTEM
+
+Value used to refer to the ‘Database unit system’.
+
+
+
+### InterpolationType
+
+alias of [`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[‘None’, ‘Linear’, ‘Cubic Spline’]
+
+
+
+### ScaleType
+
+alias of [`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[‘Linear’, ‘Log’]
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/database.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/database.md
new file mode 100644
index 0000000000..b9638d8756
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/database.md
@@ -0,0 +1,362 @@
+# Database
+
+
+
+
+
+### *class* Database
+
+Represents an MI database, and provides access to its tables, unit systems, and record link groups.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use [`Session.get_db()`](session.md#ansys.grantami.core.mi.Session.get_db)
+to access an instance of this class.
+
+
+
+#### dimensionally_equivalent_units(unit)
+
+Returns all units which are dimensionally equivalent to the specified unit, with conversion factor and offset.
+
+* **Parameters:**
+ **unit** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The unit to find equivalent units for.
+* **Returns:**
+ Dictionary mapping unit symbols to their conversion factors and offsets.
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [float](https://docs.python.org/3/library/functions.html#float)]]
+
+### Notes
+
+Makes a single call to the Service Layer and caches the results.
+
+### Examples
+
+```pycon
+>>> db.dimensionally_equivalent_units(unit='kg')
+{'g': {'factor': 1000.0, 'offset': 0.0}}
+```
+
+
+
+#### get_record_by_id(hguid=None, vguid=None, history_identity=None, version_number=None)
+
+Returns the [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) object with the following (sets of) references in priority order.
+
+1. `vguid` (record version GUID): Uniquely identifies specific version of record.
+2. `history_identity` (record history identity): Uniquely identifies record only, and optionally
+ `version_number` (record version number).
+3. `hguid` (record history GUID): Uniquely identifies record only.
+
+If `vguid` or `version_number` are not provided for version controlled records, this method will
+return the latest available version of the record available to the user. The latest available version
+is dependent on the user’s Granta MI permissions.
+
+* **Parameters:**
+ * **hguid** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Record history GUID: uniquely identifies record.
+ * **vguid** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Record version GUID: uniquely identifies record version.
+ * **history_identity** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *optional*) – Record history identity.
+ * **version_number** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *optional*) – Record version number.
+* **Returns:**
+ Record object with the specified ID.
+* **Return type:**
+ [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### get_records_by_ids(record_identifiers)
+
+Returns a [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) object for each identifier provided.
+
+Each element in the `record_identifiers` parameter should be a dictionary with one or more of the
+following (sets of) references in priority order:
+
+1. `vguid` (record version GUID): Uniquely identifies specific version of record.
+2. `history_identity` (record history identity): Uniquely identifies record only, and optionally
+ `version_number` (record version number).
+3. `hguid` (record history GUID): Uniquely identifies record only.
+
+If `vguid` or `version_number` are not provided for version controlled records, this method will
+return the latest available version of the record available to the user. The latest available version
+is dependent on the user’s Granta MI permissions.
+
+The returned list of records will have the same number of elements as the provided list of identifiers.
+If no record corresponds to that identifier then the corresponding item in the returned list will be [`None`](https://docs.python.org/3/library/constants.html#None).
+
+* **Parameters:**
+ **record_identifiers** (*Sequence* *[*[*dict*](https://docs.python.org/3/library/stdtypes.html#dict) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* [*str*](https://docs.python.org/3/library/stdtypes.html#str) *|* [*int*](https://docs.python.org/3/library/functions.html#int) *]* *]*) – Sequence of dictionaries containing record identifiers.
+* **Return type:**
+ list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) | [`None`](https://docs.python.org/3/library/constants.html#None)]
+
+### Notes
+
+Makes multiple Service Layer calls depending on number of identifiers provided.
+
+
+
+#### get_table(name)
+
+Returns the [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table) object with the specified name.
+
+Case-insensitive.
+
+* **Parameters:**
+ **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Name of the table.
+* **Return type:**
+ [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table)
+* **Raises:**
+ [**KeyError**](https://docs.python.org/3/library/exceptions.html#KeyError) – If no table with the specified name exists in the database.
+
+
+
+#### get_table_by_guid(guid)
+
+Returns the [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table) object with the specified GUID.
+
+Case-insensitive.
+
+* **Parameters:**
+ **guid** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – GUID of the table.
+* **Return type:**
+ [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table)
+* **Raises:**
+ [**KeyError**](https://docs.python.org/3/library/exceptions.html#KeyError) – If no table with the specified GUID exists in the database.
+
+
+
+#### refetch_unit_systems()
+
+Fetches the unit systems associated with the database.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### refresh_tables()
+
+Performs a Foundation API [`BrowseService.get_tables()`](../foundation_api.md#ansys.grantami.backend.soap.BrowseService.BrowseService.get_tables) request and creates a new list of tables.
+
+Also updates the attributes in each table.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### search_for_records_by_name(name)
+
+Performs a search on record name across the database.
+
+Returns only the [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects whose short or long names are an exact match for `name`.
+Case-insensitive. This method searches in the currently active subsets for each table, and will raise
+an exception if a table has more than one active subset.
+
+* **Parameters:**
+ **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Name to search for.
+* **Return type:**
+ list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]
+
+### Notes
+
+Makes a Service Layer call for each table in the database.
+
+#### SEE ALSO
+[`Table.search_for_records_by_name()`](table.md#ansys.grantami.core.mi_tree_classes.Table.search_for_records_by_name)
+: Searches within a single table.
+
+
+
+#### search_for_records_by_text(text)
+
+Performs a simple text search across the database for the string provided.
+
+Returns a list of matching [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects. This method does not apply any subset filtering.
+
+* **Parameters:**
+ **text** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Text to search for.
+* **Return type:**
+ list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]
+
+### Notes
+
+Makes a Service Layer call for each table in the database.
+
+#### SEE ALSO
+[`Table.search_for_records_by_text()`](table.md#ansys.grantami.core.mi_tree_classes.Table.search_for_records_by_text)
+: Searches within a single table.
+
+
+
+#### search_for_records_where(list_of_criteria, silent=True)
+
+Performs a search using criteria within tables across the database.
+
+Use [`Table.search_for_records_where()`](table.md#ansys.grantami.core.mi_tree_classes.Table.search_for_records_where) to narrow your search to a single table.
+
+Criteria searches can be performed at the database level only if the provided `list_of_criteria` is not
+table specific, i.e. all criterion apply to pseudo-attributes.
+
+If any criterion is specific to an attribute, then the criterion is table specific and the search will be
+performed on the table.
+
+* **Parameters:**
+ * **list_of_criteria** (list[[`SearchCriterion`](supporting.md#ansys.grantami.core.mi_meta_classes.SearchCriterion)]) – List of search criteria.
+ * **silent** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: True*) – Whether to ignore errors caused by non-existent attributes.
+* **Returns:**
+ A list of Record objects that match the provided criteria.
+* **Return type:**
+ list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the `list_of_criteria` comprise criteria in multiple tables.
+ * [**KeyError**](https://docs.python.org/3/library/exceptions.html#KeyError) – If the search criteria include an attribute that does not exist in the database and `silent` is
+ [`False`](https://docs.python.org/3/library/constants.html#False).
+
+### Notes
+
+Makes a Service Layer call for each table in the database.
+
+Tabular column criteria are aggregated by column name when processed server-side, effectively restricting
+results to records where a single row must meet all criteria on the same column.
+
+To perform a search with multiple tabular column criteria defined on the same column, and obtain results
+where the criteria can be met by individual different rows, perform individual searches for each criterion
+and compute the intersection of the resulting lists of records.
+
+
+
+#### *property* absolute_temperatures *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the [`Database`](#ansys.grantami.core.mi_tree_classes.Database) uses absolute temperature units (Kelvin/Rankine) or not (Celsius/Fahrenheit).
+
+Default value is [`False`](https://docs.python.org/3/library/constants.html#False).
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* currency *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Database currency code.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* db_key *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Database key.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* guid *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+GUID of the database.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* mi *: [Session](session.md#ansys.grantami.core.mi.Session)*
+
+Granta MI Session used to create or access the [`Database`](#ansys.grantami.core.mi_tree_classes.Database) object.
+
+Used for any Service Layer calls made by the [`Database`](#ansys.grantami.core.mi_tree_classes.Database).
+
+* **Returns:**
+ The session object.
+* **Return type:**
+ [`Session`](session.md#ansys.grantami.core.mi.Session)
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the database.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* parameters *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [DatabaseParameter](supporting.md#ansys.grantami.core.mi_attribute_classes.DatabaseParameter)]*
+
+Parameters associated with the database, indexed by name.
+
+* **Return type:**
+ dict[str, [`DatabaseParameter`](supporting.md#ansys.grantami.core.mi_attribute_classes.DatabaseParameter)]
+
+
+
+#### *property* record_link_groups *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[LinkGroupDetails](supporting.md#ansys.grantami.core.mi_meta_classes.LinkGroupDetails)]*
+
+All record link groups in the database.
+
+* **Return type:**
+ list[[`LinkGroupDetails`](supporting.md#ansys.grantami.core.mi_meta_classes.LinkGroupDetails)]
+
+
+
+#### *property* tables *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[Table](table.md#ansys.grantami.core.mi_tree_classes.Table)]*
+
+Tables associated with the database.
+
+* **Return type:**
+ list[[`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table)]
+
+
+
+#### *property* tables_by_guid *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [Table](table.md#ansys.grantami.core.mi_tree_classes.Table)]*
+
+Tables in the database, as dictionary keyed by GUID.
+
+* **Return type:**
+ dict[str, [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table)]
+
+
+
+#### *property* tables_by_name *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [Table](table.md#ansys.grantami.core.mi_tree_classes.Table)]*
+
+Tables in the database, as dictionary keyed by name.
+
+* **Return type:**
+ dict[str, [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table)]
+
+
+
+#### *property* unit_system *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Currently selected unit system (default is [`DATABASE_UNIT_SYSTEM`](constants.md#ansys.grantami.core.mi_constants.DATABASE_UNIT_SYSTEM)).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* unit_systems_available *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+Names of unit systems associated with the database.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* version_guid *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Version GUID of the database.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/exceptions.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/exceptions.md
new file mode 100644
index 0000000000..9e37c2e8e2
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/exceptions.md
@@ -0,0 +1,40 @@
+# Exceptions
+
+
+
+
+
+### *class* UnsupportedLinkGroupError
+
+Raised when an operation is performed on a record link group which is incompatible with that operation.
+
+
+
+### *class* InvalidRecordStateError
+
+Raised when a record is in an invalid state for the requested operation.
+
+
+
+### *class* UnexportedBinaryDataError
+
+Raised when an operation requires binary data which has not been exported from the Granta MI database.
+
+
+
+# Warnings
+
+
+
+### *class* APIDeprecationWarning
+
+Warning displayed when a property, method, or function will be removed in a future release of MI Scripting Toolkit.
+
+Users should update their scripts to make use of new features and to avoid breaking changes when the deprecated API
+is removed.
+
+
+
+### *class* PrereleaseVersionWarning
+
+Warning displayed when a prerelease version of MI Scripting Toolkit is imported.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/helpers.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/helpers.md
new file mode 100644
index 0000000000..287232f8d2
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/helpers.md
@@ -0,0 +1,12 @@
+# Helper functions
+
+
+
+
+
+### get_foundation_logger()
+
+Return the logger used by the Foundation API (has the name “GDL”).
+
+* **Return type:**
+ [logging.Logger](https://docs.python.org/3/library/logging.html#logging.Logger)
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/api/index.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/index.md
similarity index 66%
rename from 2026R1/scripting-toolkit-dev-portal-26-r1/api/index.md
rename to 2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/index.md
index ec814f5464..5f6392813a 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/api/index.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/index.md
@@ -1,8 +1,8 @@
-# API reference
+# Streamlined API reference
-
+
-Reference documentation for the Scripting Toolkit API.
+Reference documentation for the Streamlined API.
* [Session](session.md)
* [Database](database.md)
@@ -11,7 +11,7 @@ Reference documentation for the Scripting Toolkit API.
* [Record](record.md)
* [Attribute values](attribute-values.md)
* [Schema and supporting items](supporting.md)
-* [Bulk operators](bulk-operators.md)
+* [Tabular attribute value items](tabular.md)
* [Helper functions](helpers.md)
* [Constants](constants.md)
* [Exceptions](exceptions.md)
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/record.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/record.md
new file mode 100644
index 0000000000..109729c8d9
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/record.md
@@ -0,0 +1,1023 @@
+# Record
+
+
+
+
+
+
+
+### *class* Record
+
+Represents a Granta MI record.
+
+May represent an existing Granta MI record, or a record which is staged for import.
+
+Stores and provides access to record attributes, pseudo-attributes, links and children. Provides methods for adding,
+editing and deleting records, and importing and exporting record data.
+
+* **Parameters:**
+ * **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Long name for new records.
+ * **table** ([`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table)) – Table object.
+ * **parent** ([`Record`](#ansys.grantami.core.mi_record_classes.Record) or [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table), optional) – Parent record or table object.
+ * **short_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Short (tree) name for new records.
+ * **attributes** (dict[str, [`AttributeValue`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue)], optional) – Dictionary of attribute values.
+ * **subsets** ([*set*](https://docs.python.org/3/library/stdtypes.html#set) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]* *,* *optional*) – Subsets the record belongs to.
+ * **folder** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether the record is ‘Folder’ type.
+ * **record_color** ([`RecordColor`](constants.md#ansys.grantami.core.mi_constants.RecordColor), optional) – Color of the record.
+ * **release_record** (bool, default: [`True`](https://docs.python.org/3/library/constants.html#True)) – Release state of the record; [`True`](https://docs.python.org/3/library/constants.html#True) to release next version.
+
+#### WARNING
+Do not create [`Record`](#ansys.grantami.core.mi_record_classes.Record) instances for records which are already in the database. Use the appropriate
+[`Session`](session.md#ansys.grantami.core.mi.Session), [`Database`](database.md#ansys.grantami.core.mi_tree_classes.Database), [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table), or [`Record`](#ansys.grantami.core.mi_record_classes.Record) methods and properties to access existing
+records.
+
+### Notes
+
+[`Record`](#ansys.grantami.core.mi_record_classes.Record) objects may be created to represent records that do not currently exist in the database.
+
+A name and parent table must be specified. `name` will become the record’s long name. The record short name
+(or tree name) can be set via the argument `short_name`, or via the [`Record.short_name`](#ansys.grantami.core.mi_record_classes.Record.short_name) property following
+object creation. If a record is pushed to Granta MI without a specifying short name, the short name will default to
+the record name.
+
+Records created this way will not exist in the specified database until the changes have been pushed to Granta MI
+(see [`Session.update()`](session.md#ansys.grantami.core.mi.Session.update)).
+
+
+
+#### clear_attributes(attributes)
+
+Flags attribute values to be deleted when [`Session.update()`](session.md#ansys.grantami.core.mi.Session.update) is next called.
+
+Does not delete the local value of flagged attributes, only the data on Granta MI. Supersedes previous
+[`set_attributes()`](#ansys.grantami.core.mi_record_classes.Record.set_attributes) calls.
+
+* **Parameters:**
+ **attributes** (*Iterable* *[*[*AttributeValue*](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) *]*) – Attributes to clear on the record.
+
+
+
+#### copy_to(destination, record_name=None, release=False)
+
+Creates a copy of the record at the provided location.
+
+Returns a record object that represents the newly created record. The resulting record is added to the
+same subsets as the original record, and contains identical attribute values.
+
+* **Parameters:**
+ * **destination** ([`Record`](#ansys.grantami.core.mi_record_classes.Record) or [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table)) – Location in the tree where to create the copy.
+ * **record_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Record name for the created record. By default, the copied record is created with the same name as the
+ original record. If the destination already contains a record with an identical name, use this parameter to
+ override the name.
+ * **release** (bool, default: [`False`](https://docs.python.org/3/library/constants.html#False)) – Whether to release the created record. The argument has no effect for records in tables that are not
+ version-controlled.
+* **Return type:**
+ [Record](#ansys.grantami.core.mi_record_classes.Record)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+#### WARNING
+Data validation rules, such as attribute value uniqueness, might prevent record copying.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### decache_attributes()
+
+Removes all attribute values from the [`Record`](#ansys.grantami.core.mi_record_classes.Record).
+
+
+
+#### decache_links()
+
+Removes all links from the [`Record`](#ansys.grantami.core.mi_record_classes.Record).
+
+
+
+#### delete_or_withdraw_record_on_server(withdrawal_notes=None)
+
+Deletes the record from the server, or withdraws it from a version-controlled table.
+
+* **Parameters:**
+ **withdrawal_notes** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Withdrawal revision notes.
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### find_parent()
+
+Finds and sets the parent record or table.
+
+* **Raises:**
+ * [**PermissionError**](https://docs.python.org/3/library/exceptions.html#PermissionError) – If parent record cannot be accessed due to access control.
+ * [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the parent has not already been fetched.
+
+This operation performs no subset filtering because, by definition, the parent record must belong to all subsets
+that this record belongs to.
+
+
+
+#### get_associated_records(target_table, link_direction='Both', attribute_path=None)
+
+Gets records `target_table` linked to the current [`Record`](#ansys.grantami.core.mi_record_classes.Record) object via tabular data association chains.
+
+This can be filtered by link direction and to a specific path.
+
+If `attribute_path` is provided, then only records from that exact path will be returned. Note that the
+specified tabular attributes will be the ‘source’ of the tabular link, and there may be tables in the chain
+with no attributes.
+
+This operation performs no subset filtering.
+
+* **Parameters:**
+ * **target_table** ([`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table)) – The table from which to retrieve associated records.
+ * **link_direction** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *default: "Both"*) – Which direction to follow links in: `Both` (default), `Forward`, `Reverse`.
+ * **attribute_path** (list[[`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)], optional) – Path of tabular attributes to follow. If [`None`](https://docs.python.org/3/library/constants.html#None), all paths are followed.
+* **Return type:**
+ list[[`Record`](#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### get_attributes(names=None, types=None, include_attributes=True, include_meta_attributes=False, include_pseudo_attributes=False, empty=None)
+
+Retrieve a list of attributes from the `record.attributes` dictionary.
+
+You can narrow the results by specifying the attribute names or data types, or the required attribute categories
+(attribute, meta-attribute, or pseudo-attribute).
+
+If the `record.attributes` dictionary is empty when `get_attributes` is called, it will be populated before
+retrieving any attributes.
+
+This operation performs no subset filtering, so all tabular rows will be included in the response regardless of
+the subset membership of the linked records.
+
+#### Versionchanged
+Changed in version 4.2: Argument `include_metas` was renamed to `include_meta_attributes`.
+
+#### Versionchanged
+Changed in version 4.2: Argument `include_pseudos` was renamed to `include_pseudo_attributes`.
+
+* **Parameters:**
+ * **names** ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]* *,* *optional*) – Attribute names.
+ * **types** ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]* *,* *optional*) – Attribute data types; allowed values are: `DISC`, `DTTM`, `FILE`, `FUNC`, `HLNK`, `INPT`,
+ `LOGI`, `LTXT`, `PICT`, `POIN`, `RNGE`, `STXT`, `TABL`.
+ * **include_attributes** (bool, default: [`True`](https://docs.python.org/3/library/constants.html#True)) – Whether to retrieve attributes that are not meta-attributes or pseudo-attributes.
+ * **include_meta_attributes** (bool, default: [`False`](https://docs.python.org/3/library/constants.html#False)) – Whether to retrieve meta-attributes.
+ * **include_pseudo_attributes** (bool, default: [`False`](https://docs.python.org/3/library/constants.html#False)) – Whether to retrieve pseudo-attributes.
+ * **empty** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether to filter by whether an attribute is populated or not. If [`None`](https://docs.python.org/3/library/constants.html#None), both populated and empty
+ attributes are returned.
+* **Return type:**
+ list[[`PseudoAttributeValue`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.PseudoAttributeValue) or [`AttributeValue`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue)]
+
+### Examples
+
+The code below returns all point or functional series attributes or meta-attributes named Density or
+Stress-Strain:
+
+```python
+r.get_attributes(names=['Density', 'Stress-Strain'], types=['POIN', 'FUNC'], include_meta_attributes=True)
+```
+
+
+
+#### get_available_exporters(package=None, model=None, applicability_tag=None)
+
+Returns exporters available for this record filtered by package, model, and applicability tag value.
+
+* **Parameters:**
+ * **package** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Name of target FEA analysis package, for example ‘NX 10.0’ or ‘CATIA V5’.
+ * **model** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Material model type, for example ‘Isotropic’ or ‘Linear, temperature-independent,
+ isotropic, thermal, plastic’.
+ * **applicability_tag** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Tag that identifies the MI applications an exporter is intended to be used with,
+ for example, ‘MIMaterialsGateway’ or ‘MIViewer’.
+* **Return type:**
+ list[[`Exporter`](supporting.md#ansys.grantami.core.mi_exporters.Exporter)]
+
+### Notes
+
+Makes a Service Layer call on first request for each applicability tag.
+
+
+
+#### get_descendants(include_folders=False, include_generics=True, filter_by_subset=True, subset_name=None)
+
+Returns a flattened list of all descendants of a record.
+
+Populates the [`children`](#ansys.grantami.core.mi_record_classes.Record.children) property of each [`Record`](#ansys.grantami.core.mi_record_classes.Record) object traversed in the process.
+
+If `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) then the operation will only return records that are in the subset given
+in `subset_name`, if no value is provided then the subset specified on the table will be used.
+
+If `filter_by_subset` is [`False`](https://docs.python.org/3/library/constants.html#False) then records will be returned from all subsets.
+
+* **Parameters:**
+ * **include_folders** (bool, default: [`False`](https://docs.python.org/3/library/constants.html#False)) – Whether to include folders in the list of descendants.
+ * **include_generics** (bool, default: [`True`](https://docs.python.org/3/library/constants.html#True)) – Whether to include generic records in the list of descendants.
+ * **filter_by_subset** (bool, default: [`True`](https://docs.python.org/3/library/constants.html#True)) – Whether to filter by subset.
+ * **subset_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Name of the subset to use for filtering.
+* **Return type:**
+ list[[`Record`](#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If more than one subset is applied to the table when `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) and `subset_name`
+ is not provided.
+ * [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### move_to(new_parent)
+
+Moves the record and all its descendants to a new parent.
+
+The provided new parent must be a [`Record`](#ansys.grantami.core.mi_record_classes.Record) of type [`RecordType.Folder`](constants.md#ansys.grantami.core.mi_constants.RecordType.Folder) or
+[`RecordType.Generic`](constants.md#ansys.grantami.core.mi_constants.RecordType.Generic), or a [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table) to move the record at the root of the table.
+
+* **Parameters:**
+ **new_parent** ([`Record`](#ansys.grantami.core.mi_record_classes.Record) or [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table))
+
+### Notes
+
+Some cached properties are cleared after the record has been moved, as they would be out-of-date:
+
+* pseudo-attribute properties
+* [`Record.path`](#ansys.grantami.core.mi_record_classes.Record.path)
+* [`Record.parent`](#ansys.grantami.core.mi_record_classes.Record.parent)
+
+They will be dynamically retrieved from the server on property access, or can be manually refreshed via the
+following methods:
+
+* [`Record.refetch_pseudo_attributes()`](#ansys.grantami.core.mi_record_classes.Record.refetch_pseudo_attributes)
+* [`Record.refresh_path()`](#ansys.grantami.core.mi_record_classes.Record.refresh_path)
+* [`Record.find_parent()`](#ansys.grantami.core.mi_record_classes.Record.find_parent)
+* [`Record.refresh_properties()`](#ansys.grantami.core.mi_record_classes.Record.refresh_properties)
+
+[`Record.children`](#ansys.grantami.core.mi_record_classes.Record.children) is not cleared, because children are moved with the parent. Their internal state might
+be outdated, and if necessary can be updated via the methods listed above.
+
+`children` properties of the source and target parent are not cleared or updated. This is by design, to
+prevent unnecessary updates in scripts performing a large number of record move operations.
+
+To update the list of children of a table (after moving a child record from it or to it), use the method
+[`Table.refetch_children()`](table.md#ansys.grantami.core.mi_tree_classes.Table.refetch_children).
+
+To update the list of children of a record (after moving a child record from it or to it), use the method
+[`Record.refetch_children()`](#ansys.grantami.core.mi_record_classes.Record.refetch_children).
+
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### refetch_children(filter_by_subset=True, subset_name=None)
+
+Refreshes the list of children belonging to the record.
+
+If `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) then the operation will only return records that are in the subset given in
+`subset_name`, if no value is provided then the subset specified on the table will be used.
+
+If `filter_by_subset` is [`False`](https://docs.python.org/3/library/constants.html#False) then records will be returned from all subsets.
+
+* **Parameters:**
+ * **filter_by_subset** (bool, default: [`True`](https://docs.python.org/3/library/constants.html#True)) – Whether to filter by subset.
+ * **subset_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Name of the subset to use for filtering.
+* **Raises:**
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If more than one subset is applied to the table when `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) and `subset_name`
+ is not provided.
+ * [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### refetch_pseudo_attributes()
+
+Fetches pseudo-attribute data for this record, and updates subsets for the record if not set.
+
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### refetch_record_release_state()
+
+Fetches the record’s release state from the server.
+
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### refetch_record_versions()
+
+Refetches version information and all visible versions of the record for this user.
+
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### refresh_attributes()
+
+Updates the [`Record`](#ansys.grantami.core.mi_record_classes.Record) object if they have changed on the server.
+
+Can also be used to populate attributes.
+
+Always includes binary data in the response. Use the [`bulk_fetch()`](table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) method if URL data
+representation is required.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### refresh_path()
+
+Re-calculates the record path within the current table.
+
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+This operation performs no subset filtering because, by definition, the parent record must belong to all subsets
+that this record belongs to.
+
+Makes a Service Layer call.
+
+
+
+#### refresh_properties()
+
+Refreshes the Foundation API [`ansys.grantami.backend.soap.TreeRecord`](../foundation_api.md#module-ansys.grantami.backend.soap.TreeRecord) object associated with the
+[`Record`](#ansys.grantami.core.mi_record_classes.Record), if it has one.
+
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### set_attributes(attributes)
+
+Flags attribute values to update on the server when [`Session.update()`](session.md#ansys.grantami.core.mi.Session.update) is next called.
+
+If attribute values are not supplied to this method, changes to those attributes will not be transferred to
+Granta MI.
+
+* **Parameters:**
+ **attributes** (*Iterable* *[*[*AttributeValue*](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) *]*) – Attributes to set on the record.
+
+#### SEE ALSO
+[`clear_attributes()`](#ansys.grantami.core.mi_record_classes.Record.clear_attributes)
+: Flags attribute values to be deleted when [`Session.update()`](session.md#ansys.grantami.core.mi.Session.update) is next called.
+
+
+
+#### set_links(link_name, records)
+
+Adds the specified records to the named record link group and flags those links for update.
+
+Links that are not set through this method will not be updated on the server.
+
+* **Parameters:**
+ * **link_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Link group name to be updated.
+ * **records** (Iterable[[`Record`](#ansys.grantami.core.mi_record_classes.Record)]) – Records to add to the link group.
+
+
+
+#### *property* all_versions *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [Record](#ansys.grantami.core.mi_record_classes.Record)]*
+
+Returns all versions or the record as dictionary of [`Record`](#ansys.grantami.core.mi_record_classes.Record) objects.
+
+The dictionary is indexed by the version number in the form ‘v#’, for example ‘v1’ or ‘v2’. In a version
+controlled table there is an entry for each version of the record in Granta MI. In a non-version controlled
+table there is a single entry with the key ‘v0’.
+
+* **Return type:**
+ dict[str, [`Record`](#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the [`refetch_record_versions()`](#ansys.grantami.core.mi_record_classes.Record.refetch_record_versions) method has not already been called on
+this record.
+
+
+
+#### *property* attributes *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [AttributeValue](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue)]*
+
+Attributes associated with the record, indexed by attribute name.
+
+* **Return type:**
+ dict[str, [`AttributeValue`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue)]
+
+#### SEE ALSO
+[`Table.bulk_fetch()`](table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch)
+: Fetch attributes for multiple records in a single call.
+
+### Notes
+
+Makes a Service Layer call if the `record.attributes` dictionary is empty when accessed.
+
+
+
+#### *property* children *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[Record](#ansys.grantami.core.mi_record_classes.Record)]*
+
+Records that are direct children of the current record.
+
+Records returned by this property may have been cached from previous calls to [`Record.get_descendants()`](#ansys.grantami.core.mi_record_classes.Record.get_descendants),
+[`Record.refetch_children()`](#ansys.grantami.core.mi_record_classes.Record.refetch_children) or [`Table.all_records()`](table.md#ansys.grantami.core.mi_tree_classes.Table.all_records), which all apply subset filtering. If the
+[`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table) subset configuration has since been updated, refresh the list of children via one of the methods
+listed.
+
+If there is no cached list of children, children are dynamically fetched on property access via
+[`refetch_children()`](#ansys.grantami.core.mi_record_classes.Record.refetch_children). The default subset filtering behavior is applied.
+
+* **Return type:**
+ list[[`Record`](#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If more than one subset is applied to the table when dynamically retrieving children records.
+ * [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if there is no cached list of children.
+
+
+
+#### *property* color *: [RecordColor](constants.md#ansys.grantami.core.mi_constants.RecordColor)*
+
+Color of the record when displayed in MI Viewer and other Granta MI applications.
+
+If the [`Record`](#ansys.grantami.core.mi_record_classes.Record) object represents an existing record:
+
+* The `color` property will initially return the exported color of the record. It will be fetched if it has
+ not already been exported.
+* If `color` is modified, the [`Record`](#ansys.grantami.core.mi_record_classes.Record) color will be set to the specified value.
+* If `color` is set to [`None`](https://docs.python.org/3/library/constants.html#None), the [`Record`](#ansys.grantami.core.mi_record_classes.Record) color will be reset to the exported value.
+
+If the [`Record`](#ansys.grantami.core.mi_record_classes.Record) object represents a new record:
+
+* The `color` property will initially return the value specified in the [`Record`](#ansys.grantami.core.mi_record_classes.Record) constructor. If not
+ set, it will default to the value `InheritFromParent`.
+* If `color` is modified, the [`Record`](#ansys.grantami.core.mi_record_classes.Record) color will be set to the specified value.
+* If `color` is set to [`None`](https://docs.python.org/3/library/constants.html#None), the [`Record`](#ansys.grantami.core.mi_record_classes.Record) color will be set to the value `InheritFromParent`.
+
+* **Return type:**
+ [`RecordColor`](constants.md#ansys.grantami.core.mi_constants.RecordColor)
+
+### Notes
+
+Makes a Service Layer call if the record exists on the server and the color has not already been fetched.
+
+If a [`Record`](#ansys.grantami.core.mi_record_classes.Record) is imported with `color` set to [`None`](https://docs.python.org/3/library/constants.html#None), the record will inherit the color of the
+parent record.
+
+
+
+#### *property* created_by *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+User who created the record.
+
+Read-only property. This property is populated from a pseudo-attribute value and can be refreshed via
+[`refetch_pseudo_attributes()`](#ansys.grantami.core.mi_record_classes.Record.refetch_pseudo_attributes).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the pseudo-attributes have not yet been fetched for this record.
+
+
+
+#### *property* created_on *: [datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)*
+
+Datetime of the record creation.
+
+Read-only property. This property is populated from a pseudo-attribute value and can be refreshed via
+[`refetch_pseudo_attributes()`](#ansys.grantami.core.mi_record_classes.Record.refetch_pseudo_attributes).
+
+* **Return type:**
+ [datetime.datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the pseudo-attributes have not yet been fetched for this record.
+
+
+
+#### *property* data_revision_history *: Dict[[str](https://docs.python.org/3/library/stdtypes.html#str), [DataRevisionHistory](supporting.md#ansys.grantami.core.mi_meta_classes.DataRevisionHistory)]*
+
+Data revision history for all attributes, indexed by attribute name.
+
+* **Return type:**
+ dict[str, [`DataRevisionHistory`](supporting.md#ansys.grantami.core.mi_meta_classes.DataRevisionHistory)]
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the data revision history has not already been fetched for this record.
+
+
+
+#### *property* db_key *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Database key for the database the record belongs to.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* exists_on_server *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the record exists on the server ([`True`](https://docs.python.org/3/library/constants.html#True)) or has been created in memory ([`False`](https://docs.python.org/3/library/constants.html#False)).
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* flag_for_release *: [bool](https://docs.python.org/3/library/functions.html#bool) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Whether the record will be made available to users when it is next updated.
+
+* [`True`](https://docs.python.org/3/library/constants.html#True) (default): If changes were made to the [`Record`](#ansys.grantami.core.mi_record_classes.Record), a new version will be created and then
+ immediately released. If changes were not made to the [`Record`](#ansys.grantami.core.mi_record_classes.Record), the existing version will be released.
+* [`False`](https://docs.python.org/3/library/constants.html#False): If changes were made to the [`Record`](#ansys.grantami.core.mi_record_classes.Record), a new, unreleased version will be created. The
+ record will not be released.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool) or None
+
+### Notes
+
+If you do not have the correct permissions to change release states, setting this property will not have the
+documented effect. See the Service Layer documentation for more details.
+
+
+
+#### *property* history_guid *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Record history GUID.
+
+* **Returns:**
+ [`None`](https://docs.python.org/3/library/constants.html#None) for records that do not exist on the server.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+Records in unversioned tables can be uniquely identified by their record history GUID.
+
+For records in versioned tables, the record history guid refers to the latest version of the record the user has
+access to.
+
+
+
+#### *property* history_identity *: [int](https://docs.python.org/3/library/functions.html#int) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Record history identity.
+
+* **Returns:**
+ [`None`](https://docs.python.org/3/library/constants.html#None) for records that do not exist on the server.
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int) or None
+
+### Notes
+
+Do not use, use [`history_guid`](#ansys.grantami.core.mi_record_classes.Record.history_guid) instead.
+
+
+
+#### *property* is_folder *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the record is a [`RecordType.Folder`](constants.md#ansys.grantami.core.mi_constants.RecordType.Folder) type.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* is_writable *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the current user has write permissions on the record.
+
+Read-only property. This property is populated from a pseudo-attribute value and can be refreshed via
+[`refetch_pseudo_attributes()`](#ansys.grantami.core.mi_record_classes.Record.refetch_pseudo_attributes).
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the pseudo-attributes have not yet been fetched for this record.
+
+
+
+#### *property* last_modified_by *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+User who last modified the record.
+
+Read-only property. This property is populated from a pseudo-attribute value and can be refreshed via
+[`refetch_pseudo_attributes()`](#ansys.grantami.core.mi_record_classes.Record.refetch_pseudo_attributes).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the pseudo-attributes have not yet been fetched for this record.
+
+
+
+#### *property* last_modified_on *: [datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)*
+
+Datetime of the last modification.
+
+Read-only property. This property is populated from a pseudo-attribute value and can be refreshed via
+[`refetch_pseudo_attributes()`](#ansys.grantami.core.mi_record_classes.Record.refetch_pseudo_attributes).
+
+* **Return type:**
+ [datetime.datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the pseudo-attributes have not yet been fetched for this record.
+
+
+
+#### *property* links *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [Set](https://docs.python.org/3/library/typing.html#typing.Set)[[Record](#ansys.grantami.core.mi_record_classes.Record)]]*
+
+Link groups for this [`Record`](#ansys.grantami.core.mi_record_classes.Record) object, and the records they link to.
+
+Smart links may be viewed but not edited through the `links` property.
+
+This operation performs no subset filtering.
+
+* **Return type:**
+ dict[str, set[[`Record`](#ansys.grantami.core.mi_record_classes.Record)]]
+
+
+
+#### *property* mi *: [Session](session.md#ansys.grantami.core.mi.Session)*
+
+Session used to create or access the record.
+
+Used for any Service Layer calls made by the [`Record`](#ansys.grantami.core.mi_record_classes.Record) object.
+
+* **Return type:**
+ [`Session`](session.md#ansys.grantami.core.mi.Session)
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Long name of record.
+
+If the [`Record`](#ansys.grantami.core.mi_record_classes.Record) object represents an existing record:
+
+* The property will initially return the exported name of the record. It will be fetched if it has not already
+ been exported.
+* If the property is modified, the [`Record`](#ansys.grantami.core.mi_record_classes.Record) name will be set to the specified value.
+* If the property is set to [`None`](https://docs.python.org/3/library/constants.html#None), the [`Record`](#ansys.grantami.core.mi_record_classes.Record) name will be reset to the exported value.
+
+If the [`Record`](#ansys.grantami.core.mi_record_classes.Record) object represents a new record:
+
+* The property will initially return the value specified in the [`Record`](#ansys.grantami.core.mi_record_classes.Record) constructor.
+* If the property is modified, the [`Record`](#ansys.grantami.core.mi_record_classes.Record) name will be set to the specified value.
+* If the property is set to [`None`](https://docs.python.org/3/library/constants.html#None), the [`Record`](#ansys.grantami.core.mi_record_classes.Record) name will be set to [`None`](https://docs.python.org/3/library/constants.html#None).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+### Notes
+
+If a [`Record`](#ansys.grantami.core.mi_record_classes.Record) is imported with `name` set to [`None`](https://docs.python.org/3/library/constants.html#None), a `ValueError` is raised.
+
+
+
+#### *property* parent *: [Record](#ansys.grantami.core.mi_record_classes.Record) | [Table](table.md#ansys.grantami.core.mi_tree_classes.Table)*
+
+Parent record or table of this record.
+
+* **Return type:**
+ [`Record`](#ansys.grantami.core.mi_record_classes.Record), [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table), or [`None`](https://docs.python.org/3/library/constants.html#None)
+* **Raises:**
+ * [**PermissionError**](https://docs.python.org/3/library/exceptions.html#PermissionError) – If parent record cannot be accessed due to access control.
+ * [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the parent has not already been fetched.
+
+
+
+#### *property* parent_record_history_identity *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+History identity of the parent record.
+
+If the record is at the root of the table, returns the history identity of the table root node.
+
+Read-only property. This property is populated from a pseudo-attribute value and can be refreshed via
+[`refetch_pseudo_attributes()`](#ansys.grantami.core.mi_record_classes.Record.refetch_pseudo_attributes).
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the pseudo-attributes have not yet been fetched for this record.
+
+
+
+#### *property* parent_record_name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the parent record.
+
+If the record is at the root of the table, returns the name of the table.
+
+Read-only property. This property is populated from a pseudo-attribute value and can be refreshed via
+[`refetch_pseudo_attributes()`](#ansys.grantami.core.mi_record_classes.Record.refetch_pseudo_attributes).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the pseudo-attributes have not yet been fetched for this record.
+
+
+
+#### *property* parent_record_short_name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Short name of the parent record.
+
+If the record is at the root of the table, returns the name of the table.
+
+Read-only property. This property is populated from a pseudo-attribute value and can be refreshed via
+[`refetch_pseudo_attributes()`](#ansys.grantami.core.mi_record_classes.Record.refetch_pseudo_attributes).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the pseudo-attributes have not yet been fetched for this record.
+
+
+
+#### *property* path *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+Browse tree path for the record as a list of folder short names.
+
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+### Notes
+
+Makes a Service Layer call if the path has not already been fetched.
+
+
+
+#### *property* record_guid *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Record version GUID.
+
+* **Returns:**
+ [`None`](https://docs.python.org/3/library/constants.html#None) for records that do not exist on the server.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+Records in unversioned and versioned tables can be uniquely identified by their record version GUID.
+
+For records in versioned tables, the record version guid refers to a specific version of a record.
+
+
+
+#### *property* record_history *: [RecordVersionHistory](supporting.md#ansys.grantami.core.mi_meta_classes.RecordVersionHistory)*
+
+Details about the record history.
+
+Includes user, datetime, and notes associated with events of the record’s life cycle.
+
+* **Return type:**
+ [`RecordVersionHistory`](supporting.md#ansys.grantami.core.mi_meta_classes.RecordVersionHistory)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the [`refetch_record_release_state()`](#ansys.grantami.core.mi_record_classes.Record.refetch_record_release_state) method has not already been called on
+this record.
+
+
+
+#### *property* release_state *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Release state of the record.
+
+Allowed values are `Released`, `Superseded`, `Withdrawn`, `Unreleased`, `Unversioned` or `Unknown`.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the [`refetch_record_release_state()`](#ansys.grantami.core.mi_record_classes.Record.refetch_record_release_state) method has not already been called on
+this record.
+
+
+
+#### *property* released_on *: [datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)*
+
+Datetime of the record release.
+
+Read-only property. This property is populated from a pseudo-attribute value and can be refreshed via
+[`refetch_pseudo_attributes()`](#ansys.grantami.core.mi_record_classes.Record.refetch_pseudo_attributes).
+
+* **Return type:**
+ [datetime.datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the pseudo-attributes have not yet been fetched for this record.
+
+
+
+#### *property* short_name *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Short (tree) name of the record.
+
+If the [`Record`](#ansys.grantami.core.mi_record_classes.Record) object represents an existing record:
+
+* The `short_name` property will initially return the exported short name of the record. It will be fetched if
+ it has not already been exported.
+* If `short_name` is modified, the [`Record`](#ansys.grantami.core.mi_record_classes.Record) short name will be set to the specified value.
+* If `short_name` is set to [`None`](https://docs.python.org/3/library/constants.html#None), the [`Record`](#ansys.grantami.core.mi_record_classes.Record) short name will be reset to the exported value.
+
+If the [`Record`](#ansys.grantami.core.mi_record_classes.Record) object represents a new record:
+
+* The `short_name` property will initially return the value specified in the [`Record`](#ansys.grantami.core.mi_record_classes.Record) constructor.
+* If `short_name` is modified, the [`Record`](#ansys.grantami.core.mi_record_classes.Record) short name will be set to the specified value.
+* If `short_name` is set to [`None`](https://docs.python.org/3/library/constants.html#None), the [`Record`](#ansys.grantami.core.mi_record_classes.Record) short name will be set to [`None`](https://docs.python.org/3/library/constants.html#None).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str), optional
+
+### Notes
+
+Makes a Service Layer call if the record exists on the server and the short name has not already been fetched.
+
+If a [`Record`](#ansys.grantami.core.mi_record_classes.Record) is imported with `short_name` set to [`None`](https://docs.python.org/3/library/constants.html#None), the short name will default to the
+record name.
+
+
+
+#### *property* subsets *: [Set](https://docs.python.org/3/library/typing.html#typing.Set)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+Subsets that the record belongs to.
+
+* **Return type:**
+ [set](https://docs.python.org/3/library/stdtypes.html#set)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+### Notes
+
+Makes a Service Layer call if the record exists on the server and the subsets have not already been fetched.
+
+
+
+#### *property* table *: [Table](table.md#ansys.grantami.core.mi_tree_classes.Table)*
+
+Parent table the record belongs to.
+
+* **Return type:**
+ [`Table`](table.md#ansys.grantami.core.mi_tree_classes.Table)
+
+
+
+#### *property* table_name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of parent table.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* type *: [RecordType](constants.md#ansys.grantami.core.mi_constants.RecordType)*
+
+Record type.
+
+On record creation via the MI Scripting Toolkit, the record type can only be set to [`RecordType.Folder`](constants.md#ansys.grantami.core.mi_constants.RecordType.Folder)
+or [`RecordType.Record`](constants.md#ansys.grantami.core.mi_constants.RecordType.Record). The type of an existing record cannot be set via this property.
+
+Adding children to a record, or populating attributes on a folder both result in the type updating to
+[`RecordType.Generic`](constants.md#ansys.grantami.core.mi_constants.RecordType.Generic) during the update.
+
+* **Return type:**
+ [RecordType](constants.md#ansys.grantami.core.mi_constants.RecordType)
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the record exists on the server and an attempt is made to change its type. If this property is set to
+ [`RecordType.Generic`](constants.md#ansys.grantami.core.mi_constants.RecordType.Generic).
+
+
+
+#### *property* version_number *: [int](https://docs.python.org/3/library/functions.html#int) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Record version number.
+
+This is set to None if the record is in a non version-controlled table.
+
+Read-only property. This property is populated from a pseudo-attribute value and can be refreshed via
+[`refetch_pseudo_attributes()`](#ansys.grantami.core.mi_record_classes.Record.refetch_pseudo_attributes).
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int) or None
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call if the pseudo-attributes have not yet been fetched for this record.
+
+
+
+#### *property* viewer_url *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The MI Viewer URL for the record.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the record has not been pushed to the server.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/session.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/session.md
new file mode 100644
index 0000000000..feb0282162
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/session.md
@@ -0,0 +1,519 @@
+# Session
+
+
+
+
+
+
+
+### *class* Session
+
+Represents a Granta MI Session.
+
+Allows the MI Scripting Toolkit to make calls to the Service Layer, and provides access to and search functions for
+available databases.
+
+Use [`SessionBuilder`](#ansys.grantami.core.mi.SessionBuilder) to create a session and authenticate via one of the supported modes of authentication.
+
+### Examples
+
+Authenticating using Windows authentication
+
+```pycon
+>>> session = SessionBuilder(
+... service_layer_url="https://my_server_name/mi_servicelayer",
+... ).with_autologon()
+```
+
+Authenticating using credentials and setting timeout and retries
+
+```pycon
+>>> session = SessionBuilder(
+... service_layer_url="https://my_server_name/mi_servicelayer",
+... session_configuration=SessionConfiguration(
+... timeout=200000,
+... max_retries=1,
+... )
+... ).with_credentials(username="username", password="password")
+```
+
+
+
+#### bulk_delete_or_withdraw_records(records, batch_size=100, parallelize=False, max_num_threads=6, update_release_states=False, withdrawal_notes=None)
+
+Deletes records from the server (or withdraws them, if in a version-controlled table).
+
+Record release states can also be updated using this method.
+
+#### Versionchanged
+Changed in version 4.2: Argument `parallelise` was renamed to `parallelize`.
+
+* **Parameters:**
+ * **records** ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*Record*](record.md#ansys.grantami.core.mi_record_classes.Record) *]*) – List of records to delete or withdraw.
+ * **batch_size** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 100*) – Number of records to process in each batch.
+ * **parallelize** (bool, default: [`False`](https://docs.python.org/3/library/constants.html#False)) – Whether to parallelize the operation.
+ * **max_num_threads** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 6*) – Maximum number of threads to use when parallelizing.
+ * **update_release_states** (bool, default: [`False`](https://docs.python.org/3/library/constants.html#False)) – Whether to update release states after deletion/withdrawal.
+ * **withdrawal_notes** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Notes to add when withdrawing records.
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If one or more records have not been pushed to the server.
+
+#### WARNING
+`parallelize=True` should not be set when using long-running sessions authenticated via OIDC. See
+[OIDC and parallel operation](../release_notes/known_issues.md#oidc-known-issue) for more details.
+
+
+
+#### bulk_fetch_release_states(records, batch_size=100, parallelize=False, max_num_threads=6)
+
+Fetches and populates the release states of the specified [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects.
+
+#### Versionchanged
+Changed in version 4.2: Argument `parallelise` was renamed to `parallelize`.
+
+* **Parameters:**
+ * **records** ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*Record*](record.md#ansys.grantami.core.mi_record_classes.Record) *]*) – List of records to fetch release states for.
+ * **batch_size** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 100*) – Number of records to process in each batch.
+ * **parallelize** (bool, default: [`False`](https://docs.python.org/3/library/constants.html#False)) – Whether to parallelize the fetch operation.
+ * **max_num_threads** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 6*) – Maximum number of threads to use when parallelizing.
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If one or more records have not been pushed to the server.
+
+#### WARNING
+`parallelize` should not be set to [`True`](https://docs.python.org/3/library/constants.html#True) when using long-running sessions authenticated via
+OIDC. See [OIDC and parallel operation](../release_notes/known_issues.md#oidc-known-issue) for more details.
+
+#### SEE ALSO
+[`Table.bulk_fetch_all_record_versions()`](table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch_all_record_versions)
+: Also populates the [`Record.all_versions`](record.md#ansys.grantami.core.mi_record_classes.Record.all_versions) property.
+
+
+
+#### get_db(name=None, db_key=None, guid=None, version_guid=None)
+
+Returns the database matching the specified criteria.
+
+Provide at least one of:
+
+* Database name: `name`
+* Database key: `db_key`
+* Database GUID: `guid`
+* Database version GUID: `version_guid`
+
+* **Parameters:**
+ * **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Database name.
+ * **db_key** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Database key.
+ * **guid** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Database GUID.
+ * **version_guid** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Database version GUID.
+* **Returns:**
+ Database object matching the specified criteria.
+* **Return type:**
+ [Database](database.md#ansys.grantami.core.mi_tree_classes.Database)
+* **Raises:**
+ * [**KeyError**](https://docs.python.org/3/library/exceptions.html#KeyError) – If multiple databases are found for the same criteria.
+ * [**KeyError**](https://docs.python.org/3/library/exceptions.html#KeyError) – If no databases are found matching the provided criteria.
+ * [**KeyError**](https://docs.python.org/3/library/exceptions.html#KeyError) – If no criteria are provided.
+
+
+
+#### get_record_by_id(db_key, hguid=None, vguid=None, history_identity=None, version_number=None)
+
+Returns the record with the specified ID from the database specified by `db_key`.
+
+This method resolves records with the following (sets of) references in priority order:
+
+1. `vguid` (record version GUID): Uniquely identifies specific record version.
+2. `history_identity` (record history identity): Uniquely identifies record only. Can be optionally
+ combined with `version_number` (record version number) to identify a specific record version.
+3. `hguid` (record history GUID): Uniquely identifies record only.
+
+If `vguid` or `version_number` are not provided for version controlled records, this method will return the
+latest available version of the record available to the user. The latest available version is dependent on the
+user’s Granta MI permissions.
+
+* **Parameters:**
+ * **db_key** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Database key.
+ * **hguid** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Record history GUID, uniquely identifies record.
+ * **vguid** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Record version GUID, uniquely identifies record version.
+ * **history_identity** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *optional*) – Record history identity.
+ * **version_number** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *optional*) – Record version number.
+* **Returns:**
+ Record object with the specified ID.
+* **Return type:**
+ [Record](record.md#ansys.grantami.core.mi_record_classes.Record)
+
+
+
+#### get_records_by_ids(record_identifiers)
+
+Returns a [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) object for each identifier provided.
+
+The returned list of records will have the same number of elements as the provided list of identifiers. If no
+record corresponds to that identifier then the corresponding item in the returned list will be [`None`](https://docs.python.org/3/library/constants.html#None).
+
+Each element in the `record_identifiers` parameter should be a dictionary with the `db_key` entry.
+Additionally, it must contain one or more of the following (sets of) references in priority order:
+
+1. `vguid` (record version GUID): Uniquely identifies specific record version.
+2. `history_identity` (record history identity): Uniquely identifies record only. Can be optionally
+ combined with `version_number` (record version number) to identify a specific record version.
+3. `hguid` (record history GUID): Uniquely identifies record only.
+
+If `vguid` or `version_number` are not provided for version controlled records, this method will
+return the latest available version of the record available to the user. The latest available version
+is dependent on the user’s Granta MI permissions.
+
+* **Parameters:**
+ **record_identifiers** (*Sequence* *[*[*dict*](https://docs.python.org/3/library/stdtypes.html#dict) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* [*str*](https://docs.python.org/3/library/stdtypes.html#str) *|* [*int*](https://docs.python.org/3/library/functions.html#int) *]* *]*) – Sequence of dictionaries containing record identifiers.
+* **Returns:**
+ List of Record objects corresponding to the identifiers, or [`None`](https://docs.python.org/3/library/constants.html#None) if the reference did not identify a
+ resolvable record.
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[Record](record.md#ansys.grantami.core.mi_record_classes.Record) | None]
+
+
+
+#### persist_oidc_token()
+
+Stores a refresh token in the credential manager for your system for unattended later use.
+
+The `keyring` package uses system-managed storage, and supports the following credential managers:
+
+* Windows Credential Manager
+* macOS Keychain
+* Freedesktop Secret Service
+* KDE4 and KDE5 KWallet
+
+#### WARNING
+This method raises a `win32ctypes.pywin32.pywintypes.error` when it is used to persist a refresh token
+longer than 1280 characters in the Windows Credential Manager. If this error is raised, use an alternative
+keyring backend. A list of alternative backends are available on the [keyring PyPI page](https://pypi.org/project/keyring/).
+
+
+
+#### records_from_string(text, use_strict_version=True)
+
+Generates [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects from a tab separated values (.tsv) record list.
+
+* **Parameters:**
+ * **text** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The text string defining the record list.
+ * **use_strict_version** (bool, default: [`True`](https://docs.python.org/3/library/constants.html#True)) – If [`True`](https://docs.python.org/3/library/constants.html#True), return only the specified version of the record (if you do not have permission, the item
+ will be [`None`](https://docs.python.org/3/library/constants.html#None)). If [`False`](https://docs.python.org/3/library/constants.html#False), return the latest visible version of the record.
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[Record](record.md#ansys.grantami.core.mi_record_classes.Record) | None]
+
+### Notes
+
+The required string format to identify a record is tab separated values (.tsv) with column headers
+`RecordHistoryGuid`, `RecordGuid`, `Table`, `DatabaseKey` and `RecordFullName`. This format may be
+generated by copying an MI Viewer record list to the clipboard.
+
+In MI Viewer, a field name may be prefixed by an asterisk to denote a default Match Column. This functionality
+is not supported in the MI Scripting Toolkit. Either the `RecordHistoryGuid` (if `use_strict_mode = False`)
+or `RecordGuid` (if `use_strict_mode = True`) will be used to identify the record.
+
+In One MI, use MI Favorites and PyGranta RecordLists to transfer a collection of records from the browser to
+Scripting Toolkit.
+
+
+
+#### refetch_dbs()
+
+Fetches the list of databases from the server.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### search_for_records_by_name(name)
+
+Searches by record name over all databases (uses [`Database.search_for_records_by_name()`](database.md#ansys.grantami.core.mi_tree_classes.Database.search_for_records_by_name)).
+
+* **Parameters:**
+ **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The name of the record to search for.
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[Record](record.md#ansys.grantami.core.mi_record_classes.Record)]
+
+### Notes
+
+Makes a Service Layer call for each table in each database.
+
+
+
+#### search_for_records_by_text(text)
+
+Performs a simple text search over all databases (uses [`Database.search_for_records_by_text()`](database.md#ansys.grantami.core.mi_tree_classes.Database.search_for_records_by_text)).
+
+* **Parameters:**
+ **text** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The text to search for.
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[Record](record.md#ansys.grantami.core.mi_record_classes.Record)]
+
+### Notes
+
+Makes a Service Layer call for each table in each database.
+
+
+
+#### update(records, update_attributes=True, update_links=False, refresh_attributes=True, include_binary_data_in_refresh=False, notes=None, release_notes=None)
+
+Pushes any changes in the specified records (including adding newly-created records) to the server.
+
+Returns a list of successfully imported [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects. If refresh_attributes set to [`True`](https://docs.python.org/3/library/constants.html#True), the
+imported records’ attributes are exported after the update is complete.
+
+* **Parameters:**
+ * **records** ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*Record*](record.md#ansys.grantami.core.mi_record_classes.Record) *]*) – List of records to update.
+ * **update_attributes** (bool, default: [`True`](https://docs.python.org/3/library/constants.html#True)) – Whether to include attribute updates.
+ * **update_links** (bool, default: [`False`](https://docs.python.org/3/library/constants.html#False)) – Whether to include link updates.
+ * **refresh_attributes** (bool, default: [`True`](https://docs.python.org/3/library/constants.html#True)) – Whether to include updated attribute values in the returned records. See Notes for more details.
+ * **include_binary_data_in_refresh** (bool, default: [`False`](https://docs.python.org/3/library/constants.html#False)) – Whether to include binary data in the refresh. See Notes for more details.
+ * **notes** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Revision notes for the update. Applies to all records in the update.
+ * **release_notes** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Version release notes for the update. Applies to all records flagged for release in the update.
+* **Returns:**
+ List of successfully updated Record objects.
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[Record](record.md#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If a [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) is imported with `name` set to [`None`](https://docs.python.org/3/library/constants.html#None).
+ * [**UnexportedBinaryDataError**](exceptions.md#ansys.grantami.core.mi_meta_classes.UnexportedBinaryDataError) – If a tabular attribute has been modified destructively and contains unexported binary data that has not
+ been overwritten.
+
+#### WARNING
+If `include_binary_data_in_refresh` is set to [`False`](https://docs.python.org/3/library/constants.html#False), the `binary_data` property and `save()` method are
+both still available for backwards compatibility. However, they will download the data from Granta MI on
+demand for each attribute value. A warning will be generated each time this occurs, but may only occur once
+due to the Python warning configuration settings.
+
+This behavior is likely to have a significant performance impact, and so it is recommended that if access to
+the binary data is required without a subsequent HTTP GET request, you should specify
+`include_binary_data_in_refresh = True`.
+
+On-demand access to attribute values without using [`Table.bulk_fetch()`](table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) is unaffected.
+
+### Notes
+
+If `refresh_attributes` is set to [`True`](https://docs.python.org/3/library/constants.html#True) (default), the data will be re-exported after import. If data
+is not required for subsequent operations, setting `refresh_attributes` to [`False`](https://docs.python.org/3/library/constants.html#False) can improve
+performance of this operation significantly.
+
+If `include_binary_data_in_refresh` is set to [`False`](https://docs.python.org/3/library/constants.html#False) (default), the export will not fetch the binary data
+representing the request File and Picture attributes and will instead export URLs (see the
+[`BinaryType.url`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType.url) documentation for more information on how to use the URL to access the data). This
+setting is recommended for large files and pictures, or if the binary data itself is not required.
+
+To summarize how the file and picture data can be accessed:
+
+* `include_binary_data_in_refresh = False` (default): The [`BinaryType.url`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType.url) property is populated.
+* `include_binary_data_in_refresh = True`: The [`BinaryType.binary_data`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType.binary_data) property, and
+ [`AttributeFile.save()`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFile.save) and [`AttributePicture.save()`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributePicture.save) methods are all available to access and save
+ the binary data. The [`BinaryType.url`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType.url) property is empty and returns [`None`](https://docs.python.org/3/library/constants.html#None).
+
+
+
+#### update_links(records)
+
+Pushes any changes in the links of the specified records (including newly-created records) to the server.
+
+Returns a list of successfully modified [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects. All source and target records must be exported
+to/from the server before being linked.
+
+* **Parameters:**
+ **records** ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*Record*](record.md#ansys.grantami.core.mi_record_classes.Record) *]*) – List of records to update links for.
+* **Returns:**
+ List of successfully updated Record objects.
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[Record](record.md#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If one or more records have not been pushed to the server.
+
+
+
+#### *property* dbs *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[Database](database.md#ansys.grantami.core.mi_tree_classes.Database)]*
+
+List of databases on the server.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[Database](database.md#ansys.grantami.core.mi_tree_classes.Database)]
+
+
+
+#### *property* dbs_by_guid *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [Database](database.md#ansys.grantami.core.mi_tree_classes.Database)]*
+
+Dictionary of databases on the server, indexed by database GUID
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [Database](database.md#ansys.grantami.core.mi_tree_classes.Database)]
+* **Raises:**
+ [**KeyError**](https://docs.python.org/3/library/exceptions.html#KeyError) – If multiple databases have the same GUID.
+
+
+
+#### *property* dbs_by_key *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [Database](database.md#ansys.grantami.core.mi_tree_classes.Database)]*
+
+Dictionary of databases on the server, indexed by database key.
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [Database](database.md#ansys.grantami.core.mi_tree_classes.Database)]
+
+
+
+#### *property* refresh_token *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The refresh token returned by the OIDC identity provider if one was provided.
+
+If a refresh token was not returned by the OIDC identity provider, the initial provided token is returned.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str), optional
+
+#### WARNING
+Refresh tokens are bearer tokens that grant access to the Granta MI server, and so should be treated as
+confidential. To use a refresh token for unattended Scripting Toolkit authentication, use the
+[`persist_oidc_token()`](#ansys.grantami.core.mi.Session.persist_oidc_token) method to persist the refresh token in a secure credential store.
+
+
+
+#### *property* service_layer_url *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Service Layer URL.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* viewer_base_url *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+MI Viewer URL associated with the Service Layer.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+### *class* SessionBuilder(service_layer_url, session_configuration)
+
+Builds a [`Session`](#ansys.grantami.core.mi.Session).
+
+* **Parameters:**
+ * **service_layer_url** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Granta MI Service Layer URL.
+ * **session_configuration** ([*SessionConfiguration*](#ansys.grantami.core.mi.SessionConfiguration) *,* *optional*) – Additional settings for the connection.
+
+### Notes
+
+If MI Scripting Toolkit has been installed on the Granta MI application server, then the Granta MI application
+server name *must* be specified in full in the url parameter. If you use ‘localhost’ or a loopback address, MI
+Scripting Toolkit will be unable to use the specified user account to connect to Granta MI.
+
+
+
+#### with_oidc()
+
+Connect with OIDC.
+
+* **Returns:**
+ An OIDC Session builder to finalize the OIDC connection.
+* **Return type:**
+ [OIDCSessionBuilder](#ansys.grantami.core.mi.OIDCSessionBuilder)
+
+
+
+#### with_autologon()
+
+Connect with Windows Authentication.
+
+* **Return type:**
+ [Session](#ansys.grantami.core.mi.Session)
+
+
+
+#### with_credentials(username, password, domain=None, store_password=False)
+
+Connect using provided credentials.
+
+* **Parameters:**
+ * **username** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Username for the connection.
+ * **password** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Password for the connection.
+ * **domain** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Domain to use for the connection.
+ * **store_password** (bool, default: [`False`](https://docs.python.org/3/library/constants.html#False)) – Set to [`True`](https://docs.python.org/3/library/constants.html#True) if additional sessions need to be spawned, for example when parallelization is required.
+* **Return type:**
+ [Session](#ansys.grantami.core.mi.Session)
+
+
+
+### *class* OIDCSessionBuilder
+
+OIDC session builder.
+
+Returned by [`SessionBuilder.with_oidc()`](#ansys.grantami.core.mi.SessionBuilder.with_oidc).
+
+
+
+#### with_access_token(token)
+
+Authenticate the user via the provided access token.
+
+Access tokens have short lifespans. The session will no longer be authenticated once the token expires.
+
+* **Parameters:**
+ **token** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Access token.
+* **Return type:**
+ [Session](#ansys.grantami.core.mi.Session)
+
+
+
+#### with_authorization_code_flow()
+
+Authenticate the user interactively via a web browser.
+
+Requires a web browser on the client machine.
+
+* **Return type:**
+ [Session](#ansys.grantami.core.mi.Session)
+
+
+
+#### with_device_code_flow()
+
+Authenticate the user interactively using device code flow.
+
+* **Return type:**
+ [Session](#ansys.grantami.core.mi.Session)
+
+
+
+#### with_refresh_token(token)
+
+Authenticate the user via the provided refresh token.
+
+* **Parameters:**
+ **token** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Refresh token.
+* **Return type:**
+ [Session](#ansys.grantami.core.mi.Session)
+
+
+
+#### with_stored_token()
+
+Authenticate the user via a persisted token.
+
+The token must have been persisted to the system credential manager via [`Session.persist_oidc_token()`](#ansys.grantami.core.mi.Session.persist_oidc_token).
+
+* **Return type:**
+ [Session](#ansys.grantami.core.mi.Session)
+
+
+
+### *class* SessionConfiguration(timeout=300000, max_retries=0, \*\*kwargs)
+
+Configuration for a session.
+
+* **Parameters:**
+ * **timeout** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 300000*) – Maximum time to wait for a response, in milliseconds.
+ * **max_retries** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 0*) – Maximum number of times to retry requests sent to the Service Layer.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/supporting.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/supporting.md
new file mode 100644
index 0000000000..68e1363e6f
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/supporting.md
@@ -0,0 +1,2923 @@
+# Schema and supporting items
+
+
+
+
+
+
+
+
+
+## Schema
+
+
+
+### *class* LinkGroupDetails
+
+Provides access to the properties of a record link group.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Database.record_link_groups`](database.md#ansys.grantami.core.mi_tree_classes.Database.record_link_groups) to access instances of this class.
+
+
+
+#### *property* database_from *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Database key of the database the link group originates from.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* database_to *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Database key of the database target by the link group.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the record link group.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* reverse_name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the record link group in the return direction.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* table_from *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the table the link group comes from.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* table_to *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the table targeted by the link group.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* type *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Whether the record link group is ‘static’, ‘crossDatabase’ or ‘dynamic’.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+### *class* TableLayout
+
+Represents a layout for a table in the database.
+
+Provides individually accessible categories, or a full representation of the layout as a JSON-style object.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use [`Table.layouts`](table.md#ansys.grantami.core.mi_tree_classes.Table.layouts)
+to access instances of this class.
+
+
+
+#### meta_attributes_on(attribute_name)
+
+Returns the list of meta-attributes corresponding to a given attribute in this layout.
+
+* **Parameters:**
+ **attribute_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Name of the attribute.
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* attributes_by_category *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]]*
+
+Dictionary of attribute lists, indexed by the layout category they are in.
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]]
+
+
+
+#### *property* categories *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+List of all the categories (headings) in the layout.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* layout *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [str](https://docs.python.org/3/library/stdtypes.html#str) | [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)] | [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [str](https://docs.python.org/3/library/stdtypes.html#str) | [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]]]]*
+
+JSON-style representation of the layout.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [str](https://docs.python.org/3/library/stdtypes.html#str) or [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)] or [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [str](https://docs.python.org/3/library/stdtypes.html#str) or [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]]]]
+
+
+
+#### *property* link_groups_by_category *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]]*
+
+Dictionary of link group lists, indexed by the layout category they are in.
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]]
+
+
+
+#### *property* meta_attributes_by_attribute *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]]*
+
+Dictionary of meta-attribute lists, indexed by parent attributes.
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]]
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Layout name.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+### *class* Exporter
+
+Represents a Granta MI FEA exporter.
+
+FEA exporters are used to export record data from Granta MI into formats supported by CAD and CAE packages.
+
+This operation performs no subset filtering, so all tabular rows will be included in the Initial XML
+regardless of the subset membership of the linked records.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`get_available_exporters()`](table.md#ansys.grantami.core.mi_tree_classes.Table.get_available_exporters) to retrieve exporters for a given table.
+
+
+
+#### export_list_is_valid(records)
+
+Verifies that a list of records is valid for export.
+
+* **Parameters:**
+ **records** (list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]) – List of records to validate.
+* **Returns:**
+ Whether the specified list of records can be exported with this exporter.
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### get_parameters_required_for_export(records)
+
+Returns a dictionary of all the parameter definitions the Exporter requires to export the data.
+
+Returns parameters required from the specified list of records, indexed by parameter name.
+
+* **Parameters:**
+ **records** (list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]) – List of records to export.
+* **Return type:**
+ dict[str, [`ExporterParameter`](#ansys.grantami.core.mi_attribute_classes.ExporterParameter)]
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If one or more records have not been pushed to the server.
+
+
+
+#### run_exporter(records, stop_before=None, parameter_defs=None, sig_figs=None)
+
+Performs an FEA export on the specified list of records, returning the data representing the records as a
+string.
+
+* **Parameters:**
+ * **records** (list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]) – List of records to export.
+ * **stop_before** ([*int*](https://docs.python.org/3/library/functions.html#int) *or* [*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Either refers to the index of the transform step (int) or its name (str).
+ * **parameter_defs** (dict[str, [`ExporterParameter`](#ansys.grantami.core.mi_attribute_classes.ExporterParameter)], optional) – Dictionary of exporter parameters.
+ * **sig_figs** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *optional*) – Number of significant figures for numerical data.
+* **Returns:**
+ Contains data output by the exporter.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If one or more records have not been pushed to the server.
+
+
+
+#### save(file_path, file_name=None, file_extension=None)
+
+Saves the output of the last FEA export to the path provided.
+
+Uses the default naming convention and file extension for the exporter; specify a `file_name` or
+`file_extension` to override the defaults.
+
+* **Parameters:**
+ * **file_path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – File path of the form *C:\\Users\\Username\\*.
+ * **file_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Output file name. Does not require a file extension.
+ * **file_extension** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Output file extension.
+
+
+
+#### *property* absolute_temperatures_optional *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether this exporter allows the user to specify absolute or relative temperatures.
+
+If [`True`](https://docs.python.org/3/library/constants.html#True) the user can choose to use the absolute or relative form of the temperature
+unit defined in the unit system. Otherwise, the exporter will use the form defined in the
+`.exp` file.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* default_bom *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Returns the default byte-order mark as defined by the exporter configuration file.
+
+If no BOM is required by default, this property is [`None`](https://docs.python.org/3/library/constants.html#None).
+
+* **Return type:**
+ bytes or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* default_encoding *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Returns the default file encoding scheme as defined by the exporter configuration file.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+### Notes
+
+This is returned as a Python-compatible string (e.g. “cp1252”) rather than the .NET codepage “1252”.
+
+
+
+#### *property* default_file_extension *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Returns the default file extension as defined by the exporter configuration file.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* default_file_name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Returns the default file name for the last performed export.
+
+As defined by the exporter configuration file.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* description *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The Exporter description.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* exporter_key *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The unique key that is used to identify the exporter.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* model *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The Finite-Element Material Model name.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+### Notes
+
+This name is exported to the initial XML file, and appears in the MI Viewer and MI Explore export interfaces.
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The name of the exporter, as defined in the `.exp` file.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* package *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The Package defines the name of the target CAE analysis package.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+### Notes
+
+This name is exported to the initial XML file, and appears in the MI Viewer and MI Explore export interfaces.
+
+
+
+#### *property* transforms *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[ExporterTransform](#ansys.grantami.core.mi_exporters.ExporterTransform)]*
+
+Iterable containing the transform steps defined for this exporter.
+
+Each entry in the iterable contains the index of the transform stage, and the ID.
+Either can be provided to the [`Exporter.run_exporter()`](#ansys.grantami.core.mi_exporters.Exporter.run_exporter) `stop_before` argument to selectively run
+transformation steps.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[ExporterTransform](#ansys.grantami.core.mi_exporters.ExporterTransform)]
+
+
+
+#### *property* unit_system *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The currently selected unit-system.
+
+If None then the default unit system for the exporter will be used, otherwise the provided
+unit-system will be used when running the exporter.
+
+* **Return type:**
+ str or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* unit_systems *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+All the unit-systems this exporter supports.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* use_absolute_temperatures *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether this exporter should use absolute temperatures.
+
+If [`True`](https://docs.python.org/3/library/constants.html#True) the exporter will use the absolute form of the temperature unit defined in the
+selected unit-system. Otherwise, it will use the relative form.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+### *class* ExporterTransform
+
+Dictionary representing a transformation step defined for an [`Exporter`](#ansys.grantami.core.mi_exporters.Exporter).
+
+Provide the `id` or `index` to the [`Exporter.run_exporter()`](#ansys.grantami.core.mi_exporters.Exporter.run_exporter) `stop_before` argument to selectively run
+transformation steps.
+
+
+
+#### id *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+ID of the transform step.
+
+
+
+#### index *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Index of the transform step.
+
+
+
+
+
+## Parameters
+
+
+
+### *class* ParameterDefinition
+
+Base class for parameters.
+
+Provides access to parameter properties such as revision history, default and possible values, and units.
+
+### Notes
+
+Do not create instances of this class; it represents an abstract database structure.
+
+
+
+#### reset_unit()
+
+Resets the unit back to its original value when the parameter was initially exported.
+
+
+
+#### *property* axis_scale_type *: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['Linear', 'Log'] | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Axis scale type for the parameter.
+
+* **Returns:**
+ [`None`](https://docs.python.org/3/library/constants.html#None) for discrete parameters.
+* **Return type:**
+ [`ScaleType`](constants.md#ansys.grantami.core.mi_constants.ScaleType) or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* data_type *: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['Numeric', 'Discrete']*
+
+Parameter data type.
+
+* **Returns:**
+ One of ‘Numeric’ or ‘Discrete’.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+* **Raises:**
+ [**NotImplementedError**](https://docs.python.org/3/library/exceptions.html#NotImplementedError) – If the parameter type is not supported.
+
+
+
+#### *property* database_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Database unit symbol for the parameter.
+
+* **Return type:**
+ str or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+#### *property* default_value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float)*
+
+Default value of the parameter.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or [float](https://docs.python.org/3/library/functions.html#float)
+
+
+
+#### *property* history *: [ObjectHistory](#ansys.grantami.core.mi_meta_classes.ObjectHistory)*
+
+Revision history of the parameter.
+
+* **Return type:**
+ [`ObjectHistory`](#ansys.grantami.core.mi_meta_classes.ObjectHistory)
+
+
+
+#### *property* history_of_default *: [ObjectHistory](#ansys.grantami.core.mi_meta_classes.ObjectHistory)*
+
+Revision history of the parameter’s default value.
+
+* **Return type:**
+ [`ObjectHistory`](#ansys.grantami.core.mi_meta_classes.ObjectHistory)
+
+
+
+#### *property* id *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Parameter identifier.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* interpolation_type *: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['None', 'Linear', 'Cubic Spline']*
+
+The interpolation type for the parameter.
+
+* **Return type:**
+ [`InterpolationType`](constants.md#ansys.grantami.core.mi_constants.InterpolationType)
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Parameter name.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* restricted *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the parameter is restricted to specific values.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol for the parameter.
+
+* **Return type:**
+ str or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+### Notes
+
+This property is used to specify a unit in the following situations:
+
+* Specify a unit on an object of any [`ParameterDefinition`](#ansys.grantami.core.mi_attribute_classes.ParameterDefinition) subclass to control the unit of the values
+ returned by the [`default_value`](#ansys.grantami.core.mi_attribute_classes.ParameterDefinition.default_value) and [`values`](#ansys.grantami.core.mi_attribute_classes.ParameterDefinition.values) properties on that object.
+* Specify a unit on an [`ExporterParameter`](#ansys.grantami.core.mi_attribute_classes.ExporterParameter) object to provide a value with a different unit to the
+ [`ExporterParameter.value_for_exporters`](#ansys.grantami.core.mi_attribute_classes.ExporterParameter.value_for_exporters) property.
+
+This property does not impact data export. Attribute parameter values are always exported according to the
+[`Database.unit_system`](database.md#ansys.grantami.core.mi_tree_classes.Database.unit_system) and [`Database.absolute_temperatures`](database.md#ansys.grantami.core.mi_tree_classes.Database.absolute_temperatures) settings.
+
+
+
+#### *property* values *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float)]*
+
+List of all possible values the parameter can take.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) or [float](https://docs.python.org/3/library/functions.html#float)]
+
+
+
+#### *property* values_histories *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[ObjectHistory](#ansys.grantami.core.mi_meta_classes.ObjectHistory)]*
+
+Revision histories of each possible value of a parameter.
+
+* **Return type:**
+ list[[`ObjectHistory`](#ansys.grantami.core.mi_meta_classes.ObjectHistory)]
+
+
+
+### *class* DatabaseParameter
+
+Bases: [`ParameterDefinition`](#ansys.grantami.core.mi_attribute_classes.ParameterDefinition)
+
+Definition of a parameter at the database level.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Database.parameters`](database.md#ansys.grantami.core.mi_tree_classes.Database.parameters) to access instances of this class.
+
+
+
+### *class* AttributeParameter
+
+Bases: [`DatabaseParameter`](#ansys.grantami.core.mi_attribute_classes.DatabaseParameter)
+
+Definition of a parameter as configured for an attribute.
+
+Inherited properties [`ParameterDefinition.default_value`](#ansys.grantami.core.mi_attribute_classes.ParameterDefinition.default_value), [`ParameterDefinition.axis_scale_type`](#ansys.grantami.core.mi_attribute_classes.ParameterDefinition.axis_scale_type), and
+[`ParameterDefinition.interpolation_type`](#ansys.grantami.core.mi_attribute_classes.ParameterDefinition.interpolation_type) can differ from the database parameter definition.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`AttributeDefinitionMultiValue.parameters`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionMultiValue.parameters) to access instances of this class.
+
+
+
+#### *property* order *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Order in which the parameter is stored in the attribute.
+
+This is relevant for some interpolation methods, and determines the display order in MI Viewer.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* parent_attribute *: [AttributeDefinitionMultiValue](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionMultiValue)*
+
+Attribute to which this parameter applies.
+
+* **Return type:**
+ [`AttributeDefinitionMultiValue`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionMultiValue)
+
+
+
+### *class* PointValueParameter
+
+Parameter information that is associated with a point attribute value.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`AttributePointMulti.parameters`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributePointMulti.parameters) to access instances of this class.
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Parameter name.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol for the parameter.
+
+Defines the unit of the values for this parameter when importing into a point attribute.
+
+* **Returns:**
+ Unit symbol as str if units are used, else [`None`](https://docs.python.org/3/library/constants.html#None).
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+### *class* ExporterParameter
+
+Bases: [`DatabaseParameter`](#ansys.grantami.core.mi_attribute_classes.DatabaseParameter)
+
+Definition of a parameter that is used by an exporter.
+
+The value and unit can be set to control the exporter output. If the value is not set then the database parameter
+default value will be used.
+
+### Notes
+
+Do not create instances of this class manually. Use [`Exporter.get_parameters_required_for_export()`](#ansys.grantami.core.mi_exporters.Exporter.get_parameters_required_for_export) to
+generate instances of this class.
+
+
+
+#### clear_value_for_exporters()
+
+Clear the value on the [`ExporterParameter`](#ansys.grantami.core.mi_attribute_classes.ExporterParameter) instance and return it to the default value.
+
+
+
+#### *property* value_for_exporters *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float)*
+
+Value on the [`ExporterParameter`](#ansys.grantami.core.mi_attribute_classes.ExporterParameter) instance for use in any exporters the parameter is passed to.
+
+Can be set by the user. If this value is unset, the exporter will use the default value defined in the database
+schema.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or [float](https://docs.python.org/3/library/functions.html#float)
+
+
+
+### *class* FunctionalValueParameter
+
+Parameter that is associated with a functional attribute value.
+
+Used to override parameter settings for an individual attribute value.
+
+#### WARNING
+When importing data, if [`FunctionalValueParameter`](#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter) object attributes are modified and the parameter is not
+populated in the parent attribute value, the modification will be ignored during import. A `UserWarning` will be
+emitted.
+
+When exporting data, parameter settings may exist even if the parameter has no value on the parent attribute. These
+parameter settings will be exported correctly.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use the `parameters`
+property of a functional attribute value, for example [`AttributeFunctionalSeriesPoint.parameters`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.parameters), to access
+instances of this class.
+
+
+
+#### *property* axis_scale_type *: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['Linear', 'Log'] | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The scale type for the parameter.
+
+* **Returns:**
+ If set to [`None`](https://docs.python.org/3/library/constants.html#None), the value is inherited from the parameter definition associated with the parent
+ attribute definition.
+* **Return type:**
+ [`ScaleType`](constants.md#ansys.grantami.core.mi_constants.ScaleType) or None
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a non-string value.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If providing an invalid scale type.
+
+#### SEE ALSO
+[`effective_axis_scale_type`](#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.effective_axis_scale_type)
+: The effective value of this property, taking inheritance into account if the property is set to [`None`](https://docs.python.org/3/library/constants.html#None).
+
+
+
+#### *property* default_value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Default value for the parameter.
+
+* **Returns:**
+ Parameter default value. If set to [`None`](https://docs.python.org/3/library/constants.html#None), the value is inherited from the parameter definition associated
+ with the parent attribute definition.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or [float](https://docs.python.org/3/library/functions.html#float) or None
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a non-float value for a numeric parameter or a non-str value for a discrete parameter.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the string value is not in the allowed values list.
+
+#### SEE ALSO
+[`effective_default_value`](#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.effective_default_value)
+: The effective value of this property, taking inheritance into account if the property is set to [`None`](https://docs.python.org/3/library/constants.html#None).
+
+
+
+#### *property* effective_axis_scale_type *: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['Linear', 'Log'] | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Effective scale type, inherited from the attribute parameter if not defined on the datum.
+
+None for all discrete parameters.
+
+* **Return type:**
+ [`ScaleType`](constants.md#ansys.grantami.core.mi_constants.ScaleType) or None
+
+
+
+#### *property* effective_default_value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float)*
+
+Effective default value, inherited from the attribute parameter if not defined on the datum.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or [float](https://docs.python.org/3/library/functions.html#float)
+
+
+
+#### *property* effective_interpolation_type *: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['None', 'Linear', 'Cubic Spline']*
+
+Effective interpolation type, inherited from the attribute parameter if not defined on the datum.
+
+* **Return type:**
+ [`InterpolationType`](constants.md#ansys.grantami.core.mi_constants.InterpolationType)
+
+
+
+#### *property* interpolation_type *: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['None', 'Linear', 'Cubic Spline'] | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The interpolation type for the parameter.
+
+* **Returns:**
+ If set to [`None`](https://docs.python.org/3/library/constants.html#None), the value is inherited from the parameter definition associated with the parent
+ attribute definition.
+* **Return type:**
+ [`InterpolationType`](constants.md#ansys.grantami.core.mi_constants.InterpolationType) or None
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a non-string value.
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If providing an invalid interpolation type.
+
+#### SEE ALSO
+[`effective_interpolation_type`](#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.effective_interpolation_type)
+: The effective value of this property, taking inheritance into account if the property is set to [`None`](https://docs.python.org/3/library/constants.html#None).
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Parameter name.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol for the parameter.
+
+Defines the unit of the values for this parameter when importing into a functional attribute.
+
+* **Returns:**
+ Unit symbol as str if units are used, else [`None`](https://docs.python.org/3/library/constants.html#None).
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+#### WARNING
+The [`unit`](#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.unit) property affects both the [`default_value`](#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.default_value) and the functional attribute parameter
+value for import. If the unit is modified, you must make sure that both the [`default_value`](#ansys.grantami.core.mi_attribute_value_classes.FunctionalValueParameter.default_value) and the
+corresponding functional attribute data contain values consistent with the new unit.
+
+
+
+
+
+## Item history
+
+
+
+### *class* ObjectHistory
+
+Provides access to the revision history of an MI database element.
+
+Object histories are currently supported via the following properties:
+
+* [`AttributeDefinition.history`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition.history)
+* [`AttributeDefinitionTabular.column_histories`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionTabular.column_histories)
+* [`ParameterDefinition.history`](#ansys.grantami.core.mi_attribute_classes.ParameterDefinition.history)
+* [`ParameterDefinition.history_of_default`](#ansys.grantami.core.mi_attribute_classes.ParameterDefinition.history_of_default)
+* [`ParameterDefinition.values_histories`](#ansys.grantami.core.mi_attribute_classes.ParameterDefinition.values_histories)
+* [`DataRevisionHistory.history`](#ansys.grantami.core.mi_meta_classes.DataRevisionHistory.history)
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use the properties listed
+above to access instances of this class.
+
+
+
+#### *property* created_at *: [datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)*
+
+Date and time the database element was created.
+
+* **Return type:**
+ [datetime.datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)
+
+
+
+#### *property* created_by *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The username of the user who created the database element.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* date_created *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Date the database element was created.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* last_modified_at *: [datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)*
+
+Date and time the database element was last modified.
+
+* **Return type:**
+ [datetime.datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)
+
+
+
+#### *property* last_modified_by *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The username of the last user to modify the database element.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* last_modified_date *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Date the database element was last modified.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* update_count *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+The number of times the object has been updated.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+
+
+### *class* RecordVersionHistory
+
+Provides access to the revision history of an MI Record.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.record_history`](record.md#ansys.grantami.core.mi_record_classes.Record.record_history) to access an instance of this class.
+
+
+
+#### *property* created_at *: [datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)*
+
+Date and time the record version was created.
+
+* **Return type:**
+ [datetime.datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)
+
+
+
+#### *property* created_by *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The username of the user who created the record version.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* creation_notes *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Notes associated with the creation of the record version.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* last_modification_notes *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Notes associated with the last modification made to record version.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* last_modified_at *: [datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)*
+
+Date and time the record version was last modified.
+
+* **Return type:**
+ [datetime.datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime)
+
+
+
+#### *property* last_modified_by *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The username of the user who last modified the record version.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* release_notes *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Notes associated with the release of the record version.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* released_at *: [datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Date and time the record version was released.
+
+* **Return type:**
+ [datetime.datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime) or None
+
+
+
+#### *property* released_by *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The username of the user who released the record version.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* superseded_at *: [datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Date and time the record version was superseded.
+
+* **Return type:**
+ [datetime.datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime) or None
+
+
+
+#### *property* superseded_by *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The username of the user who superseded the record version.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* supersession_notes *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Notes associated with the last operation that superseded the record version.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* withdrawal_notes *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Notes associated with the withdrawal of the record version.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* withdrawn_at *: [datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Date and time the record version was withdrawn.
+
+* **Return type:**
+ [datetime.datetime](https://docs.python.org/3/library/datetime.html#datetime.datetime) or None
+
+
+
+#### *property* withdrawn_by *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The username of the user who withdrew the record version.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+
+
+### *class* DataRevisionHistory
+
+Provides revision history information about the data in an attribute of a record.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Record.data_revision_history`](record.md#ansys.grantami.core.mi_record_classes.Record.data_revision_history) to access an instance of this class.
+
+
+
+#### *property* created_in_record_version *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Version of the record when this datum was created.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* data_version_number *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Data version number.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* history *: [ObjectHistory](#ansys.grantami.core.mi_meta_classes.ObjectHistory) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Revision history of the attribute data, as an [`ObjectHistory`](#ansys.grantami.core.mi_meta_classes.ObjectHistory) object.
+
+Is [`None`](https://docs.python.org/3/library/constants.html#None) for empty attributes.
+
+* **Return type:**
+ [`ObjectHistory`](#ansys.grantami.core.mi_meta_classes.ObjectHistory) or None
+
+
+
+#### *property* is_meta *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the attribute is a meta-attribute or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* is_meta_for *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Name of the parent attribute, if a meta-attribute.
+
+Returns [`None`](https://docs.python.org/3/library/constants.html#None) otherwise.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* is_populated *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the attribute is populated.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* meta_attributes *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [DataRevisionHistory](#ansys.grantami.core.mi_meta_classes.DataRevisionHistory)]*
+
+Data revision history of meta-attributes associated with this attribute, indexed by meta-attribute name.
+
+* **Return type:**
+ dict[str, [`DataRevisionHistory`](#ansys.grantami.core.mi_meta_classes.DataRevisionHistory)]
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the attribute.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* retired_in_record_version *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Version of the record when this datum was retired.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+
+
+## Search criterion
+
+
+
+### *class* SearchCriterion(attribute, operator, value=None, column_name=None)
+
+Defines a single criterion for use in a search.
+
+The criterion can be as simple as the presence of the specified attribute, or as complex as the data in a specified
+column of the tabular attribute being greater than a specified value. The search will use the same units as the
+[`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition).
+
+* **Parameters:**
+ * **attribute** ([*AttributeDefinition*](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) *|* [*PseudoAttributeDefinition*](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.PseudoAttributeDefinition)) – The subject of the search criterion.
+ * **operator** (*Literal* *[* *"LESS_THAN"* *,* *"GREATER_THAN"* *,* *"BETWEEN"* *,* *"CONTAINS_ANY"* *,* *"CONTAINS_ALL"* *,* *"CONTAINS"* *,* *"NOT_CONTAINS"* *,* *"EXISTS"* *,* *"NOT_EXISTS"* *,* *"EQUAL"* *]*) – The search mode for this criterion. The operator value must be compatible with the type of attribute or pseudo-
+ attribute specified in the `attribute` parameter.
+ * **value** ([*float*](https://docs.python.org/3/library/functions.html#float) *|* [*bool*](https://docs.python.org/3/library/functions.html#bool) *|* [*int*](https://docs.python.org/3/library/functions.html#int) *|* [*str*](https://docs.python.org/3/library/stdtypes.html#str) *|* *List* *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]* *|* [*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*datetime.datetime*](https://docs.python.org/3/library/datetime.html#datetime.datetime) *,* [*datetime.datetime*](https://docs.python.org/3/library/datetime.html#datetime.datetime) *]* *|* [*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*datetime.date*](https://docs.python.org/3/library/datetime.html#datetime.date) *,* [*datetime.date*](https://docs.python.org/3/library/datetime.html#datetime.date) *]* *|* [*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *]* *|* [*RecordColor*](constants.md#ansys.grantami.core.mi_constants.RecordColor) *|* [*RecordType*](constants.md#ansys.grantami.core.mi_constants.RecordType) *|* *None*) – The value used in this criterion. The value type must correspond to the type of attribute or pseudo-attribute
+ specified in the `attribute` parameter.
+ * **column_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *|* *None*) – For tabular attributes, the name of the column to which this search criterion applies. Required when the
+ operator is `EQUAL`.
+
+### Notes
+
+To perform an exact search on a discrete attribute, the operator argument should be either `CONTAINS_ANY` or
+`CONTAINS_ALL`. In the case of searching for a single discrete value, the `value` argument should be a list
+containing the search term.
+
+[`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime) values default to UTC if no timezone information is provided.
+
+
+
+#### *property* attribute *: [AttributeDefinition](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) | [PseudoAttributeDefinition](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.PseudoAttributeDefinition)*
+
+[`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) or [`PseudoAttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.PseudoAttributeDefinition) for the attribute used in this search criterion.
+
+* **Return type:**
+ [AttributeDefinition](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) | [PseudoAttributeDefinition](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.PseudoAttributeDefinition)
+
+
+
+#### *property* operation *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Operator used in this criterion, if provided.
+
+* **Example:**
+ ‘EXISTS’ or ‘CONTAINS’
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+
+
+## Media attribute values
+
+
+
+
+
+### *class* BinaryType
+
+Stores and provides access to Pictures and Files and associated metadata.
+
+Pictures and files can appear in Granta MI as data (for example, in a tabular data column), or as an attribute
+value. This class wraps files and images for inclusion in the corresponding MI Scripting Toolkit class.
+
+
+
+#### load(path)
+
+Populates the object with the data located on `path`.
+
+Relative paths are permitted.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to the object to load.
+
+
+
+#### save(path)
+
+Saves an object to file location `path`.
+
+Relative paths are permitted.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path where the object should be saved.
+
+
+
+#### *property* binary_data *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The binary data for the file.
+
+Binary data can be set with a bytes object or file buffer.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If binary data is available on the server but has not been exported.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Checks whether the [`BinaryType`](#ansys.grantami.core.mi_attribute_value_classes.BinaryType) object is populated by checking whether there is binary data in the
+object.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* mime_file_type *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+MIME (Multipurpose Internet Mail Extensions) file type.
+
+If this object is populated via export, the `mime_file_type` property returns the MIME file type stored in
+Granta MI.
+
+If this object is populated via [`load()`](#ansys.grantami.core.mi_attribute_value_classes.BinaryType.load) or setting the [`binary_data`](#ansys.grantami.core.mi_attribute_value_classes.BinaryType.binary_data) property, the
+`mime_file_type` property is populated using the `filetype` library. If `filetype` cannot determine the
+MIME file type, the `mime_file_type` property is set to [`None`](https://docs.python.org/3/library/constants.html#None) and Granta MI determines the MIME file
+type during import.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+The [filetype PyPI page](https://pypi.org/project/filetype) lists supported MIME types.
+
+
+
+#### *property* url *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+URL of the hosted file.
+
+* **Returns:**
+ URL to the file stored in the parent Granta MI attribute, or [`None`](https://docs.python.org/3/library/constants.html#None) if the URL was not populated.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+The data can be retrieved by using a Python HTTP library (e.g. Requests, HTTPX) and by supplying the
+appropriate authentication for your Granta MI server.
+
+To populate this property, the [`Table.bulk_fetch()`](table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) method must be used with
+`include_binary_data = False` (default). If `include_binary_data = True` is specified, or if the attribute
+is fetched on-demand by accessing the `attributes` dictionary without performing a bulk fetch, this property
+will always return [`None`](https://docs.python.org/3/library/constants.html#None).
+
+
+
+#### *property* value *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The binary data of the hosted file, if exported.
+
+[`None`](https://docs.python.org/3/library/constants.html#None) if the attribute was exported with `include_binary_data = False`.
+
+* **Return type:**
+ bytes or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+
+
+### *class* Picture(\*, path=None)
+
+Extended [`BinaryType`](#ansys.grantami.core.mi_attribute_value_classes.BinaryType) class for Pictures in MI.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path) *,* *optional*) – Path to the image file to load. Takes the form `C:\\Users\\username\\Pictures\\image.jpg` or
+ `/home/username/Pictures/image.jpg`.
+
+### Notes
+
+Pictures of up to 500 MB in size may be stored in Granta MI. To upload pictures larger than 20 Mb using Scripting
+Toolkit:
+
+* Granta MI Service Layer must be configured to allow large requests. If this is not configured,
+ [`Session.update()`](session.md#ansys.grantami.core.mi.Session.update) will raise a [`GRANTA_ServiceLayerError`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_ServiceLayerError) for a “413 Request Entity Too Large” HTTP
+ response. For more information, contact your Ansys Technical Representative.
+* The Python client environment must have sufficient system resources to load and Base64-encode the binary data. If
+ there are insufficient system resources, unhandled Python exceptions may be raised.
+
+
+
+#### load(path)
+
+Populates the Picture object with the image located on `path`.
+
+Relative paths are permitted.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to the image file to load. Takes the form
+ `C:\\Users\\username\\Pictures\\image.jpg` or `/home/username/Pictures/image.jpg`.
+
+
+
+#### save(path)
+
+Saves a Picture object to file location `path`.
+
+Relative paths are permitted.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path where the image should be saved. Takes the form
+ `C:\\Users\\username\\Pictures\\image.jpg` or `/home/username/Pictures/image.jpg`.
+
+
+
+
+
+### *class* File(\*, path=None)
+
+Extended [`BinaryType`](#ansys.grantami.core.mi_attribute_value_classes.BinaryType) class for Files in MI.
+
+* **Parameters:**
+ **path** (*Union* *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path) *]* *,* *optional*) – Path to the file to load. Takes the form `C:\\Users\\username\\Documents\\file.pdf` or
+ `/home/username/Documents/file.pdf`.
+
+### Notes
+
+Files of up to 500 MB in size may be stored in Granta MI. To upload files larger than 20 Mb using Scripting Toolkit:
+
+* Granta MI Service Layer must be configured to allow large requests. If this is not configured,
+ [`Session.update()`](session.md#ansys.grantami.core.mi.Session.update) will raise a [`GRANTA_ServiceLayerError`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_ServiceLayerError) for a “413 Request Entity Too Large” HTTP
+ response. For more information, contact your Ansys Technical Representative.
+* The Python client environment must have sufficient system resources to load and Base64-encode the binary data. If
+ there are insufficient system resources, unhandled Python exceptions may be raised.
+
+
+
+#### load(path)
+
+Populates the File object with the file located by `path`.
+
+Relative paths are permitted.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to the file to load. Takes the form
+ `C:\\Users\\username\\Documents\\file.pdf` or `/home/username/Documents/file.pdf`.
+
+
+
+#### save(path)
+
+Saves a File object to file location `path`.
+
+Relative paths are permitted.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path where the file should be saved. Takes the form
+ `C:\\Users\\username\\Documents\\file.pdf` or `/home/username/Documents/file.pdf`.
+
+
+
+#### *property* description *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+File description.
+
+Stored with the data value. If provided, the description replaces the file name for the attribute when
+displayed on a datasheet in MI Viewer.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+* **Raises:**
+ [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If providing a non-string value.
+
+
+
+#### *property* file_name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the file.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+
+
+## Numeric attribute values
+
+
+
+### *class* ParameterizedPointValue(value, parameters=)
+
+Represents a point value with parameters in a multi-valued point attribute value.
+
+* **Parameters:**
+ * **value** ([*float*](https://docs.python.org/3/library/functions.html#float) *|* [*ValueWithPrecision*](#ansys.grantami.core.mi_meta_classes.ValueWithPrecision)) – The point float value.
+ * **parameters** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*PointParameterValue*](#ansys.grantami.core._mi_value_classes.PointParameterValue) *,* *...* *]* *,* *optional*) – Tuple of [`PointParameterValue`](#ansys.grantami.core._mi_value_classes.PointParameterValue) objects.
+
+### Examples
+
+Point with no parameters:
+
+```pycon
+>>> point = ParameterizedPointValue(value=1.0)
+```
+
+Point with parameters:
+
+```pycon
+>>> point = ParameterizedPointValue(
+... value=1.0,
+... parameters=(
+... PointParameterValue("Temperature", 25.0),
+... PointParameterValue("Statistical basis", "A-basis"),
+... ),
+... )
+```
+
+Point with precision information and parameters:
+
+```pycon
+>>> point = ParameterizedPointValue(
+... value=ValueWithPrecision(1.0, 3),
+... parameters=(
+... PointParameterValue("Temperature", 25.0),
+... PointParameterValue("Statistical basis", "A-basis"),
+... ),
+... )
+```
+
+
+
+#### *classmethod* from_data(value, parameters=None)
+
+Alternative constructor to create [`ParameterizedPointValue`](#ansys.grantami.core._mi_value_classes.ParameterizedPointValue) from more general data types.
+
+* **Parameters:**
+ * **value** (*SupportsFloat*) – The point float value.
+ * **parameters** (*Sequence* *[*[*PointParameterValue*](#ansys.grantami.core._mi_value_classes.PointParameterValue) *]* *,* *optional*) – Sequence of [`PointParameterValue`](#ansys.grantami.core._mi_value_classes.PointParameterValue) objects.
+* **Return type:**
+ [ParameterizedPointValue](#ansys.grantami.core._mi_value_classes.ParameterizedPointValue)
+
+
+
+#### parameters *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[PointParameterValue](#ansys.grantami.core._mi_value_classes.PointParameterValue), ...]*
+
+Tuple of [`PointParameterValue`](#ansys.grantami.core._mi_value_classes.PointParameterValue) objects.
+
+
+
+#### *property* parameters_by_name *: mappingproxy[[str](https://docs.python.org/3/library/stdtypes.html#str), [str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float)]*
+
+Returns a read-only mapping of parameter values by name.
+
+* **Return type:**
+ [`MappingProxyType`](https://docs.python.org/3/library/types.html#types.MappingProxyType) [str, str | float]
+
+
+
+#### value *: [float](https://docs.python.org/3/library/functions.html#float) | [ValueWithPrecision](#ansys.grantami.core.mi_meta_classes.ValueWithPrecision)*
+
+The point float value.
+
+
+
+### *class* PointParameterValue(name, value)
+
+Parameter value for a point in a multi-valued point value.
+
+* **Parameters:**
+ * **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The name of the parameter.
+ * **value** ([*float*](https://docs.python.org/3/library/functions.html#float) *|* [*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The value of the parameter. This must be a [`float`](https://docs.python.org/3/library/functions.html#float) for numeric parameters, or [`str`](https://docs.python.org/3/library/stdtypes.html#str) for discrete
+ parameters.
+
+### Examples
+
+Numeric parameter:
+
+```pycon
+>>> parameter = PointParameterValue(
+... name="Temperature",
+... value=25.0,
+... )
+```
+
+Discrete parameter:
+
+```pycon
+>>> parameter = PointParameterValue(
+... name="Statistical basis",
+... value="A-basis",
+... )
+```
+
+
+
+#### *classmethod* from_data(name, value)
+
+Alternative constructor to create [`PointParameterValue`](#ansys.grantami.core._mi_value_classes.PointParameterValue) from more general data types.
+
+* **Parameters:**
+ * **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The name of the parameter.
+ * **value** (*SupportsFloat* *|* [*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The value of the parameter. This must be a ‘float’-like for numeric parameters, or a ‘str’ for discrete
+ parameters.
+* **Return type:**
+ [PointParameterValue](#ansys.grantami.core._mi_value_classes.PointParameterValue)
+
+
+
+#### name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The name of the parameter.
+
+
+
+#### value *: [float](https://docs.python.org/3/library/functions.html#float) | [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The value of the parameter.
+
+
+
+### *class* Range(low, high, low_value_is_inclusive=True, high_value_is_inclusive=True)
+
+Range value representation.
+
+* **Parameters:**
+ * **low** ([*float*](https://docs.python.org/3/library/functions.html#float) *|* [*ValueWithPrecision*](#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) *|* *None*) – The lower bound value. Use [`None`](https://docs.python.org/3/library/constants.html#None) for an open-ended range.
+ * **high** ([*float*](https://docs.python.org/3/library/functions.html#float) *|* [*ValueWithPrecision*](#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) *|* *None*) – The upper bound value. Use [`None`](https://docs.python.org/3/library/constants.html#None) for an open-ended range.
+ * **low_value_is_inclusive** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether the low value is included in the range. Defaults to [`True`](https://docs.python.org/3/library/constants.html#True). This property should only be set if the
+ [`low`](#ansys.grantami.core._mi_value_classes.Range.low) property has a value. If [`low`](#ansys.grantami.core._mi_value_classes.Range.low) is [`None`](https://docs.python.org/3/library/constants.html#None), this property has no effect on imported data.
+ * **high_value_is_inclusive** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether the high value is included in the range. Defaults to [`True`](https://docs.python.org/3/library/constants.html#True). This property should only be set if
+ the [`high`](#ansys.grantami.core._mi_value_classes.Range.high) property has a value. If [`high`](#ansys.grantami.core._mi_value_classes.Range.high) is [`None`](https://docs.python.org/3/library/constants.html#None), this property has no effect on imported
+ data.
+
+### Examples
+
+Range with default inclusiveness and values for the lower and upper bounds:
+
+```pycon
+>>> value = Range(1.0, 2.0)
+```
+
+Range value using significant figures and specifying inclusiveness:
+
+```pycon
+>>> value = Range(
+... low=ValueWithPrecision(1.0, 2),
+... high=2.0,
+... low_value_is_inclusive=False,
+... high_value_is_inclusive=False,
+... )
+```
+
+Open-ended range:
+
+```pycon
+>>> value = Range(1.0, None)
+```
+
+
+
+#### *classmethod* from_data(value, low_value_is_inclusive=True, high_value_is_inclusive=True)
+
+Create a [`Range`](#ansys.grantami.core._mi_value_classes.Range) from data in various formats.
+
+* **Parameters:**
+ * **value** ([`Range_Value_Type`](#ansys.grantami.core._mi_value_classes.Range_Value_Type)) – Low and high values.
+ * **low_value_is_inclusive** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether the low value is included in the range. Defaults to [`True`](https://docs.python.org/3/library/constants.html#True).
+ * **high_value_is_inclusive** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *optional*) – Whether the high value is included in the range. Defaults to [`True`](https://docs.python.org/3/library/constants.html#True).
+* **Returns:**
+ The created [`Range`](#ansys.grantami.core._mi_value_classes.Range) object.
+* **Return type:**
+ [Range](#ansys.grantami.core._mi_value_classes.Range)
+
+### Examples
+
+From a dictionary with keys `low` and `high`:
+
+```pycon
+>>> value = Range.from_data({"low": 1.0, "high": 2.0})
+```
+
+From a tuple:
+
+```pycon
+>>> value = Range.from_data((1.0, 2.0))
+```
+
+From a list of integers:
+
+```pycon
+>>> value = Range.from_data([1, 2])
+```
+
+From a single float value:
+
+```pycon
+>>> Range.from_data(1.0)
+Range(low=1.0, high=1.0, low_value_is_inclusive=True, high_value_is_inclusive=True)
+```
+
+
+
+#### *property* as_dict *: [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [float](https://docs.python.org/3/library/functions.html#float) | [ValueWithPrecision](#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) | [None](https://docs.python.org/3/library/constants.html#None)]*
+
+Returns a dictionary representation of the range value with `low` and `high` keys.
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [float](https://docs.python.org/3/library/functions.html#float) | [ValueWithPrecision](#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) | None]
+
+
+
+#### high *: [float](https://docs.python.org/3/library/functions.html#float) | [ValueWithPrecision](#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The upper bound value.
+
+
+
+#### high_value_is_inclusive *: [bool](https://docs.python.org/3/library/functions.html#bool)* *= True*
+
+Whether the high value is included in the range.
+
+This property should only be set if the [`high`](#ansys.grantami.core._mi_value_classes.Range.high) property has a value. If [`high`](#ansys.grantami.core._mi_value_classes.Range.high) is [`None`](https://docs.python.org/3/library/constants.html#None), this
+property has no effect on imported data.
+
+
+
+#### low *: [float](https://docs.python.org/3/library/functions.html#float) | [ValueWithPrecision](#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The lower bound value.
+
+
+
+#### low_value_is_inclusive *: [bool](https://docs.python.org/3/library/functions.html#bool)* *= True*
+
+Whether the low value is included in the range.
+
+This property should only be set if the [`low`](#ansys.grantami.core._mi_value_classes.Range.low) property has a value. If [`low`](#ansys.grantami.core._mi_value_classes.Range.low) is [`None`](https://docs.python.org/3/library/constants.html#None), this
+property has no effect on imported data.
+
+
+
+### Range_Value_Type
+
+Valid values for use with [`Range.from_data()`](#ansys.grantami.core._mi_value_classes.Range.from_data).
+
+Alias of:
+
+* [`tuple`](https://docs.python.org/3/library/stdtypes.html#tuple) [[`Range_Extrema_Value_Type`](#ansys.grantami.core._mi_value_classes.Range_Extrema_Value_Type), [`Range_Extrema_Value_Type`](#ansys.grantami.core._mi_value_classes.Range_Extrema_Value_Type)]
+* [`list`](https://docs.python.org/3/library/stdtypes.html#list) [[`Range_Extrema_Value_Type`](#ansys.grantami.core._mi_value_classes.Range_Extrema_Value_Type)]
+* [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) [[`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal) [`"high"`, `"low"`], [`Range_Extrema_Value_Type`](#ansys.grantami.core._mi_value_classes.Range_Extrema_Value_Type)]
+* Single [`Range_Extrema_Value_Type`](#ansys.grantami.core._mi_value_classes.Range_Extrema_Value_Type) for ranges with identical low and high values.
+
+
+
+### Range_Extrema_Value_Type
+
+alias of [`SupportsFloat`](https://docs.python.org/3/library/typing.html#typing.SupportsFloat) | [`ValueWithPrecision`](#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) | [`None`](https://docs.python.org/3/library/constants.html#None)
+
+
+
+### *class* ValueWithPrecision(value, number_of_digits)
+
+Represents a float value with a specific precision defined as a number of decimal digits.
+
+Upon import the value is rounded at the specified number of digits. This class helps compute the number of
+significant figures in a value.
+
+* **Parameters:**
+ * **value** ([*float*](https://docs.python.org/3/library/functions.html#float) *or* [*int*](https://docs.python.org/3/library/functions.html#int)) – Float value.
+ * **number_of_digits** ([*int*](https://docs.python.org/3/library/functions.html#int)) – Number of significant decimal places.
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If the value and precision would result in more than 15 significant figures or fewer than 1 significant figure.
+
+### Notes
+
+Up to 15 significant figures are supported.
+
+
+
+#### *property* as_decimal *: [Decimal](https://docs.python.org/3/library/decimal.html#decimal.Decimal)*
+
+Return a [`Decimal`](https://docs.python.org/3/library/decimal.html#decimal.Decimal) representation of the floating point value with the configured precision.
+
+* **Return type:**
+ [decimal.Decimal](https://docs.python.org/3/library/decimal.html#decimal.Decimal)
+
+### Examples
+
+```pycon
+>>> ValueWithPrecision(value=5.4, number_of_digits=2).as_decimal
+Decimal('5.40')
+```
+
+```pycon
+>>> ValueWithPrecision(value=5.4, number_of_digits=4).as_decimal
+Decimal('5.4000')
+```
+
+```pycon
+>>> ValueWithPrecision(value=5.4, number_of_digits=0).as_decimal
+Decimal('5')
+```
+
+
+
+#### *property* number_of_digits *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Number of significant decimal places.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* significant_figures *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Number of significant figures, computed from the floating point value and number of digits.
+
+Significant figures as defined in an MI system include the number of digits in the integral and decimal parts
+of the value.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+### Examples
+
+```pycon
+>>> ValueWithPrecision(value=5.5, number_of_digits=2).significant_figures
+3
+```
+
+```pycon
+>>> ValueWithPrecision(value=10.2, number_of_digits=2).significant_figures
+4
+```
+
+
+
+#### *property* value *: [float](https://docs.python.org/3/library/functions.html#float)*
+
+Floating point value.
+
+* **Return type:**
+ [float](https://docs.python.org/3/library/functions.html#float)
+
+
+
+### *class* TrailingZeroInformation
+
+Trailing zero information for an exported attribute value.
+
+* **Parameters:**
+ * **entered_value** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – String representation of the imported floating-point value.
+ * **entered_unit** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Unit symbol of the entered value.
+ * **significant_figures** ([*int*](https://docs.python.org/3/library/functions.html#int)) – Number of significant figures in the entered value.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`ValueWithPrecision`](#ansys.grantami.core.mi_meta_classes.ValueWithPrecision) to create values with precision information.
+
+
+
+#### *property* as_decimal *: [Decimal](https://docs.python.org/3/library/decimal.html#decimal.Decimal)*
+
+Return a [`Decimal`](https://docs.python.org/3/library/decimal.html#decimal.Decimal) representation of the value.
+
+* **Return type:**
+ [decimal.Decimal](https://docs.python.org/3/library/decimal.html#decimal.Decimal)
+
+### Examples
+
+2 m, measured to a precision of 1 mm:
+
+```pycon
+>>> trailing_zero_information = TrailingZeroInformation("2", "m", 4)
+>>> trailing_zero_information.as_decimal
+Decimal('2.000')
+```
+
+
+
+#### *property* entered_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Unit symbol in which the value with trailing zero information was imported.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* entered_value *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+String representation of the floating point value.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* number_of_digits *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Number of digits, computed from the entered value and significant figures.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* significant_figures *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+Number of significant digits in the value, including trailing zeros.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+
+
+## Functional attribute values
+
+
+
+### *class* SeriesPoint(\*, x, is_estimated=None, decoration=GraphDecoration.LINES, y, parameters=)
+
+Data that represents the value of a point series functional attribute.
+
+This class is a frozen [`dataclass`](https://docs.python.org/3/library/dataclasses.html#module-dataclasses).
+
+* **Parameters:**
+ * **x** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *,* *...* *]* *|* [*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *...* *]*) – Tuple of x-axis parameter values.
+ * **y** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *,* *...* *]*) – Tuple of y-axis values. Must be the same length as the `x` parameter.
+ * **is_estimated** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *...* *]* *,* *optional*) – Whether points are estimated. Defaults to a tuple of [`False`](https://docs.python.org/3/library/constants.html#False) values. If provided, must be a tuple of
+ [`bool`](https://docs.python.org/3/library/functions.html#bool) values and must be the same length as the `x` and `y` parameters.
+ * **parameters** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*SeriesParameterValue*](#ansys.grantami.core._mi_value_classes.SeriesParameterValue) *,* *...* *]* *,* *optional*) – Tuple of [`SeriesParameterValue`](#ansys.grantami.core._mi_value_classes.SeriesParameterValue) objects.
+ * **decoration** ([*GraphDecoration*](#ansys.grantami.core._mi_value_classes.GraphDecoration) *,* *optional*) – [`GraphDecoration`](#ansys.grantami.core._mi_value_classes.GraphDecoration) style. Defaults to [`GraphDecoration.LINES`](#ansys.grantami.core._mi_value_classes.GraphDecoration.LINES).
+
+### Examples
+
+Series with no extra parameters:
+
+```pycon
+>>> series = SeriesPoint(
+... x=(1.0, 2.0),
+... y=(4.5, 5.5),
+... )
+```
+
+Series with additional parameters, all points marked as estimated, and using markers as the display type:
+
+```pycon
+>>> series = SeriesPoint(
+... x=(1.0, 2.0),
+... y=(4.5, 5.5),
+... is_estimated=(True, True),
+... parameters=(
+... SeriesParameterValue("Temperature", 25.0),
+... SeriesParameterValue("Strain rate", 0.01),
+... ),
+... decoration=GraphDecoration.MARKERS,
+... )
+```
+
+
+
+#### *classmethod* from_data(x, y, is_estimated=None, parameters=None, decoration=None)
+
+Alternative constructor to create [`SeriesPoint`](#ansys.grantami.core._mi_value_classes.SeriesPoint) from more general data types.
+
+* **Parameters:**
+ * **x** (*Sequence* *[**SupportsFloat* *]* *|* *Sequence* *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]*) – Sequence of x-axis parameter values.
+ * **y** (*Sequence* *[**SupportsFloat* *]*) – Sequence of values for the y-axis.
+ * **is_estimated** (*Sequence* *[*[*bool*](https://docs.python.org/3/library/functions.html#bool) *]* *,* *optional*) – Whether values are estimated. Defaults to [`None`](https://docs.python.org/3/library/constants.html#None), which results in all points being marked as not
+ estimated.
+ * **parameters** (*Sequence* *[*[*SeriesParameterValue*](#ansys.grantami.core._mi_value_classes.SeriesParameterValue) *]* *,* *optional*) – Sequence of [`SeriesParameterValue`](#ansys.grantami.core._mi_value_classes.SeriesParameterValue) objects.
+ * **decoration** ([*GraphDecoration*](#ansys.grantami.core._mi_value_classes.GraphDecoration) *,* *optional*) – Graph decoration style.
+* **Return type:**
+ [SeriesPoint](#ansys.grantami.core._mi_value_classes.SeriesPoint)
+
+
+
+#### decoration *: [GraphDecoration](#ansys.grantami.core._mi_value_classes.GraphDecoration)* *= 'Lines'*
+
+[`GraphDecoration`](#ansys.grantami.core._mi_value_classes.GraphDecoration) style.
+
+
+
+#### is_estimated *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[bool](https://docs.python.org/3/library/functions.html#bool), ...]* *= None*
+
+Whether points are estimated. Defaults to a tuple of [`False`](https://docs.python.org/3/library/constants.html#False) values.
+
+
+
+#### parameters *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[SeriesParameterValue](#ansys.grantami.core._mi_value_classes.SeriesParameterValue), ...]*
+
+Tuple of [`SeriesParameterValue`](#ansys.grantami.core._mi_value_classes.SeriesParameterValue) objects.
+
+
+
+#### *property* parameters_by_name *: mappingproxy[[str](https://docs.python.org/3/library/stdtypes.html#str), [str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float)]*
+
+Returns a read-only mapping of parameter values by name.
+
+* **Return type:**
+ [`MappingProxyType`](https://docs.python.org/3/library/types.html#types.MappingProxyType) [str, str | float]
+
+
+
+#### x *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...] | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str), ...]*
+
+Tuple of x-axis parameter values.
+
+
+
+#### y *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...]*
+
+Tuple of y-axis values.
+
+
+
+### *class* SeriesRange(\*, x, is_estimated=None, decoration=GraphDecoration.LINES, y_low, y_high, parameters=)
+
+Data that represents the value of a range series functional attribute.
+
+This class is a frozen [`dataclass`](https://docs.python.org/3/library/dataclasses.html#module-dataclasses).
+
+* **Parameters:**
+ * **x** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *,* *...* *]* *|* [*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *...* *]*) – Tuple of x-axis parameter values.
+ * **y_low** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *,* *...* *]*) – Tuple of values for the y-axis lower bound. Must be the same length as the `x` parameter.
+ * **y_high** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *,* *...* *]*) – Tuple of values for the y-axis upper bound. Must be the same length as the `x` parameter.
+ * **is_estimated** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *...* *]* *,* *optional*) – Whether points are estimated. Defaults to a tuple of [`False`](https://docs.python.org/3/library/constants.html#False) values. If provided, must be a tuple of
+ [`bool`](https://docs.python.org/3/library/functions.html#bool) values and must be the same length as the `x`, `y_low`, and `y_high` parameters.
+ * **parameters** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*SeriesParameterValue*](#ansys.grantami.core._mi_value_classes.SeriesParameterValue) *,* *...* *]* *,* *optional*) – Tuple of [`SeriesParameterValue`](#ansys.grantami.core._mi_value_classes.SeriesParameterValue) objects.
+ * **decoration** ([*GraphDecoration*](#ansys.grantami.core._mi_value_classes.GraphDecoration) *,* *optional*) – [`GraphDecoration`](#ansys.grantami.core._mi_value_classes.GraphDecoration) style. Defaults to [`GraphDecoration.LINES`](#ansys.grantami.core._mi_value_classes.GraphDecoration.LINES).
+
+### Examples
+
+Series with no extra parameters:
+
+```pycon
+>>> series = SeriesRange(
+... x=(1.0, 2.0),
+... y_low=(4.5, 5.5),
+... y_high=(4.7, 5.8),
+... )
+```
+
+Series with additional parameters, all points marked as estimated, and using markers as the display type:
+
+```pycon
+>>> series = SeriesRange(
+... x=(1.0, 2.0),
+... y_low=(4.5, 5.5),
+... y_high=(4.7, 5.8),
+... is_estimated=(True, True),
+... parameters=(
+... SeriesParameterValue("Temperature", 25.0),
+... SeriesParameterValue("Strain rate", 0.01),
+... ),
+... decoration=GraphDecoration.LINES_AND_MARKERS,
+... )
+```
+
+
+
+#### *classmethod* from_data(x, y_low, y_high, is_estimated=None, parameters=None, decoration=None)
+
+Alternative constructor to create [`SeriesRange`](#ansys.grantami.core._mi_value_classes.SeriesRange) from more general data types.
+
+* **Parameters:**
+ * **x** (*Sequence* *[**SupportsFloat* *]* *|* *Sequence* *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]*) – Sequence of x-axis parameter values.
+ * **y_low** (*Sequence* *[**SupportsFloat* *]*) – Sequence of values for the y-axis lower bound.
+ * **y_high** (*Sequence* *[**SupportsFloat* *]*) – Sequence of values for the y-axis upper bound.
+ * **is_estimated** (*Sequence* *[*[*bool*](https://docs.python.org/3/library/functions.html#bool) *]* *,* *optional*) – Whether values are estimated. Defaults to [`None`](https://docs.python.org/3/library/constants.html#None), which results in all points being marked as not
+ estimated.
+ * **parameters** (*Sequence* *[*[*SeriesParameterValue*](#ansys.grantami.core._mi_value_classes.SeriesParameterValue) *]* *,* *optional*) – Sequence of [`SeriesParameterValue`](#ansys.grantami.core._mi_value_classes.SeriesParameterValue) objects.
+ * **decoration** ([*GraphDecoration*](#ansys.grantami.core._mi_value_classes.GraphDecoration) *,* *optional*) – Graph decoration style.
+* **Return type:**
+ [SeriesRange](#ansys.grantami.core._mi_value_classes.SeriesRange)
+
+
+
+#### decoration *: [GraphDecoration](#ansys.grantami.core._mi_value_classes.GraphDecoration)* *= 'Lines'*
+
+[`GraphDecoration`](#ansys.grantami.core._mi_value_classes.GraphDecoration) style.
+
+
+
+#### is_estimated *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[bool](https://docs.python.org/3/library/functions.html#bool), ...]* *= None*
+
+Whether points are estimated. Defaults to a tuple of [`False`](https://docs.python.org/3/library/constants.html#False) values.
+
+
+
+#### parameters *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[SeriesParameterValue](#ansys.grantami.core._mi_value_classes.SeriesParameterValue), ...]*
+
+Tuple of [`SeriesParameterValue`](#ansys.grantami.core._mi_value_classes.SeriesParameterValue) objects.
+
+
+
+#### *property* parameters_by_name *: mappingproxy[[str](https://docs.python.org/3/library/stdtypes.html#str), [str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float)]*
+
+Returns a read-only mapping of parameter values by name.
+
+* **Return type:**
+ [`MappingProxyType`](https://docs.python.org/3/library/types.html#types.MappingProxyType) [str, str | float]
+
+
+
+#### x *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...] | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str), ...]*
+
+Tuple of x-axis parameter values.
+
+
+
+#### y_high *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...]*
+
+Tuple of values for the y-axis upper bound.
+
+
+
+#### y_low *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...]*
+
+Tuple of values for the y-axis lower bound.
+
+
+
+### *class* SeriesParameterValue(name, value)
+
+Parameter value for a functional series.
+
+The parameter value applies to the entire [`SeriesPoint`](#ansys.grantami.core._mi_value_classes.SeriesPoint) or [`SeriesRange`](#ansys.grantami.core._mi_value_classes.SeriesRange) it is assigned to.
+
+This class is a frozen [`dataclass`](https://docs.python.org/3/library/dataclasses.html#module-dataclasses).
+
+* **Parameters:**
+ * **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The name of the parameter.
+ * **value** ([*float*](https://docs.python.org/3/library/functions.html#float) *|* [*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The value of the parameter. This must be a ‘float’ for numeric parameters, or a ‘str’ for discrete
+ parameters.
+
+### Examples
+
+```pycon
+>>> parameter = SeriesParameterValue(
+... name="Temperature",
+... value=25.0,
+... )
+```
+
+
+
+#### *classmethod* from_data(name, value)
+
+Alternative constructor to create [`SeriesParameterValue`](#ansys.grantami.core._mi_value_classes.SeriesParameterValue) from more general data types.
+
+* **Parameters:**
+ * **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The name of the parameter.
+ * **value** (*SupportsFloat* *|* [*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The value of the parameter. This must be a ‘float’-like for numeric parameters, or a ‘str’ for discrete
+ parameters.
+* **Return type:**
+ [SeriesParameterValue](#ansys.grantami.core._mi_value_classes.SeriesParameterValue)
+
+
+
+#### name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The name of the parameter.
+
+
+
+#### value *: [float](https://docs.python.org/3/library/functions.html#float) | [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+The value of the parameter.
+
+This must be a ‘float’ for numeric parameters, or a ‘str’ for discrete parameters.
+
+
+
+### *class* GridPoint(\*, x, is_estimated=None, decoration=GraphDecoration.LINES, y, parameters=)
+
+Multi-dimensional data that represents the value of a point grid functional attribute.
+
+This class is a frozen [`dataclass`](https://docs.python.org/3/library/dataclasses.html#module-dataclasses).
+
+* **Parameters:**
+ * **x** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *,* *...* *]* *|* [*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *...* *]*) – Tuple of x-axis parameter values.
+ * **y** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *,* *...* *]*) – Tuple of y-axis values. Must be the same length as the `x` parameter.
+ * **is_estimated** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *...* *]* *,* *optional*) – Whether points are estimated. Defaults to a tuple of [`False`](https://docs.python.org/3/library/constants.html#False) values. If provided, must be a
+ tuple of [`bool`](https://docs.python.org/3/library/functions.html#bool) values and must be the same length as the `x` and `y` parameters.
+ * **parameters** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*GridParameterValues*](#ansys.grantami.core._mi_value_classes.GridParameterValues) *,* *...* *]* *,* *optional*) – Tuple of [`GridParameterValues`](#ansys.grantami.core._mi_value_classes.GridParameterValues) objects.
+ * **decoration** ([*GraphDecoration*](#ansys.grantami.core._mi_value_classes.GraphDecoration) *,* *optional*) – [`GraphDecoration`](#ansys.grantami.core._mi_value_classes.GraphDecoration) style. Defaults to [`GraphDecoration.LINES`](#ansys.grantami.core._mi_value_classes.GraphDecoration.LINES).
+
+### Examples
+
+Grid with no parameters:
+
+```pycon
+>>> grid = GridPoint(
+... x=(1.0, 2.0),
+... y=(4.5, 5.5),
+... )
+```
+
+Grid with additional parameters, all points marked as estimated, and using markers as the display type:
+
+```pycon
+>>> grid = GridPoint(
+... x=(1.0, 2.0, 1.0, 2.0),
+... y=(4.5, 5.5, 4.3, 5.3),
+... is_estimated=(True, True, True, True),
+... parameters=(
+... GridParameterValues("Temperature", (25.0, 25.0, 100.0, 100.0)),
+... ),
+... decoration=GraphDecoration.MARKERS,
+... )
+```
+
+
+
+#### \_\_add_\_(other)
+
+Returns a new grid object that concatenates both grids.
+
+Only grids that define values for the same parameters and use the same decoration style can be concatenated.
+
+* **Parameters:**
+ **other** ([*GridPoint*](#ansys.grantami.core._mi_value_classes.GridPoint)) – The other grid to concatenate with this grid.
+* **Returns:**
+ New instance with merged data from both input grids.
+* **Return type:**
+ [GridPoint](#ansys.grantami.core._mi_value_classes.GridPoint)
+
+### Examples
+
+```pycon
+>>> grid_1 = GridPoint(
+... x=(1.0, 2.0),
+... y=(4.5, 5.5),
+... parameters=(GridParameterValues("Temperature", (25.0, 25.0)),),
+... )
+>>> grid_2 = GridPoint(
+... x=(1.0, 2.0),
+... y=(7.6, 8.6),
+... parameters=(GridParameterValues("Temperature", (100.0, 100.0)),),
+... )
+>>> grid_1 + grid_2 == GridPoint(
+... x=(1.0, 2.0, 1.0, 2.0),
+... y=(4.5, 5.5, 7.6, 8.6),
+... parameters=(GridParameterValues("Temperature", (25.0, 25.0, 100.0, 100.0)),),
+... )
+True
+```
+
+
+
+#### *classmethod* from_data(x, y, is_estimated=None, parameters=None, decoration=None)
+
+Alternative constructor to create [`GridPoint`](#ansys.grantami.core._mi_value_classes.GridPoint) from more general data types.
+
+* **Parameters:**
+ * **x** (*Sequence* *[**SupportsFloat* *]* *|* *Sequence* *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]*) – Sequence of x-axis parameter values.
+ * **y** (*Sequence* *[**SupportsFloat* *]*) – Sequence of values for the y-axis.
+ * **is_estimated** (*Sequence* *[*[*bool*](https://docs.python.org/3/library/functions.html#bool) *]* *,* *optional*) – Whether values are estimated. Defaults to [`None`](https://docs.python.org/3/library/constants.html#None), which results in all points being marked as not
+ estimated.
+ * **parameters** (*Sequence* *[*[*GridParameterValues*](#ansys.grantami.core._mi_value_classes.GridParameterValues) *]* *,* *optional*) – Sequence of [`GridParameterValues`](#ansys.grantami.core._mi_value_classes.GridParameterValues) objects.
+ * **decoration** ([*GraphDecoration*](#ansys.grantami.core._mi_value_classes.GraphDecoration) *,* *optional*) – Graph decoration style.
+
+
+
+#### decoration *: [GraphDecoration](#ansys.grantami.core._mi_value_classes.GraphDecoration)* *= 'Lines'*
+
+[`GraphDecoration`](#ansys.grantami.core._mi_value_classes.GraphDecoration) style.
+
+
+
+#### is_estimated *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[bool](https://docs.python.org/3/library/functions.html#bool), ...]* *= None*
+
+Whether points are estimated. Defaults to a tuple of [`False`](https://docs.python.org/3/library/constants.html#False) values.
+
+
+
+#### parameters *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[GridParameterValues](#ansys.grantami.core._mi_value_classes.GridParameterValues), ...]*
+
+Tuple of [`GridParameterValues`](#ansys.grantami.core._mi_value_classes.GridParameterValues) objects.
+
+
+
+#### *property* parameters_by_name *: mappingproxy[[str](https://docs.python.org/3/library/stdtypes.html#str), [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str), ...] | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...]]*
+
+Returns a read-only mapping of parameter values by name.
+
+* **Return type:**
+ [`MappingProxyType`](https://docs.python.org/3/library/types.html#types.MappingProxyType) [str, tuple[str, …] | tuple[float, …]]
+
+
+
+#### x *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...] | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str), ...]*
+
+Tuple of x-axis parameter values.
+
+
+
+#### y *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...]*
+
+Tuple of y-axis values.
+
+
+
+### *class* GridRange(\*, x, is_estimated=None, decoration=GraphDecoration.LINES, y_low, y_high, parameters=)
+
+Multi-dimensional data that represents the value of a range grid functional attribute.
+
+This class is a frozen [`dataclass`](https://docs.python.org/3/library/dataclasses.html#module-dataclasses).
+
+* **Parameters:**
+ * **x** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *,* *...* *]* *|* [*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *...* *]*) – Tuple of x-axis parameter values.
+ * **y_low** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *,* *...* *]*) – Tuple of values for the y-axis lower bound. Must be the same length as the `x` parameter.
+ * **y_high** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *,* *...* *]*) – Tuple of values for the y-axis upper bound. Must be the same length as the `x` parameter.
+ * **is_estimated** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *...* *]* *,* *optional*) – Whether points are estimated. Defaults to a tuple of [`False`](https://docs.python.org/3/library/constants.html#False) values. If provided, must be a tuple of
+ [`bool`](https://docs.python.org/3/library/functions.html#bool) values and must be the same length as the `x`, `y_low`, and ``y_high` parameters.
+ * **parameters** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*GridParameterValues*](#ansys.grantami.core._mi_value_classes.GridParameterValues) *,* *...* *]* *,* *optional*) – Tuple of [`GridParameterValues`](#ansys.grantami.core._mi_value_classes.GridParameterValues) objects.
+ * **decoration** ([*GraphDecoration*](#ansys.grantami.core._mi_value_classes.GraphDecoration) *,* *optional*) – [`GraphDecoration`](#ansys.grantami.core._mi_value_classes.GraphDecoration) style. Defaults to [`GraphDecoration.LINES`](#ansys.grantami.core._mi_value_classes.GraphDecoration.LINES).
+
+### Examples
+
+Grid with no parameters:
+
+```pycon
+>>> grid = GridRange(
+... x=(1.0, 2.0),
+... y_low=(4.5, 5.5),
+... y_high=(4.55, 5.55),
+... )
+```
+
+Grid with additional parameters, all points marked as estimated, and using markers as the display type:
+
+```pycon
+>>> grid = GridRange(
+... x=(1.0, 2.0, 1.0, 2.0),
+... y_low=(4.5, 5.5, 4.3, 5.3),
+... y_high=(4.55, 5.55, 4.35, 5.35),
+... is_estimated=(True, True, True, True),
+... parameters=(
+... GridParameterValues("Temperature", (25.0, 25.0, 100.0, 100.0)),
+... ),
+... decoration=GraphDecoration.MARKERS,
+... )
+```
+
+
+
+#### \_\_add_\_(other)
+
+Returns a new grid object that concatenates both grids.
+
+Only grids that define values for the same parameters and use the same decoration style can be concatenated.
+
+* **Parameters:**
+ **other** ([*GridRange*](#ansys.grantami.core._mi_value_classes.GridRange)) – The other grid to concatenate with this grid.
+* **Returns:**
+ New instance with merged data from both input grids.
+* **Return type:**
+ [GridRange](#ansys.grantami.core._mi_value_classes.GridRange)
+
+### Examples
+
+```pycon
+>>> grid_1 = GridRange(
+... x=(1.0, 2.0),
+... y_low=(4.5, 5.5),
+... y_high=(4.55, 5.55),
+... parameters=(GridParameterValues("Temperature", (25.0, 25.0)),),
+... )
+>>> grid_2 = GridRange(
+... x=(1.0, 2.0),
+... y_low=(7.6, 8.6),
+... y_high=(7.65, 8.65),
+... parameters=(GridParameterValues("Temperature", (100.0, 100.0)),),
+... )
+>>> grid_1 + grid_2 == GridRange(
+... x=(1.0, 2.0, 1.0, 2.0),
+... y_low=(4.5, 5.5, 7.6, 8.6),
+... y_high=(4.55, 5.55, 7.65, 8.65),
+... parameters=(GridParameterValues("Temperature", (25.0, 25.0, 100.0, 100.0)),),
+... )
+True
+```
+
+
+
+#### *classmethod* from_data(x, y_low, y_high, is_estimated=None, parameters=None, decoration=None)
+
+Alternative constructor to create [`GridRange`](#ansys.grantami.core._mi_value_classes.GridRange) from more general data types.
+
+* **Parameters:**
+ * **x** (*Sequence* *[**SupportsFloat* *]* *|* *Sequence* *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]*) – Sequence of x-axis parameter values.
+ * **y_low** (*Sequence* *[**SupportsFloat* *]*) – Sequence of values for the y-axis lower bound.
+ * **y_high** (*Sequence* *[**SupportsFloat* *]*) – Sequence of values for the y-axis upper bound.
+ * **is_estimated** (*Sequence* *[*[*bool*](https://docs.python.org/3/library/functions.html#bool) *]* *,* *optional*) – Whether values are estimated. Defaults to [`None`](https://docs.python.org/3/library/constants.html#None), which results in all points being marked as not
+ estimated.
+ * **parameters** (*Sequence* *[*[*GridParameterValues*](#ansys.grantami.core._mi_value_classes.GridParameterValues) *]* *,* *optional*) – Sequence of [`GridParameterValues`](#ansys.grantami.core._mi_value_classes.GridParameterValues) objects.
+ * **decoration** ([*GraphDecoration*](#ansys.grantami.core._mi_value_classes.GraphDecoration) *,* *optional*) – Graph decoration style.
+
+
+
+#### decoration *: [GraphDecoration](#ansys.grantami.core._mi_value_classes.GraphDecoration)* *= 'Lines'*
+
+[`GraphDecoration`](#ansys.grantami.core._mi_value_classes.GraphDecoration) style.
+
+
+
+#### is_estimated *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[bool](https://docs.python.org/3/library/functions.html#bool), ...]* *= None*
+
+Whether points are estimated. Defaults to a tuple of [`False`](https://docs.python.org/3/library/constants.html#False) values.
+
+
+
+#### parameters *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[GridParameterValues](#ansys.grantami.core._mi_value_classes.GridParameterValues), ...]*
+
+Tuple of [`GridParameterValues`](#ansys.grantami.core._mi_value_classes.GridParameterValues) objects.
+
+
+
+#### *property* parameters_by_name *: mappingproxy[[str](https://docs.python.org/3/library/stdtypes.html#str), [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str), ...] | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...]]*
+
+Returns a read-only mapping of parameter values by name.
+
+* **Return type:**
+ [`MappingProxyType`](https://docs.python.org/3/library/types.html#types.MappingProxyType) [str, tuple[str, …] | tuple[float, …]]
+
+
+
+#### x *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...] | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str), ...]*
+
+Tuple of x-axis parameter values.
+
+
+
+#### y_high *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...]*
+
+Tuple of values for the y-axis upper bound.
+
+
+
+#### y_low *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...]*
+
+Tuple of values for the y-axis lower bound.
+
+
+
+### *class* GridParameterValues(name, values)
+
+Parameter values for a functional grid.
+
+When assigned to [`GridPoint`](#ansys.grantami.core._mi_value_classes.GridPoint) or [`GridRange`](#ansys.grantami.core._mi_value_classes.GridRange), there must be as many parameter values as xy value
+pairs in the grid.
+
+This class is a frozen [`dataclass`](https://docs.python.org/3/library/dataclasses.html#module-dataclasses).
+
+* **Parameters:**
+ * **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Name of the parameter.
+ * **values** ([*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*float*](https://docs.python.org/3/library/functions.html#float) *,* *...* *]* *|* [*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *...* *]*) – Tuple of values for the parameter. [`float`](https://docs.python.org/3/library/functions.html#float) for numeric parameters, [`str`](https://docs.python.org/3/library/stdtypes.html#str) for discrete parameters.
+
+### Examples
+
+```pycon
+>>> parameter = GridParameterValues(
+... name="Temperature",
+... values=(10.0, 20.0),
+... )
+```
+
+
+
+#### *classmethod* from_data(name, values)
+
+Alternative constructor to create [`GridParameterValues`](#ansys.grantami.core._mi_value_classes.GridParameterValues) from more general data types.
+
+* **Parameters:**
+ * **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – The name of the parameter.
+ * **values** (*Sequence* *[**SupportsFloat* *]* *|* *Sequence* *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]*) – The value of the parameter. This must be a Sequence of ‘float’-like objects for numeric parameters, or a
+ Sequence of ‘str’ for discrete parameters.
+* **Return type:**
+ [GridParameterValues](#ansys.grantami.core._mi_value_classes.GridParameterValues)
+
+
+
+#### name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the parameter.
+
+
+
+#### values *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[float](https://docs.python.org/3/library/functions.html#float), ...] | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[str](https://docs.python.org/3/library/stdtypes.html#str), ...]*
+
+Tuple of values for the parameter.
+
+
+
+### *class* GraphDecoration
+
+
+
+#### LINES *= 'Lines'*
+
+
+
+#### LINES_AND_MARKERS *= 'LinesAndMarkers'*
+
+
+
+#### MARKERS *= 'Markers'*
+
+
+
+### *class* FunctionalSeriesPointTableView
+
+
+
+#### *property* column_headers
+
+Column headers including units.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* data_by_column *: [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[float](https://docs.python.org/3/library/functions.html#float)] | [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)], [list](https://docs.python.org/3/library/stdtypes.html#list)[[bool](https://docs.python.org/3/library/functions.html#bool)], [list](https://docs.python.org/3/library/stdtypes.html#list)[[None](https://docs.python.org/3/library/constants.html#None)]]*
+
+View of the attribute value in a dictionary format.
+
+This is a view of the attribute value data. Modifying the view has no effect on the underlying attribute value.
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[float](https://docs.python.org/3/library/functions.html#float)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[[bool](https://docs.python.org/3/library/functions.html#bool)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[None]]
+
+### Examples
+
+For a functional attribute named `Stress-Strain (Ranged)`, with an X-axis of `Strain` and an additional
+parameter `Temperature`:
+
+```pycon
+>>> ranged_functional_attribute.value = (
+... SeriesRange(
+... x=(1.0, 2.0, 3.0),
+... y_low=(10.0, 20.0, 30.0),
+... y_high=(11.0, 21.0, 31.0),
+... parameters=(SeriesParameterValue("Temperature", 25.0),),
+... is_estimated=(False, True, False),
+... ),
+... )
+>>> ranged_functional_attribute.table_view.data_by_column
+{'Y min (Stress-Strain (Ranged) [MPa])': [10.0, 20.0, 30.0],
+'Y max (Stress-Strain (Ranged) [MPa])': [11.0, 21.0, 31.0],
+'Strain [% strain]': [1.0, 2.0, 3.0],
+'Temperature [°C]': [25.0, 25.0, 25.0],
+'Estimated point?': [False, True, False]}
+```
+
+
+
+#### *property* parameter_column_index *: [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [int](https://docs.python.org/3/library/functions.html#int)]*
+
+Mapping of parameter names to index in the [`column_headers`](#ansys.grantami.core.mi_attribute_value_classes.FunctionalSeriesPointTableView.column_headers).
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [int](https://docs.python.org/3/library/functions.html#int)]
+
+
+
+#### *property* table_view *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float) | [bool](https://docs.python.org/3/library/functions.html#bool) | [None](https://docs.python.org/3/library/constants.html#None)]]*
+
+Value returned by [`AttributeFunctionalSeriesPoint.value`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint.value) in Scripting Toolkit versions earlier than 5.0.
+
+Modifying the view has no effect on the underlying attribute value.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) or [float](https://docs.python.org/3/library/functions.html#float) or [bool](https://docs.python.org/3/library/functions.html#bool) or None]]
+
+### Examples
+
+For a functional attribute named `Stress-Strain`, with an X-axis of `Strain` and an additional parameter
+`Temperature`:
+
+```pycon
+>>> functional_attribute: AttributeFunctionalSeriesPoint
+>>> functional_attribute.value = (
+... SeriesPoint(x=(0.0, 1.0, 2.0), y=(900.0, 1210.0, 1250.0), parameters=(SeriesParameterValue("Temperature", 25.0),)),
+... )
+>>> functional_attribute.table_view.table_view
+[['Y min (Stress-Strain [MPa])', 'Y max (Stress-Strain [MPa])', 'Strain [% strain]', 'Temperature [°C]', 'Estimated point?'],
+[900.0, 900.0, 0.0, 25.0, False],
+[1210.0, 1210.0, 1.0, 25.0, False],
+[1250.0, 1250.0, 2.0, 25.0, False]]
+```
+
+
+
+#### *property* table_view_with_series_number *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float) | [bool](https://docs.python.org/3/library/functions.html#bool) | [None](https://docs.python.org/3/library/constants.html#None) | [int](https://docs.python.org/3/library/functions.html#int)]]*
+
+Table view of the attribute value as a list of points, including the series number.
+
+Modifying the view has no effect on the underlying attribute value.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) or [float](https://docs.python.org/3/library/functions.html#float) or [bool](https://docs.python.org/3/library/functions.html#bool) or None or [int](https://docs.python.org/3/library/functions.html#int)]]
+
+### Examples
+
+For a functional attribute named `Stress-Strain`, with an X-axis of `Strain` and an additional parameter
+`Temperature`:
+
+```pycon
+>>> functional_attribute: AttributeFunctionalSeriesPoint
+>>> functional_attribute.value = (
+... SeriesPoint(x=(0.0, 1.0, 2.0), y=(900.0, 1210.0, 1250.0), parameters=(SeriesParameterValue("Temperature", 25.0),)),
+... )
+>>> functional_attribute.table_view.table_view_with_series_number
+[['Y min (Stress-Strain [MPa])', 'Y max (Stress-Strain [MPa])', 'Strain [% strain]', 'Temperature [°C]', 'Estimated point?', 'Series number'],
+[900.0, 900.0, 0.0, 25.0, False, 1],
+[1210.0, 1210.0, 1.0, 25.0, False, 1],
+[1250.0, 1250.0, 2.0, 25.0, False, 1]]
+```
+
+
+
+### *class* FunctionalSeriesRangeTableView
+
+
+
+#### *property* column_headers
+
+Column headers including units.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* data_by_column *: [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[float](https://docs.python.org/3/library/functions.html#float)] | [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)], [list](https://docs.python.org/3/library/stdtypes.html#list)[[bool](https://docs.python.org/3/library/functions.html#bool)], [list](https://docs.python.org/3/library/stdtypes.html#list)[[None](https://docs.python.org/3/library/constants.html#None)]]*
+
+View of the attribute value in a dictionary format.
+
+This is a view of the attribute value data. Modifying the view has no effect on the underlying attribute value.
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[float](https://docs.python.org/3/library/functions.html#float)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[[bool](https://docs.python.org/3/library/functions.html#bool)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[None]]
+
+### Examples
+
+For a functional attribute named `Stress-Strain (Ranged)`, with an X-axis of `Strain` and an additional
+parameter `Temperature`:
+
+```pycon
+>>> ranged_functional_attribute.value = (
+... SeriesRange(
+... x=(1.0, 2.0, 3.0),
+... y_low=(10.0, 20.0, 30.0),
+... y_high=(11.0, 21.0, 31.0),
+... parameters=(SeriesParameterValue("Temperature", 25.0),),
+... is_estimated=(False, True, False),
+... ),
+... )
+>>> ranged_functional_attribute.table_view.data_by_column
+{'Y min (Stress-Strain (Ranged) [MPa])': [10.0, 20.0, 30.0],
+'Y max (Stress-Strain (Ranged) [MPa])': [11.0, 21.0, 31.0],
+'Strain [% strain]': [1.0, 2.0, 3.0],
+'Temperature [°C]': [25.0, 25.0, 25.0],
+'Estimated point?': [False, True, False]}
+```
+
+
+
+#### *property* parameter_column_index *: [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [int](https://docs.python.org/3/library/functions.html#int)]*
+
+Mapping of parameter names to index in the [`column_headers`](#ansys.grantami.core.mi_attribute_value_classes.FunctionalSeriesRangeTableView.column_headers).
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [int](https://docs.python.org/3/library/functions.html#int)]
+
+
+
+#### *property* table_view *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float) | [bool](https://docs.python.org/3/library/functions.html#bool) | [None](https://docs.python.org/3/library/constants.html#None)]]*
+
+Value returned by [`AttributeFunctionalSeriesRange.value`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange.value) in Scripting Toolkit versions earlier than 5.0.
+
+Modifying the returned value has no effect on the attribute value.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) or [float](https://docs.python.org/3/library/functions.html#float) or [bool](https://docs.python.org/3/library/functions.html#bool) or None]]
+
+### Examples
+
+For a functional attribute named `Stress-Strain (Ranged)`, with an X-axis of `Strain` and an additional parameter
+`Temperature`:
+
+```pycon
+>>> ranged_functional_attribute: AttributeFunctionalSeriesRange
+>>> ranged_functional_attribute.value = (
+... SeriesRange(
+... x=(0.0, 1.0, 2.0),
+... y_low=(900.0, 1210.0, 1250.0),
+... y_high=(910.0, 1220.0, 1260.0),
+... parameters=(SeriesParameterValue("Temperature", 25.0),)
+... ),
+... )
+>>> ranged_functional_attribute.table_view.table_view
+[['Y min (Stress-Strain (Ranged) [MPa])', 'Y max (Stress-Strain (Ranged) [MPa])', 'Strain [% strain]', 'Temperature [°C]', 'Estimated point?'],
+[900.0, 910.0, 0.0, 25.0, False],
+[1210.0, 1220.0, 1.0, 25.0, False],
+[1250.0, 1260.0, 2.0, 25.0, False]]
+```
+
+
+
+#### *property* table_view_with_series_number *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float) | [bool](https://docs.python.org/3/library/functions.html#bool) | [None](https://docs.python.org/3/library/constants.html#None) | [int](https://docs.python.org/3/library/functions.html#int)]]*
+
+Table view of the attribute value as a list of points, including the series number.
+
+Modifying the view has no effect on the underlying attribute value.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) or [float](https://docs.python.org/3/library/functions.html#float) or [bool](https://docs.python.org/3/library/functions.html#bool) or None or [int](https://docs.python.org/3/library/functions.html#int)]]
+
+### Examples
+
+For a functional attribute named `Stress-Strain (Ranged)`, with an X-axis of `Strain` and an additional
+parameter `Temperature`:
+
+```pycon
+>>> ranged_functional_attribute: AttributeFunctionalSeriesRange
+>>> ranged_functional_attribute.value = (
+... SeriesRange(
+... x=(0.0, 1.0, 2.0),
+... y_low=(900.0, 1210.0, 1250.0),
+... y_high=(910.0, 1220.0, 1260.0),
+... parameters=(SeriesParameterValue("Temperature", 25.0),)
+... ),
+... )
+>>> ranged_functional_attribute.table_view.table_view_with_series_number
+[['Y min (Stress-Strain (Ranged) [MPa])', 'Y max (Stress-Strain (Ranged) [MPa])', 'Strain [% strain]', 'Temperature [°C]', 'Estimated point?', 'Series number'],
+[900.0, 910.0, 0.0, 25.0, False, 1],
+[1210.0, 1220.0, 1.0, 25.0, False, 1],
+[1250.0, 1260.0, 2.0, 25.0, False, 1]]
+```
+
+
+
+### *class* FunctionalGridPointTableView
+
+
+
+#### *property* column_headers
+
+Column headers including units.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* data_by_column *: [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[float](https://docs.python.org/3/library/functions.html#float)] | [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)], [list](https://docs.python.org/3/library/stdtypes.html#list)[[bool](https://docs.python.org/3/library/functions.html#bool)], [list](https://docs.python.org/3/library/stdtypes.html#list)[[None](https://docs.python.org/3/library/constants.html#None)]]*
+
+View of the attribute value in a dictionary format.
+
+This is a view of the attribute value data. Modifying the view has no effect on the underlying attribute value.
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[float](https://docs.python.org/3/library/functions.html#float)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[[bool](https://docs.python.org/3/library/functions.html#bool)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[None]]
+
+### Examples
+
+For a functional attribute named `Stress-Strain (Ranged)`, with an X-axis of `Strain` and an additional
+parameter `Temperature`:
+
+```pycon
+>>> ranged_functional_attribute.value = (
+... SeriesRange(
+... x=(1.0, 2.0, 3.0),
+... y_low=(10.0, 20.0, 30.0),
+... y_high=(11.0, 21.0, 31.0),
+... parameters=(SeriesParameterValue("Temperature", 25.0),),
+... is_estimated=(False, True, False),
+... ),
+... )
+>>> ranged_functional_attribute.table_view.data_by_column
+{'Y min (Stress-Strain (Ranged) [MPa])': [10.0, 20.0, 30.0],
+'Y max (Stress-Strain (Ranged) [MPa])': [11.0, 21.0, 31.0],
+'Strain [% strain]': [1.0, 2.0, 3.0],
+'Temperature [°C]': [25.0, 25.0, 25.0],
+'Estimated point?': [False, True, False]}
+```
+
+
+
+#### *property* parameter_column_index *: [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [int](https://docs.python.org/3/library/functions.html#int)]*
+
+Mapping of parameter names to index in the [`column_headers`](#ansys.grantami.core.mi_attribute_value_classes.FunctionalGridPointTableView.column_headers).
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [int](https://docs.python.org/3/library/functions.html#int)]
+
+
+
+#### *property* table_view *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float) | [bool](https://docs.python.org/3/library/functions.html#bool) | [None](https://docs.python.org/3/library/constants.html#None)]]*
+
+Value returned by [`AttributeFunctionalGridPoint.value`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint.value) in Scripting Toolkit versions earlier than 5.0.
+
+Modifying the view has no effect on the underlying attribute value.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) or [float](https://docs.python.org/3/library/functions.html#float) or [bool](https://docs.python.org/3/library/functions.html#bool) or None]]
+
+### Examples
+
+For a functional attribute named `Stress-Strain`, with an X-axis of `Strain` and an additional parameter
+`Temperature`:
+
+```pycon
+>>> gridded_functional_attribute: AttributeFunctionalGridPoint
+>>> gridded_functional_attribute.value = GridPoint(
+... x=(0.0, 1.0, 2.0, 0.0, 1.0, 2.0),
+... y=(900.0, 1210.0, 1250.0, 895.0, 1205.0, 1245.0),
+... parameters=(GridParameterValues("Temperature", (25.0, 25.0, 25.0, 100.0, 100.0, 100.0)),)
+... )
+>>> gridded_functional_attribute.table_view.table_view
+[['Y min (Stress-Strain [MPa])',
+ 'Y max (Stress-Strain [MPa])',
+ 'Strain [% strain]',
+ 'Temperature [°C]',
+ 'Estimated point?'],
+[900.0, 900.0, 0.0, 25.0, False],
+[1210.0, 1210.0, 1.0, 25.0, False],
+[1250.0, 1250.0, 2.0, 25.0, False],
+[895.0, 895.0, 0.0, 100.0, False],
+[1205.0, 1205.0, 1.0, 100.0, False],
+[1245.0, 1245.0, 2.0, 100.0, False]]
+```
+
+
+
+### *class* FunctionalGridRangeTableView
+
+
+
+#### *property* column_headers
+
+Column headers including units.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* data_by_column *: [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[float](https://docs.python.org/3/library/functions.html#float)] | [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)], [list](https://docs.python.org/3/library/stdtypes.html#list)[[bool](https://docs.python.org/3/library/functions.html#bool)], [list](https://docs.python.org/3/library/stdtypes.html#list)[[None](https://docs.python.org/3/library/constants.html#None)]]*
+
+View of the attribute value in a dictionary format.
+
+This is a view of the attribute value data. Modifying the view has no effect on the underlying attribute value.
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [list](https://docs.python.org/3/library/stdtypes.html#list)[[float](https://docs.python.org/3/library/functions.html#float)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[[bool](https://docs.python.org/3/library/functions.html#bool)] or [list](https://docs.python.org/3/library/stdtypes.html#list)[None]]
+
+### Examples
+
+For a functional attribute named `Stress-Strain (Ranged)`, with an X-axis of `Strain` and an additional
+parameter `Temperature`:
+
+```pycon
+>>> ranged_functional_attribute.value = (
+... SeriesRange(
+... x=(1.0, 2.0, 3.0),
+... y_low=(10.0, 20.0, 30.0),
+... y_high=(11.0, 21.0, 31.0),
+... parameters=(SeriesParameterValue("Temperature", 25.0),),
+... is_estimated=(False, True, False),
+... ),
+... )
+>>> ranged_functional_attribute.table_view.data_by_column
+{'Y min (Stress-Strain (Ranged) [MPa])': [10.0, 20.0, 30.0],
+'Y max (Stress-Strain (Ranged) [MPa])': [11.0, 21.0, 31.0],
+'Strain [% strain]': [1.0, 2.0, 3.0],
+'Temperature [°C]': [25.0, 25.0, 25.0],
+'Estimated point?': [False, True, False]}
+```
+
+
+
+#### *property* parameter_column_index *: [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [int](https://docs.python.org/3/library/functions.html#int)]*
+
+Mapping of parameter names to index in the [`column_headers`](#ansys.grantami.core.mi_attribute_value_classes.FunctionalGridRangeTableView.column_headers).
+
+* **Return type:**
+ [dict](https://docs.python.org/3/library/stdtypes.html#dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [int](https://docs.python.org/3/library/functions.html#int)]
+
+
+
+#### *property* table_view *: [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) | [float](https://docs.python.org/3/library/functions.html#float) | [bool](https://docs.python.org/3/library/functions.html#bool) | [None](https://docs.python.org/3/library/constants.html#None)]]*
+
+Value returned by [`AttributeFunctionalGridRange.value`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange.value) by pre-v5.0 Scripting Toolkit versions.
+
+Modifying the view has no effect on the underlying attribute value.
+
+* **Return type:**
+ [list](https://docs.python.org/3/library/stdtypes.html#list)[[list](https://docs.python.org/3/library/stdtypes.html#list)[[str](https://docs.python.org/3/library/stdtypes.html#str) or [float](https://docs.python.org/3/library/functions.html#float) or [bool](https://docs.python.org/3/library/functions.html#bool) or None]]
+
+### Examples
+
+For a functional attribute named `Stress-Strain (Ranged)`, with an X-axis of `Strain` and an additional parameter
+`Temperature`:
+
+```pycon
+>>> gridded_ranged_functional_attribute: AttributeFunctionalGridRange
+>>> gridded_ranged_functional_attribute.value = GridRange(
+... x=(0.0, 1.0, 2.0, 0.0, 1.0, 2.0),
+... y_low=(900.0, 1210.0, 1250.0, 895.0, 1205.0, 1245.0),
+... y_high=(910.0, 1220.0, 1260.0, 905.0, 1215.0, 1255.0),
+... parameters=(GridParameterValues("Temperature", (25.0, 25.0, 25.0, 100.0, 100.0, 100.0)),)
+... )
+>>> gridded_ranged_functional_attribute.table_view.table_view
+[['Y min (Stress-Strain (Ranged) [MPa])',
+ 'Y max (Stress-Strain (Ranged) [MPa])',
+ 'Strain [% strain]',
+ 'Temperature [°C]',
+ 'Estimated point?'],
+[900.0, 910.0, 0.0, 25.0, False],
+[1210.0, 1220.0, 1.0, 25.0, False],
+[1250.0, 1260.0, 2.0, 25.0, False],
+[895.0, 905.0, 0.0, 100.0, False],
+[1205.0, 1215.0, 1.0, 100.0, False],
+[1245.0, 1255.0, 2.0, 100.0, False]]
+```
+
+
+
+
+
+## Miscellaneous attribute values
+
+
+
+
+
+### *class* UnsupportedType
+
+Represents a data type that is unsupported. No information about the value of the Attribute or the
+Tabular Cell is available. Properties of this object cannot
+be edited.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/table.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/table.md
new file mode 100644
index 0000000000..8556173ad2
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/table.md
@@ -0,0 +1,897 @@
+# Table
+
+
+
+
+
+### *class* Table
+
+Represents an MI table, and provides access to records (particularly searching on record properties),
+exporters and attribute definitions.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`Database.get_table()`](database.md#ansys.grantami.core.mi_tree_classes.Database.get_table) or [`Database.get_table_by_guid()`](database.md#ansys.grantami.core.mi_tree_classes.Database.get_table_by_guid) to access an instance of this class.
+
+
+
+#### add_subsets(values)
+
+Adds single or multiple subsets to the list of subsets currently applied to the [`Table`](#ansys.grantami.core.mi_tree_classes.Table) object.
+
+* **Parameters:**
+ **values** ([*set*](https://docs.python.org/3/library/stdtypes.html#set) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *] or* [*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *] or* [*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]*) – Subset name(s) to add.
+
+### Notes
+
+Makes a Service Layer call if the available subsets have not already been fetched.
+
+
+
+#### all_records(include_folders=False, include_generics=True, filter_by_subset=True, subset_name=None)
+
+Returns a flattened list of all records in the table and populates each [`Record.children`](record.md#ansys.grantami.core.mi_record_classes.Record.children) property.
+
+If `filter_by_subset` is True then the operation will only return records that are in the subset given in
+`subset_name`, if no value is provided then the subset specified on the table will be used.
+
+If `filter_by_subset` is False then records will be returned from all subsets.
+
+* **Parameters:**
+ * **include_folders** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: False*) – Whether to include folders in the results.
+ * **include_generics** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: True*) – Whether to include generics in the results.
+ * **filter_by_subset** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: True*) – Whether to filter records by subset.
+ * **subset_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Name of the subset to use for filtering. If not specified, uses the currently applied subset.
+* **Return type:**
+ list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If more than one subset is applied to the table when `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) and `subset_name`
+ is not provided.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### bulk_fetch(records, attributes=None, batch_size=100, parallelize=False, max_num_threads=6, include_binary_data=False)
+
+Populate attribute and pseudo-attribute values for multiple records in a single operation.
+
+Populates data values for all named [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) and [`PseudoAttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.PseudoAttributeDefinition) objects in
+the specified [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects. Attribute values for requested `attributes` are added to
+[`Record.attributes`](record.md#ansys.grantami.core.mi_record_classes.Record.attributes) dictionary whether the attribute is populated or not.
+
+Meta-attributes can be included in a bulk operation by providing the meta-attribute [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)
+in `attributes`. [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) of meta-attributes can be obtained from the parent attribute
+[`AttributeDefinition.meta_attributes`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition.meta_attributes).
+
+Attribute values will not be created for attributes not included in the export via the attributes argument and
+trying to access them might raise a [`KeyError`](https://docs.python.org/3/library/exceptions.html#KeyError).
+
+#### Versionchanged
+Changed in version 4.2: Argument `parallelise` was renamed to `parallelize`.
+
+* **Parameters:**
+ * **records** (list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]) – List of records to fetch data for.
+ * **attributes** (list[[`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) or [`PseudoAttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.PseudoAttributeDefinition) or str], optional) – List of attributes to fetch. Set to [`None`](https://docs.python.org/3/library/constants.html#None) to export all record data.
+ * **batch_size** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 100*) – Number of records to process in each batch.
+ * **parallelize** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: False*) – Whether to parallelize the fetch operation.
+ * **max_num_threads** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 6*) – Maximum number of threads to use when parallelizing.
+ * **include_binary_data** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: False*) – Whether to include binary data in the fetch.
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If one or more records have not been pushed to the server.
+
+### Notes
+
+Makes Service Layer calls to fetch attribute data in batches.
+
+Providing a list of attributes by name or by [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) will not fetch any meta-attributes
+associated with those attributes. If the meta-attributes are not explicitly requested, then the resulting
+[`AttributeValue.meta_attributes`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue.meta_attributes) dictionary will contain empty meta-attribute values.
+
+If `include_binary_data` is set to [`False`](https://docs.python.org/3/library/constants.html#False) (default), the export will not fetch the binary data
+for the requested File and Picture attributes and tabular columns. Instead, the export will export URLs
+(see [`BinaryType.url`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType.url) for more information about using the URL to access the data). URLs should be used
+for large files and pictures, or if the binary data itself is not required. However, as no data is fetched,
+accessing the `binary_data` property and `save()` method will raise a `ValueError`.
+
+On-demand access to attribute values without using [`Table.bulk_fetch()`](#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) always fetches binary data.
+
+To summarize how the file and picture data can be accessed:
+
+* `include_binary_data = False` (default): The [`BinaryType.url`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType.url) property is populated.
+* `include_binary_data = True`: The [`BinaryType.binary_data`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType.binary_data) property, and
+ [`AttributeFile.save()`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFile.save) and [`AttributePicture.save()`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributePicture.save) methods are both available to access and save
+ the binary data. The [`BinaryType.url`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType.url) property is empty and returns [`None`](https://docs.python.org/3/library/constants.html#None).
+
+This operation performs no subset filtering, so all tabular rows will be included in the response
+regardless of the subset membership of the linked records.
+
+#### WARNING
+`parallelize` should not be set to [`True`](https://docs.python.org/3/library/constants.html#True) when using long-running sessions authenticated via OIDC. See
+[OIDC and parallel operation](../release_notes/known_issues.md#oidc-known-issue) for more details.
+
+If `include_binary_data` is set to [`False`](https://docs.python.org/3/library/constants.html#False):
+
+* [`BinaryType.binary_data`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType.binary_data) and [`BinaryType.save()`](supporting.md#ansys.grantami.core.mi_attribute_value_classes.BinaryType.save) raise a `ValueError`.
+* Calling [`AttributeTabular.enable_destructive_editing()`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.enable_destructive_editing) on a tabular attribute value with unexported
+ binary data emits a [`UserWarning`](https://docs.python.org/3/library/exceptions.html#UserWarning).
+* Proceeding to make destructive changes on a tabular attribute which unexported binary data raises a
+ [`UnexportedBinaryDataError`](exceptions.md#ansys.grantami.core.mi_meta_classes.UnexportedBinaryDataError) on re-import.
+* Modifying the [`LocalFileValue.file_name`](tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalFileValue.file_name) or [`LocalFileValue.description`](tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalFileValue.description) properties for a cell
+ with unexported binary without adding new binary data raises a `ValueError` on re-import.
+
+### Examples
+
+The following code snippet shows how to include meta-attributes and pseudo-attributes in a `bulk_fetch`
+request:
+
+```python
+table = db.get_table("MaterialUniverse")
+attribute_names = ["Density", "Price", "Young's modulus"]
+print("Fetch three attributes by name")
+table.bulk_fetch(records, attributes=attribute_names)
+
+attribute_definitions = [table.attributes[name] for name in attribute_names]
+print("Fetch three attributes by AttributeDefinition")
+table.bulk_fetch(records, attributes=attribute_definitions)
+
+attr_and_meta_definitions = attribute_definitions + [meta_attr
+ for attr in attribute_definitions
+ for meta_attr in attr.meta_attributes.values()]
+print("Fetch three attributes and their meta-attributes")
+table.bulk_fetch(records, attributes=attr_and_meta_definitions)
+
+attr_meta_and_pseudo_definitions = attr_and_meta_definitions + mpy.RecordProperties.all()
+print("Fetch three attributes, their meta-attributes, and all pseudo-attributes")
+table.bulk_fetch(records, attributes=attr_meta_and_pseudo_definitions)
+```
+
+
+
+#### bulk_fetch_all_record_versions(records, batch_size=100, parallelize=False, max_num_threads=6)
+
+Fetches all record versions for all provided records.
+
+Populates the [`Record.all_versions`](record.md#ansys.grantami.core.mi_record_classes.Record.all_versions), [`Record.release_state`](record.md#ansys.grantami.core.mi_record_classes.Record.release_state), and [`Record.record_history`](record.md#ansys.grantami.core.mi_record_classes.Record.record_history)
+properties of the specified [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects.
+
+* **Parameters:**
+ * **records** (list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]) – List of records to fetch versions for.
+ * **batch_size** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 100*) – Number of records to process in each batch.
+ * **parallelize** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: False*) – Whether to parallelize the fetch operation.
+ * **max_num_threads** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 6*) – Maximum number of threads to use when parallelizing.
+
+#### WARNING
+`parallelize` should not be set to [`True`](https://docs.python.org/3/library/constants.html#True) when using long-running sessions authenticated via OIDC. See
+[OIDC and parallel operation](../release_notes/known_issues.md#oidc-known-issue) for more details.
+
+#### SEE ALSO
+[`Session.bulk_fetch_release_states()`](session.md#ansys.grantami.core.mi.Session.bulk_fetch_release_states)
+: Fetches [`Record.release_state`](record.md#ansys.grantami.core.mi_record_classes.Record.release_state) only.
+
+### Notes
+
+Makes Service Layer calls to fetch record versions in batches.
+
+This operation performs multiple requests per batch. As a result, the batch size should be considered a relative
+scale factor to control performance vs load on the Granta MI server, and is not an exact statement of the
+number of records included in each request.
+
+
+
+#### bulk_fetch_associated_records(records, target_table, link_direction='Both', attribute_path=None, batch_size=100, parallelize=False, max_num_threads=6)
+
+Fetches records associated with the specified [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects from a target [`Table`](#ansys.grantami.core.mi_tree_classes.Table).
+
+Returns a list of dictionaries containing the source record and associated records for each [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)
+provided.
+
+You may specify `link_direction` to only follow tabular links in the specified direction, or provide a list of
+[`AttributeDefinitionTabular`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionTabular) objects in `attribute_path` to follow only those tabular links.
+
+#### Versionchanged
+Changed in version 4.2: Argument `parallelise` was renamed to `parallelize`.
+
+* **Parameters:**
+ * **records** (list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]) – List of source records.
+ * **target_table** ([`Table`](#ansys.grantami.core.mi_tree_classes.Table)) – Target table to fetch associated records from.
+ * **link_direction** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *default: "Both"*) – Direction of links to follow: `Both`, `Forward`, or `Reverse`.
+ * **attribute_path** (list[[`AttributeDefinitionTabular`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionTabular)], optional) – List of tabular attributes to follow.
+ * **batch_size** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 100*) – Number of records to process in each batch.
+ * **parallelize** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: False*) – Whether to parallelize the fetch operation.
+ * **max_num_threads** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 6*) – Maximum number of threads to use when parallelizing.
+* **Return type:**
+ list[dict[str, [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) | list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]]]
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If one or more records have not been pushed to the server.
+
+#### WARNING
+`parallelize` should not be set to [`True`](https://docs.python.org/3/library/constants.html#True) when using long-running sessions authenticated via OIDC. See
+[OIDC and parallel operation](../release_notes/known_issues.md#oidc-known-issue) for more details.
+
+### Notes
+
+Makes Service Layer calls to fetch associated records in batches.
+
+
+
+#### bulk_fetch_data_revision_history(records, batch_size=100, parallelize=False, max_num_threads=6)
+
+Fetches the data revision history for all attributes of the provided records.
+
+Populates the [`Record.data_revision_history`](record.md#ansys.grantami.core.mi_record_classes.Record.data_revision_history) property.
+
+#### Versionchanged
+Changed in version 4.2: Argument `parallelise` was renamed to `parallelize`.
+
+* **Parameters:**
+ * **records** (list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]) – List of records to fetch data revision history for.
+ * **batch_size** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 100*) – Number of records to process in each batch.
+ * **parallelize** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: False*) – Whether to parallelize the fetch operation.
+ * **max_num_threads** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 6*) – Maximum number of threads to use when parallelizing.
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If one or more records have not been pushed to the server.
+
+#### WARNING
+`parallelize` should not be set to [`True`](https://docs.python.org/3/library/constants.html#True) when using long-running sessions authenticated via OIDC. See
+[OIDC and parallel operation](../release_notes/known_issues.md#oidc-known-issue) for more details.
+
+### Notes
+
+Makes Service Layer calls to fetch data revision history in batches.
+
+
+
+#### bulk_link_fetch(records, link_groups=None, batch_size=100, parallelize=False, max_num_threads=6, filter_subsets=True)
+
+Fetches and populates record link groups for the specified [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects.
+
+#### Versionchanged
+Changed in version 4.2: Argument `parallelise` was renamed to `parallelize`.
+
+* **Parameters:**
+ * **records** (list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]) – List of records to fetch links for.
+ * **link_groups** ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]* *,* *optional*) – List of link group names to fetch. Set to [`None`](https://docs.python.org/3/library/constants.html#None) to fetch all.
+ * **batch_size** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 100*) – Number of records to process in each batch.
+ * **parallelize** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: False*) – Whether to parallelize the fetch operation.
+ * **max_num_threads** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *default: 6*) – Maximum number of threads to use when parallelizing.
+ * **filter_subsets** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: True*) – Whether to filter by subsets. If [`True`](https://docs.python.org/3/library/constants.html#True), only linked records in the default subset of their table are
+ returned. If [`False`](https://docs.python.org/3/library/constants.html#False), linked records are returned from all subsets.
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If one or more records have not been pushed to the server.
+
+#### WARNING
+`parallelize` should not be set to [`True`](https://docs.python.org/3/library/constants.html#True) when using long-running sessions authenticated via OIDC. See
+[OIDC and parallel operation](../release_notes/known_issues.md#oidc-known-issue) for more details.
+
+### Notes
+
+Makes Service Layer calls to fetch links in batches.
+
+
+
+#### create_empty_attribute_value(definition)
+
+Create an empty [`AttributeValue`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) instance for an attribute.
+
+This can subsequently be assigned to a record for import.
+
+* **Parameters:**
+ **definition** ([`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)) – Attribute definition object.
+* **Return type:**
+ [`AttributeValue`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue)
+
+
+
+#### create_record(name, parent=None, short_name=None, attributes=None, folder=False, subsets=None, release_record=False, color=RecordColor.InheritFromParent)
+
+Creates a new [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) object in the [`Table`](#ansys.grantami.core.mi_tree_classes.Table).
+
+The record will not exist in Granta MI or be assignable as a parent until it is pushed to the server.
+
+* **Parameters:**
+ * **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Long name of the record.
+ * **parent** ([`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) or [`Table`](#ansys.grantami.core.mi_tree_classes.Table), optional) – Parent record or table.
+ * **short_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Short name of the record.
+ * **attributes** (dict[str, [`AttributeValue`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue)], optional) – Dictionary of attribute values.
+ * **folder** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: False*) – If true, the record will be created as a folder.
+ * **subsets** ([*set*](https://docs.python.org/3/library/stdtypes.html#set) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]* *,* *optional*) – List of subsets the record will belong to. If not specified, record will be added to the currently active
+ subset(s) on the table.
+ * **release_record** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: False*) – Whether the record will be released when pushed to the server.
+ * **color** ([`RecordColor`](constants.md#ansys.grantami.core.mi_constants.RecordColor), default: RecordColor.InheritFromParent) – Record color. If not specified, inherits from parent.
+* **Return type:**
+ [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)
+
+
+
+#### get_attribute_definition(name=None, identity=None)
+
+Returns the [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) object specified by `name` or the identifier `identity`.
+
+Meta-attributes are also returned if the identifier is provided.
+
+* **Parameters:**
+ * **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Name of the [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) object.
+ * **identity** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *optional*) – Attribute identifier.
+* **Return type:**
+ [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) or list[[`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)]
+
+
+
+#### get_available_exporters(package=None, model=None, applicability_tag=None)
+
+Returns exporters available on the table filtered by package, model, and applicability tag value.
+
+* **Parameters:**
+ * **package** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – The target FEA analysis package. For example: ‘NX 10.0’, ‘CATIA V5’.
+ * **model** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – The material model type. For example, ‘Isotropic’, ‘Linear, temperature-independent,
+ isotropic, thermal, plastic’.
+ * **applicability_tag** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – A tag that identifies the applications for which an exporter is intended to be used.
+ For example, ‘MIMaterialsGateway’, ‘MIViewer’.
+* **Return type:**
+ list[[`Exporter`](supporting.md#ansys.grantami.core.mi_exporters.Exporter)]
+
+### Notes
+
+Makes a Service Layer call on first request for each applicability tag.
+
+
+
+#### get_record_by_id(history_identity=None, hguid=None, vguid=None, version_number=None)
+
+Returns the [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) object with the following (sets of) references in priority order.
+
+1. `vguid` (record version GUID): Uniquely identifies specific version of record.
+2. `history_identity` (record history identity): Uniquely identifies record only, and optionally
+ `version_number` (record version number).
+3. `hguid` (record history GUID): Uniquely identifies record only.
+
+If `vguid` or `version_number` are not provided for version controlled records, this method will
+return the latest available version of the record available to the user. The latest available version
+is dependent on the user’s Granta MI permissions.
+
+This method can return records outside the currently selected subset.
+
+* **Parameters:**
+ * **history_identity** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *optional*) – Record history identity.
+ * **hguid** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Record history GUID: uniquely identifies record.
+ * **vguid** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Record version GUID: uniquely identifies record version.
+ * **version_number** ([*int*](https://docs.python.org/3/library/functions.html#int) *,* *optional*) – Record version number.
+* **Returns:**
+ Record object or [`None`](https://docs.python.org/3/library/constants.html#None) if not found.
+* **Return type:**
+ [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### get_record_by_lookup_value(attribute_name, lookup_value)
+
+Returns a [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) object specified by attribute name and an exact match for a short text string.
+
+Provided that:
+
+* The `lookup_value` matches exactly one record in the table.
+* The record is in the default subset of the table.
+
+* **Parameters:**
+ * **attribute_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Name of the attribute to search.
+ * **lookup_value** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Short text string value to match.
+* **Returns:**
+ Record object or [`None`](https://docs.python.org/3/library/constants.html#None) if not found.
+* **Return type:**
+ [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+### Notes
+
+Makes a Service Layer call.
+
+In Granta MI 2025 R2 and later, if multiple matches are detected, no results are returned. In earlier Granta MI
+versions, an exception is raised.
+
+
+
+#### get_records_by_ids(record_identifiers)
+
+Returns a [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) object for each identifier provided.
+
+The returned list of records will have the same number of elements as the provided list of identifiers.
+If no record corresponds to that identifier in this table then the corresponding item in the returned list
+will be [`None`](https://docs.python.org/3/library/constants.html#None).
+
+Each element in the `record_identifiers` parameter should be a dictionary with one or more of the
+following (sets of) references in priority order:
+
+1. `vguid` (record version GUID): Uniquely identifies specific version of record.
+2. `history_identity` (record history identity): Uniquely identifies record only, and optionally
+ `version_number` (record version number).
+3. `hguid` (record history GUID): Uniquely identifies record only.
+
+If `vguid` or `version_number` are not provided for version controlled records, this method will
+return the latest available version of the record available to the user. The latest available version
+is dependent on the user’s Granta MI permissions.
+
+This method can return records outside the currently selected subset.
+
+* **Parameters:**
+ **record_identifiers** (*Sequence* *[*[*dict*](https://docs.python.org/3/library/stdtypes.html#dict) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* [*str*](https://docs.python.org/3/library/stdtypes.html#str) *|* [*int*](https://docs.python.org/3/library/functions.html#int) *]* *]*) – Sequence of dictionaries containing record identifiers.
+* **Return type:**
+ list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) | [`None`](https://docs.python.org/3/library/constants.html#None)]
+
+### Notes
+
+Makes multiple Service Layer calls depending on number of identifiers provided.
+
+
+
+#### get_records_from_path(starting_node, tree_path, use_short_names=False)
+
+Return all records at the end of the provided path from a specified node.
+
+* The starting node identifies the node immediately above the path. To start the path at the top of the tree,
+ set `starting_node` to [`None`](https://docs.python.org/3/library/constants.html#None). To start the path under any other node in the tree,
+ specify a [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) as the `starting_node`.
+* Specify the path as a list of record names e.g. `['Polymers', 'Plastics', 'Thermoplastics', ...]`.
+* You can include “wildcards” in the path by setting a node to [`None`](https://docs.python.org/3/library/constants.html#None) e.g.
+ `['Thermoplastics', :obj:`None`, 'Unfilled', ...]`.
+* By default, the strings specified in the path list are assumed to be record full names; to specify the path
+ using record short names instead, set `use_short_names` to True.
+
+* **Parameters:**
+ * **starting_node** ([`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) or [`None`](https://docs.python.org/3/library/constants.html#None)) – Any Record in the table tree. To start the path at the root node of the table tree, set to [`None`](https://docs.python.org/3/library/constants.html#None).
+ * **tree_path** (list[str or [`None`](https://docs.python.org/3/library/constants.html#None)]) – A list of strings specifying the names of the records in the path. May include [`None`](https://docs.python.org/3/library/constants.html#None) as a wildcard.
+ * **use_short_names** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: False*) – Whether the strings in the path are the record short names.
+* **Return type:**
+ list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If the starting node has not been pushed to the server.
+
+### Notes
+
+Makes multiple Service Layer calls.
+
+### Examples
+
+Example 1:
+
+`recs = table.get_records_from_path(None, ['Record 1', None, 'Record 2'])`
+
+will return all records that are children of a record named Record 2, that also have Record 1 as a
+great-grandparent. The grandparent is set as a wildcard, and so any is allowed.
+
+Example 2:
+
+`recs = table.get_records_from_path(None, ['Record 1', 'Record 3', None])`
+
+will return all records that are grandchildren of records named Record 3 that also have a great-grandparent
+called Record 1.
+
+Both of these examples have assumed that Record 1 is a top-level record (and have a starting node as a table
+object to reflect this), but the method does not require this. The starting node can be any record object in
+the tree.
+
+
+
+#### path_from(starting_node, tree_path, color=RecordColor.InheritFromParent)
+
+Ensures that all the folders in a specified path are available, and creates any that do not already exist.
+
+In the case of a version-controlled table, folders are created in an unreleased state.
+
+* **Parameters:**
+ * **starting_node** ([`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) or [`None`](https://docs.python.org/3/library/constants.html#None)) – Identifies the node under which the new path will start. Set to [`None`](https://docs.python.org/3/library/constants.html#None) to start the path at the root
+ of the table. Set to an existing record/folder to create the path from the specified node.
+ * **tree_path** ([*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]*) – The names of the folders in the path, e.g. `['Polymers', 'Plastics', 'Thermoplastics', ...]`.
+ Folders in the path will be created if they don’t already exist. Existing records on the path will be
+ converted to generic records.
+ * **color** ([`RecordColor`](constants.md#ansys.grantami.core.mi_constants.RecordColor), default: RecordColor.InheritFromParent) – Sets the color of all folders and records in the path.
+* **Returns:**
+ The Record object representing the last folder in the path.
+* **Return type:**
+ [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If one or more start nodes has not been pushed to the server.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### paths_from(paths)
+
+Create multiple paths between specified start and end nodes in the table tree.
+
+See description of [`path_from()`](#ansys.grantami.core.mi_tree_classes.Table.path_from) for further details.
+
+* **Parameters:**
+ **paths** (list[dict[str, [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) | [`None`](https://docs.python.org/3/library/constants.html#None) | [`RecordColor`](constants.md#ansys.grantami.core.mi_constants.RecordColor) | list[str]]]) – List of path specifications.
+* **Return type:**
+ list[tuple[dict, [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]]
+* **Raises:**
+ [**InvalidRecordStateError**](exceptions.md#ansys.grantami.core.mi_meta_classes.InvalidRecordStateError) – If one or more start nodes has not been pushed to the server.
+
+### Examples
+
+Paths are specified as a list of dictionaries with the following structure:
+
+```python
+{'starting_node': Optional[Record],
+'tree_path': ['list', 'of', 'folders'],
+'color': 'color for all new nodes to be assigned'}
+```
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### refetch_children(filter_by_subset=True, subset_name=None)
+
+Refreshes the list of direct children belonging to the table.
+
+If `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) then the operation will only return records that are in the subset given
+in `subset_name`, if no value is provided then the subset specified on the table will be used.
+
+If `filter_by_subset` is [`False`](https://docs.python.org/3/library/constants.html#False) then records will be returned from all subsets.
+
+* **Parameters:**
+ * **filter_by_subset** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: True*) – Whether to filter records by subset.
+ * **subset_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Name of the subset to use for filtering.
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If more than one subset is applied to the table when `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) and `subset_name`
+ is not provided.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### refresh_attributes()
+
+Performs a Foundation API [`BrowseService.get_attribute_details()`](../foundation_api.md#ansys.grantami.backend.soap.BrowseService.BrowseService.get_attribute_details) request and creates a new set of
+attributes.
+
+This method only updates the details of existing attributes. To update the list of available attributes, use
+[`Database.refresh_tables()`](database.md#ansys.grantami.core.mi_tree_classes.Database.refresh_tables).
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### refresh_subsets()
+
+Fetches the list of subsets which can be applied to this table.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### remove_subsets(values)
+
+Removes single or multiple subsets from the list of subsets currently associated with the [`Table`](#ansys.grantami.core.mi_tree_classes.Table) object.
+
+* **Parameters:**
+ **values** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*list*](https://docs.python.org/3/library/stdtypes.html#list) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *] or* [*tuple*](https://docs.python.org/3/library/stdtypes.html#tuple) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *] or* [*set*](https://docs.python.org/3/library/stdtypes.html#set) *[*[*str*](https://docs.python.org/3/library/stdtypes.html#str) *]*) – Subset name(s) to remove.
+
+
+
+#### reset_display_unit(attribute)
+
+Resets the display unit for a `POIN` or `RNGE` attribute back to the unit system default.
+
+* **Parameters:**
+ **attribute** (str or [`AttributeDefinitionPoint`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionPoint) or [`AttributeDefinitionRange`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionRange)) – Attribute name or attribute definition object.
+
+
+
+#### search_for_records_by_name(name, filter_by_subset=True, subset_name=None)
+
+Performs a search on record name within the table.
+
+Returns only the [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects whose short or long names are an exact match for `name`.
+
+If `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) then the search will only return records that are in the subset given
+in `subset_name`, if no value is provided then the subset specified on the table will be used.
+
+If `filter_by_subset` is [`False`](https://docs.python.org/3/library/constants.html#False) then records will be returned from all subsets.
+
+This method is case-insensitive.
+
+* **Parameters:**
+ * **name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Name to search for.
+ * **filter_by_subset** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: True*) – Whether to filter records by subset.
+ * **subset_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Name of the subset to use for filtering.
+* **Return type:**
+ list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If more than one subset is applied to the table when `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) and `subset_name`
+ is not provided.
+
+### Notes
+
+Use [`Database.search_for_records_by_name()`](database.md#ansys.grantami.core.mi_tree_classes.Database.search_for_records_by_name) to search across the whole database.
+
+Makes a Service Layer call.
+
+
+
+#### search_for_records_by_text(text, filter_by_subset=True, subset_name=None)
+
+Performs a simple text search within the table for the specified string.
+
+Returns a list of matching [`Record`](record.md#ansys.grantami.core.mi_record_classes.Record) objects.
+
+If `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) then the search will only return records that are in the subset given in
+`subset_name`, if no value is provided then the subset specified on the table will be used.
+
+If `filter_by_subset` is [`False`](https://docs.python.org/3/library/constants.html#False) then records will be returned from all subsets.
+
+* **Parameters:**
+ * **text** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Text string to search for.
+ * **filter_by_subset** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: True*) – Whether to filter records by subset.
+ * **subset_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Name of the subset to use for filtering.
+* **Return type:**
+ list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If more than one subset is applied to the table when `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) and `subset_name`
+ is not provided.
+
+#### SEE ALSO
+[`Database.search_for_records_by_text()`](database.md#ansys.grantami.core.mi_tree_classes.Database.search_for_records_by_text)
+: Searches for records across the whole database.
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### search_for_records_where(list_of_criteria, silent=False, filter_by_subset=True, subset_name=None)
+
+Performs a search using criteria within the table.
+
+Use [`Database.search_for_records_where()`](database.md#ansys.grantami.core.mi_tree_classes.Database.search_for_records_where) to search across the whole database.
+
+The provided `list_of_criteria` must only comprise criteria defined against attributes in this table or
+criteria defined against pseudo-attributes. If it includes any criteria defined against attributes of another
+table, a [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) is raised.
+
+If `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) then the search will only return records that are in the subset given in
+`subset_name`, if no value is provided then the subset specified on the table will be used.
+
+If `filter_by_subset` is [`False`](https://docs.python.org/3/library/constants.html#False) then records will be returned from all subsets.
+
+* **Parameters:**
+ * **list_of_criteria** (list[[`SearchCriterion`](supporting.md#ansys.grantami.core.mi_meta_classes.SearchCriterion)]) – List of search criteria to apply.
+ * **silent** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: False*) – Whether to ignore errors caused by non-existent attributes.
+ * **filter_by_subset** ([*bool*](https://docs.python.org/3/library/functions.html#bool) *,* *default: True*) – Whether to filter records by subset.
+ * **subset_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *,* *optional*) – Name of the subset to use for filtering.
+* **Returns:**
+ A list of Record objects that match the provided criteria.
+* **Return type:**
+ list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ * [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If more than one subset is applied to the table when `filter_by_subset` is [`True`](https://docs.python.org/3/library/constants.html#True) and `subset_name`
+ is not provided.
+ * [**KeyError**](https://docs.python.org/3/library/exceptions.html#KeyError) – If the search criteria include an attribute that does not exist in the table and `silent` is [`False`](https://docs.python.org/3/library/constants.html#False).
+
+### Notes
+
+Makes a Service Layer call.
+
+Tabular column criteria are aggregated by column name when processed server-side, effectively restricting
+results to records where a single row must meet all criteria on the same column.
+
+To perform a search with multiple tabular column criteria defined on the same column, and obtain results
+where the criteria can be met by individual different rows, perform individual searches for each criterion
+and compute the intersection of the resulting lists of records.
+
+
+
+#### set_display_unit(attribute, unit_symbol)
+
+Sets the display unit for `POIN` and `RNGE` attributes (not used for import or FEA exporters).
+
+* **Parameters:**
+ * **attribute** (str or [`AttributeDefinitionPoint`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionPoint) or [`AttributeDefinitionRange`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionRange)) – Attribute name or attribute definition object.
+ * **unit_symbol** ([*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Unit symbol to set as the display unit.
+
+### Notes
+
+Units that include a currency can only be set with the abstract `currency` unit. This will cause the
+attribute to be returned with the Database Currency. For example instead of `USD/kg` use `currency/kg`.
+
+
+
+#### *property* attributes *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [AttributeDefinition](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)]*
+
+All attributes included in the table schema, indexed by name.
+
+Meta-attributes are accessible through the `meta_attributes` property of their parent attribute.
+
+* **Return type:**
+ dict[str, [`AttributeDefinition`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition)]
+
+### Notes
+
+Makes a Service Layer call if the layouts have not already been fetched.
+
+
+
+#### *property* children *: [List](https://docs.python.org/3/library/typing.html#typing.List)[[Record](record.md#ansys.grantami.core.mi_record_classes.Record)]*
+
+Return the children of the Table node.
+
+Analogous to [`Record.children`](record.md#ansys.grantami.core.mi_record_classes.Record.children), this returns all the records one level from the Table root.
+
+Records returned by this property may have been cached from previous calls to [`Table.refetch_children()`](#ansys.grantami.core.mi_tree_classes.Table.refetch_children) or
+[`Table.all_records()`](#ansys.grantami.core.mi_tree_classes.Table.all_records), which apply subset filtering. If the [`Table`](#ansys.grantami.core.mi_tree_classes.Table) subset configuration has
+since been updated, refresh the list of children via one of the methods listed.
+
+If there is no cached list of children, children are dynamically fetched on property access via
+[`refetch_children()`](#ansys.grantami.core.mi_tree_classes.Table.refetch_children). The default subset filtering behavior is applied.
+
+* **Return type:**
+ list[[`Record`](record.md#ansys.grantami.core.mi_record_classes.Record)]
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If more than one subset is applied to the [`Table`](#ansys.grantami.core.mi_tree_classes.Table).
+
+### Notes
+
+Makes a Service Layer call if the children have not already been fetched.
+
+
+
+#### *property* database *: [Database](database.md#ansys.grantami.core.mi_tree_classes.Database)*
+
+[`Database`](database.md#ansys.grantami.core.mi_tree_classes.Database) in which the [`Table`](#ansys.grantami.core.mi_tree_classes.Table) is defined.
+
+* **Returns:**
+ Database object.
+* **Return type:**
+ [`Database`](database.md#ansys.grantami.core.mi_tree_classes.Database)
+
+
+
+#### *property* db_key *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Parent database key.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* default_layout *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Name of default layout for this [`Table`](#ansys.grantami.core.mi_tree_classes.Table).
+
+* **Return type:**
+ str or [`None`](https://docs.python.org/3/library/constants.html#None)
+
+### Notes
+
+Makes a Service Layer call if the layouts have not already been fetched.
+
+
+
+#### *property* default_subset *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The default subset for this [`Table`](#ansys.grantami.core.mi_tree_classes.Table).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* guid *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+GUID of the table.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* layouts *: [Dict](https://docs.python.org/3/library/typing.html#typing.Dict)[[str](https://docs.python.org/3/library/stdtypes.html#str), [TableLayout](supporting.md#ansys.grantami.core.mi_meta_classes.TableLayout)]*
+
+Fetch and view the layouts available in this table.
+
+* **Return type:**
+ dict[str, [`TableLayout`](supporting.md#ansys.grantami.core.mi_meta_classes.TableLayout)]
+
+### Notes
+
+Makes a Service Layer call if the layouts have not already been fetched.
+
+
+
+#### *property* mi *: [Session](session.md#ansys.grantami.core.mi.Session)*
+
+MI Session that was used to create or access the [`Table`](#ansys.grantami.core.mi_tree_classes.Table) object.
+
+Used for any Service Layer calls made by the [`Table`](#ansys.grantami.core.mi_tree_classes.Table).
+
+* **Returns:**
+ Session object.
+* **Return type:**
+ [`Session`](session.md#ansys.grantami.core.mi.Session)
+
+
+
+#### *property* min_max_type *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+How table-wide minimum and maximum values of point, integer, range, and date-time attributes are calculated.
+
+* [`None`](https://docs.python.org/3/library/constants.html#None): Does not calculate values (can improve performance when loading tables)
+* `Approximate` (default): Uses a fast, approximate algorithm
+* `Exact`: Takes account of current subset and permissions (can be slow on large tables)
+
+Setting this property refetches cache extrema information for all attributes in the table.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+### Notes
+
+Makes a Service Layer call.
+
+
+
+#### *property* name *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Name of the table.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
+
+
+
+#### *property* subsets *: [Set](https://docs.python.org/3/library/typing.html#typing.Set)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+Subsets that are currently applied to the [`Table`](#ansys.grantami.core.mi_tree_classes.Table) object.
+
+Used for record creation, searching, and record fetching.
+
+* **Return type:**
+ [set](https://docs.python.org/3/library/stdtypes.html#set)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+#### WARNING
+If using any Table method which returns a list of records, such as a search method or
+[`Table.all_records()`](#ansys.grantami.core.mi_tree_classes.Table.all_records), you must ensure that only one subset is currently applied to the table.
+Otherwise, a `ValueError` will be raised by that method.
+
+
+
+#### *property* subsets_available *: [Set](https://docs.python.org/3/library/typing.html#typing.Set)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+Subsets which can be applied to this table.
+
+* **Return type:**
+ [set](https://docs.python.org/3/library/stdtypes.html#set)[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+### Notes
+
+Makes a Service Layer call if the subsets have not already been fetched.
+
+
+
+#### *property* unit_system *: [str](https://docs.python.org/3/library/stdtypes.html#str)*
+
+Unit system currently in use.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str)
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/tabular.md b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/tabular.md
new file mode 100644
index 0000000000..f9155d7aab
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/streamlined_api/tabular.md
@@ -0,0 +1,1432 @@
+# Tabular attribute value items
+
+
+
+
+
+
+
+## Tabular row
+
+
+
+
+
+### *class* TabularRow
+
+Represents a single row in a tabular attribute.
+
+Provides access to the cells in the row, as well as the linking value and identifier of the row.
+
+### Notes
+
+Do not create instances of this class. Use [`AttributeTabular.rows`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.rows) to access existing rows and
+[`AttributeTabular.append_row()`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.append_row) to create new rows.
+
+
+
+#### set_linking_value(value)
+
+Sets the linking value of the row.
+
+Set to [`None`](https://docs.python.org/3/library/constants.html#None) to clear the linking value. The row will no longer be linked to any records.
+
+* **Parameters:**
+ **value** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* *None*) – The new linking value for the row.
+* **Raises:**
+ [**ValueError**](https://docs.python.org/3/library/exceptions.html#ValueError) – If [`is_exported`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.is_exported) is [`True`](https://docs.python.org/3/library/constants.html#True) and destructive editing is not enabled.
+
+#### SEE ALSO
+[`AttributeTabular.is_destructive_editing_allowed`](attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.is_destructive_editing_allowed)
+: Whether destructive editing of the tabular attribute value is allowed.
+
+
+
+#### *property* cells *: [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[TabularCell](#ansys.grantami.core._mi_tabular_value_classes.TabularCell) | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[TabularCell](#ansys.grantami.core._mi_tabular_value_classes.TabularCell), ...], ...]*
+
+The cells in the row.
+
+* **Return type:**
+ [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[TabularCell](#ansys.grantami.core._mi_tabular_value_classes.TabularCell)]
+
+
+
+#### *property* cells_by_column *: [Mapping](https://docs.python.org/3/library/typing.html#typing.Mapping)[[str](https://docs.python.org/3/library/stdtypes.html#str), [TabularCell](#ansys.grantami.core._mi_tabular_value_classes.TabularCell) | [tuple](https://docs.python.org/3/library/stdtypes.html#tuple)[[TabularCell](#ansys.grantami.core._mi_tabular_value_classes.TabularCell), ...]]*
+
+The cells in the row, indexed by the column name.
+
+* **Returns:**
+ Mapping of column name to TabularCell.
+* **Return type:**
+ Mapping[[str](https://docs.python.org/3/library/stdtypes.html#str), [TabularCell](#ansys.grantami.core._mi_tabular_value_classes.TabularCell)]
+
+
+
+#### *property* identity *: [int](https://docs.python.org/3/library/functions.html#int)*
+
+The identity of the row.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int)
+
+
+
+#### *property* is_exported *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the row represents an existing row in the database.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* linking_value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+The linking value of the row.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+## Linked tabular cells
+
+
+
+
+
+### *class* TabularCell
+
+Abstract base class for tabular cell value types.
+
+Extended by [`EditableTabularCell`](#ansys.grantami.core._mi_tabular_value_classes.EditableTabularCell).
+
+See the following concrete implementations:
+
+* [`ShortTextValue`](#ansys.grantami.core._mi_tabular_value_classes.ShortTextValue)
+* [`LongTextValue`](#ansys.grantami.core._mi_tabular_value_classes.LongTextValue)
+* [`LogicalValue`](#ansys.grantami.core._mi_tabular_value_classes.LogicalValue)
+* [`IntegerValue`](#ansys.grantami.core._mi_tabular_value_classes.IntegerValue)
+* [`DateValue`](#ansys.grantami.core._mi_tabular_value_classes.DateValue)
+* [`PointValue`](#ansys.grantami.core._mi_tabular_value_classes.PointValue)
+* [`RangeValue`](#ansys.grantami.core._mi_tabular_value_classes.RangeValue)
+* [`HyperlinkValue`](#ansys.grantami.core._mi_tabular_value_classes.HyperlinkValue)
+* [`DiscreteValue`](#ansys.grantami.core._mi_tabular_value_classes.DiscreteValue)
+* [`PictureValue`](#ansys.grantami.core._mi_tabular_value_classes.PictureValue)
+* [`FileValue`](#ansys.grantami.core._mi_tabular_value_classes.FileValue)
+* [`IgnoredLocalTabularCell`](#ansys.grantami.core._mi_tabular_value_classes.IgnoredLocalTabularCell)
+* [`UnavailableTabularCell`](#ansys.grantami.core._mi_tabular_value_classes.UnavailableTabularCell)
+
+
+
+
+
+### *class* ShortTextValue
+
+Represents a single short text value in a linked short text tabular cell.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Text value associated with this tabular cell.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+
+
+### *class* LongTextValue
+
+Represents a single long text value in a linked long text tabular cell.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Text value associated with this tabular cell.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+
+
+### *class* LogicalValue
+
+Represents a single logical value in a linked logical tabular cell.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [bool](https://docs.python.org/3/library/functions.html#bool) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Logical value associated with this tabular cell.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool) or None
+
+
+
+
+
+### *class* IntegerValue
+
+Represents a single integer value in a linked integer tabular cell.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [int](https://docs.python.org/3/library/functions.html#int) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Integer value associated with this cell.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int) or None
+
+
+
+
+
+### *class* DateValue
+
+Represents a single date value in a linked date tabular cell.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [date](https://docs.python.org/3/library/datetime.html#datetime.date) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Date value associated with this tabular cell.
+
+* **Return type:**
+ [`datetime.date`](https://docs.python.org/3/library/datetime.html#datetime.date) or None
+
+
+
+
+
+### *class* PictureValue
+
+Represents a picture value in a linked picture tabular cell.
+
+### Notes
+
+Tabular Picture Cells only support a single binary data value, together with an optional URL and MIME file type.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### save(path)
+
+Save binary data to disk.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – File path where the binary data will be saved.
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If path is not a string or pathlib.Path.
+ * [**AssertionError**](https://docs.python.org/3/library/exceptions.html#AssertionError) – If the value is empty.
+
+
+
+#### *property* binary_data *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Binary data associated with this tabular cell.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+* **Raises:**
+ [**UnexportedBinaryDataError**](exceptions.md#ansys.grantami.core.mi_meta_classes.UnexportedBinaryDataError) – If binary data is available on the server but was not exported.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* mime_file_type *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+MIME (Multipurpose Internet Mail Extensions) file type.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* url *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+URL associated with this tabular cell.
+
+In a future version this property will raise an exception if the attribute is exported with
+`include_binary_data = True`. See [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Binary data if present.
+
+In a future version this property will return the URL if the attribute is exported with
+`include_binary_data = False`. See [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+
+
+
+
+
+### *class* FileValue
+
+Represents a file data value in a linked file tabular cell.
+
+### Notes
+
+Tabular File Cells support a single binary data value and a file name, together with an optional description,
+URL, and MIME file type.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### save(path)
+
+Save binary data to disk.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – File path where the binary data will be saved.
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If path is not a string or pathlib.Path.
+ * [**AssertionError**](https://docs.python.org/3/library/exceptions.html#AssertionError) – If the value is empty.
+
+
+
+#### *property* binary_data *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Binary data associated with this tabular cell.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+* **Raises:**
+ [**UnexportedBinaryDataError**](exceptions.md#ansys.grantami.core.mi_meta_classes.UnexportedBinaryDataError) – If binary data is available on the server but was not exported.
+
+
+
+#### *property* description *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Description of the file.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* file_name *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Name of the file, including the file extension.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* mime_file_type *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+MIME (Multipurpose Internet Mail Extensions) file type.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* url *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+URL associated with this tabular cell.
+
+In a future version this property will raise an exception if the attribute is exported with
+`include_binary_data = True`. See [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Binary data if present.
+
+In a future version this property will return the URL if the attribute is exported with
+`include_binary_data = False`. See [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+
+
+
+
+
+### *class* PointValue
+
+Represents a single point value in a linked point tabular cell.
+
+### Notes
+
+Tabular Point Cells only support a single value and an optional unit.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol of the tabular cell.
+
+* **Returns:**
+ Unit symbol, or [`None`](https://docs.python.org/3/library/constants.html#None) if the cell is dimensionless.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [int](https://docs.python.org/3/library/functions.html#int) | [float](https://docs.python.org/3/library/functions.html#float) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Point value associated with this cell.
+
+* **Return type:**
+ [float](https://docs.python.org/3/library/functions.html#float) or None
+
+
+
+
+
+### *class* RangeValue
+
+Represents a range value in a linked range tabular cell.
+
+### Notes
+
+Tabular Range Cells support a low and high value, both of which can be inclusive or exclusive, together with an
+optional unit.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### *property* high *: [float](https://docs.python.org/3/library/functions.html#float) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+High value of the range.
+
+* **Return type:**
+ [float](https://docs.python.org/3/library/functions.html#float) or None
+
+
+
+#### *property* high_value_is_inclusive *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the high value is included in the range.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* low *: [float](https://docs.python.org/3/library/functions.html#float) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Low value of the range.
+
+* **Return type:**
+ [float](https://docs.python.org/3/library/functions.html#float) or None
+
+
+
+#### *property* low_value_is_inclusive *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the low value is included in the range.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol of the tabular cell.
+
+* **Returns:**
+ Unit symbol, or [`None`](https://docs.python.org/3/library/constants.html#None) if the cell is dimensionless.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+
+
+### *class* DiscreteValue
+
+Represents a single discrete value in a linked discrete tabular cell.
+
+### Notes
+
+Tabular Discrete Cells only support a single value and an order, which is the index of the value in the list of
+possible discrete values for the column. This does not imply that the associated discrete type is ordered.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* order *: [int](https://docs.python.org/3/library/functions.html#int) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Position of the current discrete value in the discrete type.
+
+* **Returns:**
+ Position (1-indexed) in the discrete type. Relevant for ordered discrete types only.
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int) or None
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Discrete value associated with this tabular cell.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+
+
+### *class* HyperlinkValue
+
+Represents a hyperlink value in a linked hyperlink tabular cell.
+
+### Notes
+
+Tabular Hyperlink Cells support a value, a display type, and a description.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### *property* hyperlink_description *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Text which displays instead of the URL in MI applications.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* hyperlink_display *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+How the hyperlink should be opened in MI applications.
+
+Takes one of the following values:
+
+* `New`: Open in a new window or tab.
+* `Top`: Open in the current window or tab.
+* `Content`: Open within the current MI application (for example, in a frame or dialog).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+URL of the hyperlink.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+## Local tabular cells
+
+
+
+
+
+### *class* EditableTabularCell
+
+Abstract base class for editable tabular cell value types.
+
+See the following concrete implementations:
+
+* [`LocalShortTextValue`](#ansys.grantami.core._mi_tabular_value_classes.LocalShortTextValue)
+* [`LocalLongTextValue`](#ansys.grantami.core._mi_tabular_value_classes.LocalLongTextValue)
+* [`LocalLogicalValue`](#ansys.grantami.core._mi_tabular_value_classes.LocalLogicalValue)
+* [`LocalIntegerValue`](#ansys.grantami.core._mi_tabular_value_classes.LocalIntegerValue)
+* [`LocalDateValue`](#ansys.grantami.core._mi_tabular_value_classes.LocalDateValue)
+* [`LocalPointValue`](#ansys.grantami.core._mi_tabular_value_classes.LocalPointValue)
+* [`LocalRangeValue`](#ansys.grantami.core._mi_tabular_value_classes.LocalRangeValue)
+* [`LocalHyperlinkValue`](#ansys.grantami.core._mi_tabular_value_classes.LocalHyperlinkValue)
+* [`LocalDiscreteValue`](#ansys.grantami.core._mi_tabular_value_classes.LocalDiscreteValue)
+* [`LocalPictureValue`](#ansys.grantami.core._mi_tabular_value_classes.LocalPictureValue)
+* [`LocalFileValue`](#ansys.grantami.core._mi_tabular_value_classes.LocalFileValue)
+
+
+
+
+
+### *class* LocalShortTextValue
+
+Represents a single short text value in a local short text tabular cell.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### clear()
+
+Clear the `value` property.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Text value associated with this tabular cell.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+
+
+### *class* LocalLongTextValue
+
+Represents a single long text value in a local long text tabular cell.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### clear()
+
+Clear the `value` property.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Text value associated with this tabular cell.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+
+
+### *class* LocalLogicalValue
+
+Represents a single logical value in a local logical tabular cell.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### clear()
+
+Clear the `value` property.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [bool](https://docs.python.org/3/library/functions.html#bool) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Logical value associated with this tabular cell.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool) or None
+
+
+
+
+
+### *class* LocalIntegerValue
+
+Represents a single integer value in a local integer tabular cell.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### clear()
+
+Clear the `value` property.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [int](https://docs.python.org/3/library/functions.html#int) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Integer value associated with this cell.
+
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int) or None
+
+
+
+
+
+### *class* LocalDateValue
+
+Represents a single date value in a local date tabular cell.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### clear()
+
+Clear the `value` property.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [date](https://docs.python.org/3/library/datetime.html#datetime.date) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Date value associated with this tabular cell.
+
+* **Return type:**
+ [`datetime.date`](https://docs.python.org/3/library/datetime.html#datetime.date) or None
+
+
+
+
+
+### *class* LocalPictureValue
+
+Represents a picture value in a local picture tabular cell.
+
+### Notes
+
+Tabular Picture Cells only support a single binary data value, together with an optional URL and MIME file type.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### clear()
+
+Clear the `binary_data`, `url`, and `mime_file_type` properties.
+
+
+
+#### load(path)
+
+Load an image file into this PictureValue object.
+
+* **Parameters:**
+ **path** ([*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path) *or* [*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Path to the image file to load. Relative paths are permitted. Takes the form
+ `C:\Users\username\Pictures\image.jpg` or `/home/username/Pictures/image.jpg`.
+* **Raises:**
+ [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If path is not a pathlib.Path or string.
+
+
+
+#### save(path)
+
+Save binary data to disk.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – File path where the binary data will be saved.
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If path is not a string or pathlib.Path.
+ * [**AssertionError**](https://docs.python.org/3/library/exceptions.html#AssertionError) – If the value is empty.
+
+
+
+#### *property* binary_data *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Binary data associated with this tabular cell.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+* **Raises:**
+ [**UnexportedBinaryDataError**](exceptions.md#ansys.grantami.core.mi_meta_classes.UnexportedBinaryDataError) – If binary data is available on the server but was not exported.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* mime_file_type *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+MIME (Multipurpose Internet Mail Extensions) file type.
+
+If this object is populated via export, the `mime_file_type` property returns the MIME file type stored in
+Granta MI.
+
+If this object is populated via [`load()`](#ansys.grantami.core._mi_tabular_value_classes.LocalPictureValue.load), or setting [`binary_data`](#ansys.grantami.core._mi_tabular_value_classes.LocalPictureValue.binary_data) or [`value`](#ansys.grantami.core._mi_tabular_value_classes.LocalPictureValue.value), the
+`mime_file_type` property is populated using the `filetype` library. If `filetype` cannot determine the
+MIME file type, the `mime_file_type` property is set to [`None`](https://docs.python.org/3/library/constants.html#None) and Granta MI determines the MIME file
+type during import.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+The [filetype PyPI page](https://pypi.org/project/filetype) lists supported MIME types.
+
+
+
+#### *property* url *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+URL associated with this tabular cell.
+
+In a future version this property will raise an exception if the attribute is exported with
+`include_binary_data = True`. See [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Binary data if present.
+
+In a future version this property will return the URL if the attribute is exported with
+`include_binary_data = False`. See [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+
+
+
+
+
+### *class* LocalFileValue
+
+Represents a file data value in a local tabular cell.
+
+### Notes
+
+Tabular File Cells support a single binary data value and a file name, together with an optional description, URL,
+and MIME file type.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### clear()
+
+Clear the `binary_data`, `url`, `mime_file_type`, `file_name`, and `description` properties.
+
+
+
+#### load(path)
+
+Load a file into this FileValue object.
+
+* **Parameters:**
+ **path** ([*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path) *or* [*str*](https://docs.python.org/3/library/stdtypes.html#str)) – Path to the file to load. Relative paths are permitted. Takes the form
+ `C:\Users\username\Documents\file.pdf` or `/home/username/Documents/file.pdf`.
+* **Raises:**
+ [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If path is not a pathlib.Path or string.
+
+
+
+#### save(path)
+
+Save binary data to disk.
+
+* **Parameters:**
+ **path** ([*str*](https://docs.python.org/3/library/stdtypes.html#str) *or* [*pathlib.Path*](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – File path where the binary data will be saved.
+* **Raises:**
+ * [**TypeError**](https://docs.python.org/3/library/exceptions.html#TypeError) – If path is not a string or pathlib.Path.
+ * [**AssertionError**](https://docs.python.org/3/library/exceptions.html#AssertionError) – If the value is empty.
+
+
+
+#### *property* binary_data *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Binary data associated with this tabular cell.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+* **Raises:**
+ [**UnexportedBinaryDataError**](exceptions.md#ansys.grantami.core.mi_meta_classes.UnexportedBinaryDataError) – If binary data is available on the server but was not exported.
+
+
+
+#### *property* description *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Description of the file.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* file_name *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Name of the file, including the file extension.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* mime_file_type *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+MIME (Multipurpose Internet Mail Extensions) file type.
+
+If this object is populated via export, the `mime_file_type` property returns the MIME file type stored in
+Granta MI.
+
+If this object is populated via [`load()`](#ansys.grantami.core._mi_tabular_value_classes.LocalFileValue.load), or setting [`binary_data`](#ansys.grantami.core._mi_tabular_value_classes.LocalFileValue.binary_data) or [`value`](#ansys.grantami.core._mi_tabular_value_classes.LocalFileValue.value), the
+`mime_file_type` property is populated using the `filetype` library. If `filetype` cannot determine the
+MIME file type, the `mime_file_type` property is set to [`None`](https://docs.python.org/3/library/constants.html#None) and Granta MI determines the MIME file
+type during import.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+### Notes
+
+The [filetype PyPI page](https://pypi.org/project/filetype) lists supported MIME types.
+
+
+
+#### *property* url *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+URL associated with this tabular cell.
+
+In a future version this property will raise an exception if the attribute is exported with
+`include_binary_data = True`. See [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Binary data if present.
+
+In a future version this property will return the URL if the attribute is exported with
+`include_binary_data = False`. See [Planned file and picture data changes](../release_notes/deprecations.md#planned-changes-file-picture) for more details.
+
+* **Return type:**
+ [bytes](https://docs.python.org/3/library/stdtypes.html#bytes) or None
+
+
+
+
+
+### *class* LocalPointValue
+
+Represents a single point value in a local point tabular cell.
+
+### Notes
+
+Tabular Point Cells only support a single value and an optional unit. This class also exposes the default unit based
+on the column definition.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### clear()
+
+Clear the `value` property.
+
+Revert the `unit` property its default value.
+
+
+
+#### *property* default_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Default unit symbol of the tabular cell.
+
+* **Returns:**
+ Default unit symbol as defined by the column, or [`None`](https://docs.python.org/3/library/constants.html#None) if the column is dimensionless.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol of the tabular cell.
+
+* **Returns:**
+ Unit symbol, or [`None`](https://docs.python.org/3/library/constants.html#None) if the cell is dimensionless.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* value *: [int](https://docs.python.org/3/library/functions.html#int) | [float](https://docs.python.org/3/library/functions.html#float) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Point value associated with this cell.
+
+* **Return type:**
+ [float](https://docs.python.org/3/library/functions.html#float) or None
+
+
+
+
+
+### *class* LocalRangeValue
+
+Represents a range value in a local range tabular cell.
+
+### Notes
+
+Tabular Range Cells support a low and high value, both of which can be inclusive or exclusive, together with an
+optional unit. This class also exposes the default unit based on the column definition.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### clear()
+
+Clear the `low` and `high` properties.
+
+Revert `low_value_is_inclusive`, `high_value_is_inclusive`, and `unit` properties to their default values.
+
+
+
+#### *property* default_unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Default unit symbol of the tabular cell.
+
+* **Returns:**
+ Default unit symbol as defined on the column, or [`None`](https://docs.python.org/3/library/constants.html#None) if the column is dimensionless.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* high *: [float](https://docs.python.org/3/library/functions.html#float) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+High value of the range.
+
+* **Return type:**
+ [float](https://docs.python.org/3/library/functions.html#float) or None
+
+
+
+#### *property* high_value_is_inclusive *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the high value is included in the range.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* low *: [float](https://docs.python.org/3/library/functions.html#float) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Low value of the range.
+
+* **Return type:**
+ [float](https://docs.python.org/3/library/functions.html#float) or None
+
+
+
+#### *property* low_value_is_inclusive *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the low value is included in the range.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* unit *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Unit symbol of the tabular cell.
+
+* **Returns:**
+ Unit symbol, or [`None`](https://docs.python.org/3/library/constants.html#None) if the cell is dimensionless.
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+
+
+### *class* LocalDiscreteValue
+
+Represents a single discrete value in a local discrete tabular cell.
+
+### Notes
+
+Tabular Discrete Cells only support a single value and an order, which is the index of the value in the list of
+possible discrete values for the column. This does not imply that the associated discrete type is ordered. This
+class also exposes the possible discrete values based on the column definition.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### clear()
+
+Clear the `value` property.
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* order *: [int](https://docs.python.org/3/library/functions.html#int) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Position of the current discrete value in the discrete type.
+
+* **Returns:**
+ Position (1-indexed) in the discrete type. Relevant for ordered discrete types only.
+* **Return type:**
+ [int](https://docs.python.org/3/library/functions.html#int) or None
+
+
+
+#### *property* possible_discrete_values *: [FrozenSet](https://docs.python.org/3/library/typing.html#typing.FrozenSet)[[str](https://docs.python.org/3/library/stdtypes.html#str)]*
+
+Set of the tabular cell’s possible discrete data values.
+
+* **Return type:**
+ FrozenSet[[str](https://docs.python.org/3/library/stdtypes.html#str)]
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Discrete value associated with this tabular cell.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+
+
+### *class* LocalHyperlinkValue
+
+Represents a hyperlink value in a local hyperlink tabular cell.
+
+### Notes
+
+Tabular Hyperlink Cells support a value, a display text, and a description.
+
+Do not create instances of this class; it represents a pre-existing database structure. Use
+[`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) to access an instance of this class.
+
+
+
+#### clear()
+
+Clear the `value`, `hyperlink_display`, and `hyperlink_description` properties.
+
+
+
+#### *property* hyperlink_description *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+Text which displays instead of the URL in MI applications.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* hyperlink_display *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+How the hyperlink should be opened in MI applications.
+
+Takes one of the following values:
+
+* `New`: Open in a new window or tab.
+* `Top`: Open in the current window or tab.
+* `Content`: Open within the current MI application (for example, in a frame or dialog).
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+#### *property* is_empty *: [bool](https://docs.python.org/3/library/functions.html#bool)*
+
+Whether the tabular cell is populated or not.
+
+* **Return type:**
+ [bool](https://docs.python.org/3/library/functions.html#bool)
+
+
+
+#### *property* value *: [str](https://docs.python.org/3/library/stdtypes.html#str) | [None](https://docs.python.org/3/library/constants.html#None)*
+
+URL of the hyperlink.
+
+* **Return type:**
+ [str](https://docs.python.org/3/library/stdtypes.html#str) or None
+
+
+
+## Miscellaneous tabular cells
+
+
+
+### *class* IgnoredLocalTabularCell
+
+Represents a tabular cell that has been marked as ignored.
+
+### Notes
+
+Do not create instances of this class; it represents a pre-existing database structure. Instances of this class
+are returned by [`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) for ignored local columns.
+
+#### SEE ALSO
+[`AttributeDefinitionTabular.columns_to_process`](attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionTabular.columns_to_process)
+: Specify ignored columns before data export.
+
+
+
+### *class* UnavailableTabularCell
+
+Represents a cell that was not available for export.
+
+### Notes
+
+This cell type is used when the presence of data could not be determined definitively,
+for example due to a missing target database.
+
+Do not create instances of this class; it represents a pre-existing database structure. Instances of this class
+are returned by [`TabularRow.cells`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) or [`TabularRow.cells_by_column`](#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) for unavailable columns.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/toc.yml b/2026R1/scripting-toolkit-dev-portal-26-r1/toc.yml
index 1b25fe7b9f..87a14a3af4 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/toc.yml
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/toc.yml
@@ -10,14 +10,20 @@
- name: User guide
href: user_guide/index.md
items:
- - name: Streamlined API structure
- href: user_guide/streamlined_api.md
+ - name: Package overview
+ href: user_guide/package_overview.md
- name: Versioning
href: user_guide/versioning.md
- - name: Performance optimization
- href: user_guide/performance_optimization.md
+ - name: Streamlined API structure
+ href: user_guide/streamlined_api_structure.md
- name: Authentication
href: user_guide/authentication.md
+ - name: Performance optimization
+ href: user_guide/performance_optimization.md
+ - name: Logging
+ href: user_guide/logging.md
+ - name: Exceptions
+ href: user_guide/exceptions.md
- name: MI Scripting Toolkit and PyAnsys
href: user_guide/pyansys.md
- name: Example notebooks
@@ -34,26 +40,26 @@
href: samples/streamlined/03_Search_MI.md
- name: Fetch attribute data in bulk
href: samples/streamlined/04_Fetch_Attribute_Data_in_Bulk.md
- - name: Edit data
- href: samples/streamlined/05_Edit_Data.md
- name: Create and delete records in bulk
- href: samples/streamlined/06_Create_Records.md
- - name: Import functional data
- href: samples/streamlined/07_Import_Functional_Data.md
- - name: Create functional data
- href: samples/streamlined/08_Create_Functional_Data.md
- - name: Edit tabular data
- href: samples/streamlined/09_Edit_Tabular_Data.md
- - name: Edit pseudo-attributes
- href: samples/streamlined/10_Edit_Pseudo-attributes.md
- - name: Add files, pictures, and hyperlinks
- href: samples/streamlined/11_Add_Files_Pictures_and_Hyperlinks.md
- - name: Add point and range data
- href: samples/streamlined/12_Add_Point_Range_Data.md
- - name: Add date, integer and logical data
- href: samples/streamlined/13_Add_Date_Integer_and_Logical_Data.md
- - name: Create and edit tabular data
- href: samples/streamlined/14_Create_and_Edit_Tabular_Data.md
+ href: samples/streamlined/05_Create_Records.md
+ - name: Text data
+ href: samples/streamlined/06_Edit_Text_Data.md
+ - name: Point and range data
+ href: samples/streamlined/07_Edit_Point_Range_Data.md
+ - name: Date, integer and logical data
+ href: samples/streamlined/08_Edit_Data_Integer_and_Logical_Data.md
+ - name: Files, pictures, and hyperlinks
+ href: samples/streamlined/09_Edit_Files_Pictures_and_Hyperlinks.md
+ - name: Float functional data
+ href: samples/streamlined/10_Edit_Float_Functional_Data.md
+ - name: Local tabular data
+ href: samples/streamlined/11_Edit_Local_Tabular_Data.md
+ - name: Linked tabular data
+ href: samples/streamlined/12_Edit_Linked_Tabular_Data.md
+ - name: Pseudo-attributes
+ href: samples/streamlined/13_Edit_Pseudo-attributes.md
+ - name: Data with precision
+ href: samples/streamlined/14_Data_with_Precision.md
- name: Export data for FEA
href: samples/streamlined/15_Use_Exporters_for_FEA_Export.md
- name: Link records
@@ -94,7 +100,31 @@
href: samples/data-analytics/12_Preparing_data_for_Power_BI.md
- name: Data validation using Scripting Toolkit
href: samples/data-analytics/13_Data_validation.md
-- name: API reference
+ - name: Foundation API notebooks
+ items:
+ - name: Exporting data
+ href: samples/foundation/01_Exporting_data.md
+ - name: Exporting data using the Engineering Data Service
+ href: samples/foundation/02_Exporting_data_using_EngineeringDataService.md
+ - name: Text search
+ href: samples/foundation/03_Text_Search.md
+ - name: Deleting records
+ href: samples/foundation/04_Deleting_records.md
+ - name: Functional data and importing data
+ href: samples/foundation/05_Functional_data_and_importing_data.md
+ - name: Importing and exporting tabular data
+ href: samples/foundation/06_Importing_and_exporting_tabular_data.md
+ - name: Modified date
+ href: samples/foundation/07_Modified_date.md
+ - name: Inspecting record link groups
+ href: samples/foundation/08_Inspecting_Record_Link_Groups.md
+ - name: Modifying record link groups
+ href: samples/foundation/09_Modifying_Record_Link_Groups.md
+ - name: Resolve references
+ href: samples/foundation/10_Resolve_references.md
+ - name: Get unit conversions
+ href: samples/foundation/11_Get_unit_conversions.md
+- name: Streamlined API reference
href: api/index.md
items:
- name: Session
@@ -111,44 +141,28 @@
href: api/attribute-values.md
- name: Schema and supporting items
href: api/supporting.md
- - name: Bulk operators
- href: api/bulk-operators.md
- - name: Helpers
+ - name: Tabular attribute value items
+ href: api/tabular.md
+ - name: Helper functions
href: api/helpers.md
- name: Constants
href: api/constants.md
- name: Exceptions
href: api/exceptions.md
-- name: Changelog
- href: changelog.md
-- name: Foundation API
- href: foundation/index.md
+- name: Release notes
+ href: index.md
items:
- - name: Example notebooks
- items:
- - name: Exporting data
- href: samples/foundation/01_Exporting_data.md
- - name: Exporting data using the Engineering Data Service
- href: samples/foundation/02_Exporting_data_using_EngineeringDataService.md
- - name: Text search
- href: samples/foundation/03_Text_Search.md
- - name: Deleting records
- href: samples/foundation/04_Deleting_records.md
- - name: Functional data and importing data
- href: samples/foundation/05_Functional_data_and_importing_data.md
- - name: Importing and exporting tabular data
- href: samples/foundation/06_Importing_and_exporting_tabular_data.md
- - name: Modified date
- href: samples/foundation/07_Modified_date.md
- - name: Inspecting record link groups
- href: samples/foundation/08_Inspecting_Record_Link_Groups.md
- - name: Modifying record link groups
- href: samples/foundation/09_Modifying_Record_Link_Groups.md
- - name: Resolve references
- href: samples/foundation/10_Resolve_references.md
- - name: Get unit conversions
- href: samples/foundation/11_Get_unit_conversions.md
- - name: API reference
- href: foundation/api.md
+ - name: What's new in 5.0
+ href: whats_new.md
+ - name: Enhancements and bug fixes
+ href: bug_fixes_and_enhancements.md
+ - name: Upgrading from earlier versions
+ href: breaking_changes.md
+ - name: Planned changes and deprecations
+ href: deprecations.md
+ - name: Known issues
+ href: known_issues.md
+- name: Foundation API reference
+ href: foundation_api.md
- name: Copyright and Trademark Information
href: copyright.md
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/authentication.md b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/authentication.md
index 5dbf460902..bc2da4f181 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/authentication.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/authentication.md
@@ -24,11 +24,10 @@ and in batch mode.
## Autologon
-To use autologon (also known as Integrated Windows Authentication), specify `autologon=True` in the [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session)
-constructor:
+To use autologon (also known as Integrated Windows Authentication), use [`SessionBuilder.with_autologon()`](../streamlined_api/session.md#ansys.grantami.core.mi.SessionBuilder.with_autologon):
```pycon
->>> mi = mpy.Session("https://my.server.name/mi_servicelayer", autologon=True)
+>>> mi = mpy.SessionBuilder("https://my.server.name/mi_servicelayer").with_autologon()
```
Autologon uses the user’s current login session to authenticate with Granta MI, and so the user’s credentials are not
@@ -73,15 +72,16 @@ script, which in turn executes the Python script.
## Basic authentication
-To connect with basic authentication, specify the username, password, and optional domain in the [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session)
-constructor:
+To connect with basic authentication, use [`SessionBuilder.with_credentials()`](../streamlined_api/session.md#ansys.grantami.core.mi.SessionBuilder.with_credentials) to specify the username, password,
+and optional domain:
```pycon
->>> mi = mpy.Session(
-... "https://my.server.name/mi_servicelayer",
-... user_name="user",
-... password="password",
-... domain="domain",
+>>> mi = mpy.SessionBuilder(
+... service_layer_url="https://my.server.name/mi_servicelayer",
+... ).with_credentials(
+... username="user",
+... password="password",
+... domain="domain",
... )
```
@@ -109,11 +109,12 @@ below:
>>> password = getpass.getpass()
->>> mi = mpy.Session(
-... "https://my.server.name/mi_servicelayer",
-... user_name="user",
-... password=password,
-... domain="domain",
+>>> mi = mpy.SessionBuilder(
+... service_layer_url="https://my.server.name/mi_servicelayer",
+... ).with_credentials(
+... username="user",
+... password=password,
+... domain="domain",
... )
```
@@ -126,7 +127,7 @@ other options in this section should be used instead.
### Environment variables
Credentials can be injected into the script using environment variables. The [`os`](https://docs.python.org/3/library/os.html#module-os) standard library module provides
-access to environment variables, and can be used with the [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session) constructor as follows:
+access to environment variables, and can be used with [`SessionBuilder.with_credentials()`](../streamlined_api/session.md#ansys.grantami.core.mi.SessionBuilder.with_credentials) as follows:
```pycon
>>> import os
@@ -135,11 +136,12 @@ access to environment variables, and can be used with the [`Session`](./../api/s
>>> password = os.getenv("MI_PASSWORD")
>>> domain = os.getenv("MI_DOMAIN")
->>> mi = mpy.Session(
-... "https://my.server.name/mi_servicelayer",
-... user_name=user_name,
-... password=password,
-... domain=domain,
+>>> mi = mpy.SessionBuilder(
+... service_layer_url="https://my.server.name/mi_servicelayer",
+... ).with_credentials(
+... username=user_name,
+... password=password,
+... domain=domain,
... )
```
@@ -253,8 +255,9 @@ Python:
>>> keyring.set_password("my-python-script", "granta-admin-user", "my_secret_password")
```
-In general, credentials should always retrieved programmatically and provided directly to the [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session)
-constructor without them ever being visible on screen. To access a credential programmatically, use the following:
+In general, credentials should always be retrieved programmatically and provided directly to
+[`SessionBuilder.with_credentials()`](../streamlined_api/session.md#ansys.grantami.core.mi.SessionBuilder.with_credentials) without being visible on screen. To access a credential programmatically, use
+the following:
```pycon
>>> my_password = keyring.get_password("my-python-script", "granta-admin-user")
@@ -300,17 +303,27 @@ supported OIDC IdPs and for configuration and setup documentation, refer to Gran
Configuration on [Ansys help](https://ansyshelp.ansys.com/).
#### NOTE
-To use OIDC with MI Scripting Toolkit you must install the `[oidc]` extra. See [Getting started](./../getting_started/index.md) for more details.
+To use OIDC with MI Scripting Toolkit you must install the `[oidc]` extra. See [Getting started](../getting_started/index.md) for more details.
### Interactive mode
-To use OIDC authentication interactively, specify `oidc=True` in the [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session) constructor. The following
-example loads the default web browser and redirects the user to their OIDC Identity Provider (IdP) login screen:
+To use OIDC authentication interactively, use [`SessionBuilder.with_oidc()`](../streamlined_api/session.md#ansys.grantami.core.mi.SessionBuilder.with_oidc) to obtain a [`OIDCSessionBuilder`](../streamlined_api/session.md#ansys.grantami.core.mi.OIDCSessionBuilder)
+object, and then use [`OIDCSessionBuilder.with_authorization_code_flow()`](../streamlined_api/session.md#ansys.grantami.core.mi.OIDCSessionBuilder.with_authorization_code_flow).
+
+The following example loads the default web browser and redirects the user to their OIDC Identity Provider (IdP) login
+screen:
+
+```pycon
+>>> mi = mpy.SessionBuilder('https://my.server.name/mi_servicelayer').with_oidc().with_authorization_code_flow()
+```
+
+If a browser is not available, use [`OIDCSessionBuilder.with_device_code_flow()`](../streamlined_api/session.md#ansys.grantami.core.mi.OIDCSessionBuilder.with_device_code_flow) instead. The following example
+displays a URL and code which are used to authenticate instead:
```pycon
->>> mi = mpy.Session('https://my.server.name/mi_servicelayer', oidc=True)
+>>> mi = mpy.SessionBuilder('https://my.server.name/mi_servicelayer').with_oidc().with_device_code_flow()
```
@@ -320,8 +333,8 @@ example loads the default web browser and redirects the user to their OIDC Ident
In most cases, following a successful interactive authentication, the IdP returns both an access token and a refresh
token:
-* Access token: Short lifetime, not transferable, not accessible on the [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session) object.
-* Refresh token: Long lifetime, transferable between scripts, accessible via the [`Session.refresh_token`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.refresh_token)
+* Access token: Short lifetime, not transferable, not accessible on the [`Session`](../streamlined_api/session.md#ansys.grantami.core.mi.Session) object.
+* Refresh token: Long lifetime, transferable between scripts, accessible via the [`Session.refresh_token`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.refresh_token)
property.
#### WARNING
@@ -330,11 +343,11 @@ Refresh tokens are bearer tokens that grant access to the Granta MI server, and
For unattended use, the refresh token can be stored securely in the OS credential manager and used to login
automatically. This approach uses the `keyring` library, see the [Keyring](https://pypi.org/project/keyring/) section above for more details.
-Tokens can be securely persisted with the [`Session.persist_oidc_token()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.persist_oidc_token) method:
+Tokens can be securely persisted with the [`Session.persist_oidc_token()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.persist_oidc_token) method:
```pycon
# Connect to Granta MI interactively
->>> mi = mpy.Session('https://my.server.name/mi_servicelayer', oidc=True)
+>>> mi = mpy.SessionBuilder('https://my.server.name/mi_servicelayer').with_oidc().with_authorization_code_flow()
# Store the refresh token in the credential store using keyring
>>> mi.persist_oidc_token()
@@ -343,5 +356,5 @@ Tokens can be securely persisted with the [`Session.persist_oidc_token()`](./../
Tokens can then be retrieved from the store and used to create a new Session object with no user interaction:
```pycon
->>> mi = mpy.Session("https://my.server.name/mi_servicelayer", oidc=True, use_stored_token=True)
+>>> mi = mpy.SessionBuilder("https://my.server.name/mi_servicelayer").with_oidc().with_stored_token()
```
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/exceptions.md b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/exceptions.md
new file mode 100644
index 0000000000..a463643ea3
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/exceptions.md
@@ -0,0 +1,190 @@
+# Exceptions
+
+
+
+
+
+## Introduction
+
+This page describes the different types of exceptions which may be encountered when working with MI Scripting Toolkit. The sources
+of exceptions can be grouped into four categories:
+
+* Client errors: Exceptions raised as a result of an unexpected state in the script execution. These may be raised by
+ Python itself, or by the Streamlined or Foundation layers to indicate incorrect use of the library.
+* Server response errors: Exceptions raised as a result of a fault response returned by the Granta MI application
+ server.
+* Server connection errors.
+* Timeout errors.
+
+These four different sources of exceptions are described separately in this page.
+
+
+
+## Client errors
+
+Python client exceptions are generally not caused by the Granta MI application server, but instead by the inability of
+the client to correctly handle an encountered state.
+
+Client exceptions fall into the following groups:
+
+* Built-in Python exceptions: Python has a number of built-in exceptions documented
+ [here](https://docs.python.org/3/library/exceptions.html).
+* Streamlined layer exceptions: Custom exceptions related to Granta MI-specific errors, for example
+ [`UnsupportedLinkGroupError`](../streamlined_api/exceptions.md#ansys.grantami.core.mi_meta_classes.UnsupportedLinkGroupError). These are documented in the [Exceptions](../streamlined_api/exceptions.md) section of the
+ Streamlined API reference.
+* [`GRANTA_Exception`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_Exception): Raised when failing to instantiate or modify a foundation layer object. The message
+ includes details of the name and expected type of the attribute or property which caused the failure.
+
+Whenever a client error is encountered, first determine where the exception originated. To help with this, Python
+displays a traceback which shows the source of the error and the state of the stack when the error occurred.
+
+* If the exception was raised by your code, the error is likely the result of a programming error.
+* If the exception was raised by an MI Scripting Toolkit module, first check that any inputs provided to methods and functions are
+ valid according to the [Streamlined API reference](../streamlined_api/index.md). If you are unable to determine the cause of the issue, check
+ the [Ansys developer forum](https://discuss.ansys.com/categories/materials) or contact your ACE representative.
+
+#### NOTE
+Client errors may still be dependent on a certain Granta MI server state. For example, a script that divides Young’s
+modulus by density will raise a [`ZeroDivisionError`](https://docs.python.org/3/library/exceptions.html#ZeroDivisionError) if the density is 0. Whilst the Granta MI server must be
+in a specific state to cause this failure, the problem still lies with the client.
+
+
+
+## Server response errors
+
+Exceptions which originate on the Granta MI server are always raised as [`GRANTA_ServiceLayerError`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_ServiceLayerError). This
+exception class includes a message of the form:
+
+```text
+ failed with code and message:
+```
+
+* ``: The SOAP operation during which the exception occurred, for example DataImport_SetRecordAttributes
+* ``: The numeric HTTP status code returned by the Granta MI server.
+* ``: If available, a message from the server describing the fault. If not provided, then the name of the
+ numeric status code is provided instead.
+
+[`GRANTA_ServiceLayerError`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_ServiceLayerError) exceptions are raised when any Granta MI response is processed with a non-2xx status
+code.
+
+
+
+### 500 Internal Server Error
+
+Most [`GRANTA_ServiceLayerError`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_ServiceLayerError) exceptions are raised as a result of a 500 response from the Granta MI
+application server. For example, if a script attempts to create a record in a location which already contains a record
+with the same name, the following exception is raised by MI Scripting Toolkit:
+
+```text
+DataImport_SetRecordAttributes failed with code 500 and message: Commit failed: A record with this name cannot be
+added here.
+```
+
+The message and the traceback should provide enough information to determine the cause of the error, but it is the
+responsibility of the developer to define the appropriate solution. For example, in this case the developer should
+decide if:
+
+* The error results in an unhandled condition, and should either be left to halt the execution of the script or should
+ be caught in a try/except block and reporting the error via some other means.
+* The script can continue, for example by catching the exception in a try/except block and deleting the existing record.
+* The script should be extended to first check for the existence of a conflicting record before attempting the import.
+
+If an unexpected error occurs on the server, the exception is instead raised with the message:
+
+```text
+ failed with code 500 and message: Internal Server Error.
+```
+
+In this case, an unexpected condition was encountered on the server for which a more specific error message does not
+exist. Some possible steps to determine the cause of the failure are as follows:
+
+* Check the logs on the application server around the time of the failure. It may be required to temporarily set the log
+ level to DEBUG if there are no relevant entries at INFO level.
+* Check the raw request and response SOAP messages, available in the [`GRANTA_ServiceLayerError.request_xml`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_ServiceLayerError.request_xml) and
+ [`GRANTA_ServiceLayerError.response_xml`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_ServiceLayerError.response_xml) properties on the exception object.
+
+It may be necessary to contact your ACE representative for assistance in diagnosing the fault.
+
+
+
+### Other status codes
+
+3xx response codes indicate a redirection of the request. In the case of MI Scripting Toolkit, this typically results from an
+unsupported proxy configuration.
+
+4xx response codes indicate a client error. Since the foundation layer imposes very strict rules on messages that can be
+sent to the server, a [`GRANTA_Exception`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_Exception) will often be raised before an invalid request is sent to the server.
+If a [`GRANTA_ServiceLayerError`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_ServiceLayerError) is raised with a 4xx status code, check all inputs to the streamlined or
+foundation API are valid, and check that they have been translated correctly into the
+[`GRANTA_ServiceLayerError.request_xml`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_ServiceLayerError.request_xml).
+
+5xx response codes indicate a failure somewhere on one of the servers responsible for handling the request. In the use
+of MI Scripting Toolkit, a 5xx response code other than 500 generally indicates a failure with server infrastructure other than the
+Granta MI application itself.
+
+
+
+## Server connection errors
+
+If the client is unable to communicate with the Granta MI server, a [`GRANTA_Exception`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_Exception) is raised with the
+message of the form:
+
+```text
+Connection test failed:
+```
+
+The status message is either the text form of an HTTP status code, or a statement that a response was not received:
+
+* Connection test failed: Unauthorized: The server did not accept the provided authentication information. Check
+ that the credentials provided to [`SessionBuilder.with_credentials()`](../streamlined_api/session.md#ansys.grantami.core.mi.SessionBuilder.with_credentials) are valid and consistent with the Granta MI
+ server configuration.
+* Connection test failed: Unknown error (eg, no response from GRANTA MI Service Layer at all): The server did not
+ respond to the connection request. Check that the URL is correct, and that the host machine can contact the server
+ via an alternative method, for example via a web browser or `curl`.
+
+
+
+
+
+## Timeout errors
+
+If the client does not receive a response from a request within the defined receive timeout, a
+[`GRANTA_Exception`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_Exception) is raised with the message:
+
+```text
+No response from server after 1 attempt.
+```
+
+Or if [`SessionConfiguration`](../streamlined_api/session.md#ansys.grantami.core.mi.SessionConfiguration) was used to specify `max_retries` greater than 0:
+
+```text
+No response from server after attempts.
+```
+
+Where `` is the total number of failed attempts. Since no response was received within the time allowed, there is
+no response code or message.
+
+Timeout errors are often encountered when using bulk operations, because the time taken for a bulk operation to complete
+can be difficult to predict. In general, the time taken is dependent on:
+
+* The complexity of an individual element of the batch
+* The number of operations included within the batch
+* The number of parallel requests submitted to the server
+* The performance of the server
+
+The default batch size and parallelization is chosen to attempt to ensure that all bulk operations will complete within
+the default timeout, but due to the reasons described above, this cannot be guaranteed. For example, the
+[`Session.bulk_delete_or_withdraw_records()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.bulk_delete_or_withdraw_records) method is used to delete all provided records and all the data
+contained with them. If the records contain a large amount of complex data, the overall operation may take longer than
+allowed by the default timeout.
+
+To resolve a timeout failure, either reduce the complexity of the request (for example by reducing the batch size), or
+extend the timeout specified when creating the session.
+
+#### WARNING
+Even though a [`GRANTA_Exception`](../foundation_api.md#ansys.grantami.backend.soap.GRANTA_Exceptions.GRANTA_Exception) is raised, the request may still be running on the server. In general, the
+operation will continue until it has finished.
+
+Before resubmitting a request which has previously timed out, you should check that the operation has completed
+before retrying, either by checking the state of the database in a web browser, via MI Scripting Toolkit, or by consulting the
+application logs.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/index.md b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/index.md
index d994f8b2a4..3f453a2f34 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/index.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/index.md
@@ -2,55 +2,11 @@
-
-
-## Introduction
-
-MI Scripting Toolkit is a Python package that connects to your Granta MI application server (MI Server) via the Service Layer using
-the SOAP API. The package consists of the Streamlined API, the Foundation API, and C++ libraries.
-
-This user guide focuses on the Streamlined API. It provides guidance and best practice on how to develop scripts and
-applications that interact with Granta MI during their operation.
-
-
-
-### Streamlined API
-
-The Streamlined API is provided by the `granta` submodule and can be accessed as follows:
-
-```python
-from GRANTA_MIScriptingToolkit import granta as mpy
-mpy # Contains the Streamlined API
-```
-
-See the links below for more information about specific aspects of the Streamlined API.
-
-* [Streamlined API structure](streamlined_api.md): Learn more about how the Streamlined API is structured.
-* [Versioning](versioning.md): Understand the Streamlined API versioning strategy.
+* [Package overview](package_overview.md): A high-level overview of the MI Scripting Toolkit package structure.
+* [Versioning](versioning.md): Understand the MI Scripting Toolkit versioning strategy.
+* [Streamlined API structure](streamlined_api_structure.md): Learn more about the Streamlined API structure.
* [Authentication](authentication.md): Learn more about the available authentication schemes and how to connect securely in
interactive and batch operation.
* [Performance optimization](performance_optimization.md): Understand how to use bulk operations to optimize script performance.
* [Logging](logging.md): Use the Python logging library with Scripting Toolkit.
* [MI Scripting Toolkit and PyAnsys](pyansys.md): How MI Scripting Toolkit and PyAnsys can be used together.
-
-
-
-### Foundation API
-
-
-
-The Foundation API provides a low-level wrapper around the base functionality provided by the Server Layer SOAP API. As
-a result, a detailed knowledge of the Service Layer SOAP API is required, and care is needed around managing request
-size to achieve satisfactory performance and stability.
-
-#### WARNING
-The Foundation API is included for compatibility purposes only. The Streamlined API should be used for all new
-solutions.
-
-#### WARNING
-The Foundation API does not follow Semantic Versioning. Breaking changes may be introduced with any release and will
-in general not be documented.
-
-
-
-Examples and API documentation for the Foundation API are provided [here](./../foundation/index.md).
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/logging.md b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/logging.md
index 93a5cefb02..921d60a32a 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/logging.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/logging.md
@@ -30,7 +30,7 @@ logging in general, see the Python documentation:
## Creating a logger
The `GDL` logger can be accessed in two ways. The first is via the
-[`get_foundation_logger()`](./../api/helpers.md#GRANTA_MIScriptingToolkit.granta.mi_functions.get_foundation_logger) function:
+[`get_foundation_logger()`](../streamlined_api/helpers.md#ansys.grantami.core.mi_functions.get_foundation_logger) function:
```default
logger = mpy.get_foundation_logger()
@@ -118,5 +118,8 @@ used to capture information from all Scripting Toolkit loggers and loggers creat
The MI Scripting Toolkit underlying C libraries also perform their own additional logging separate to the Python
logging. These logs can be found in the following locations:
-* Windows: `%LOCALAPPDATA%\Granta Design\MIScriptingToolkit`
-* Linux: `~/.appdata/Granta Design/MIScriptingToolkit`
+* Windows: `%LOCALAPPDATA%\Granta\Granta MI\ScriptingToolkit`
+* Linux: `~/.appdata/Granta/Granta MI/ScriptingToolkit`
+
+#### Versionchanged
+Changed in version 4.2: Log location changed
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/package_overview.md b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/package_overview.md
new file mode 100644
index 0000000000..7b9c234cdf
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/package_overview.md
@@ -0,0 +1,84 @@
+# Package overview
+
+
+
+MI Scripting Toolkit is a Granta MI component that facilitates Python-based automation and integration with Granta MI servers. It
+allows access to common Granta MI functions such as searching for records, reading and writing data, and managing links
+between records.
+
+MI Scripting Toolkit provides two separate Python interfaces.
+
+* The Foundation API provides a low-level wrapper around the base functionality provided by the Service Layer SOAP API,
+ and is provided by the `ansys.grantami.backend.soap` package as a collection of Python and binary files.
+* The Streamlined API is an abstraction on top of the Foundation API, and is provided by the `ansys.grantami.core`
+ package as a set of Python modules.
+
+Both packages are required to use MI Scripting Toolkit, and both are installed automatically when following the
+[Getting started](../getting_started/index.md) guide. However, the Streamlined API should be used exclusively unless there is a
+specific need to use the Foundation API directly. This document provides an overview of both APIs, and guidance on
+when to use each.
+
+
+
+## Streamlined API
+
+The Streamlined API is provided by the `ansys.grantami.core` package, and is accessed as follows:
+
+```python
+>>> import ansys.grantami.core as mpy
+mpy # Contains the Streamlined API
+```
+
+#### Versionchanged
+Changed in version 5.0: The Streamlined API is now provided as a package called `ansys.grantami.core`.
+
+The Streamlined API provides a high-level interface to Granta MI, designed to be easy to use and to provide good
+performance out of the box. It abstracts away many of the complexities of the underlying Service Layer SOAP API by
+pre-emptively fetching information from the server and performing client-side validation to accelerate development.
+It aims to enable development to all Python users, even those without detailed experience of working with web APIs.
+
+Additional Streamlined API information:
+
+* [Streamlined API structure](streamlined_api_structure.md): Overview of the API structure.
+* [Streamlined API reference](../streamlined_api/index.md): All the classes and functions that make up the interface.
+* [Example notebooks](../examples/index.md): Examples for the Streamlined API, including both API-specific usage and examples of typical
+ use-case.
+
+
+
+
+
+## Foundation API
+
+The Foundation API is provided by the `ansys.grantami.backend.soap` package, and is accessed as follows:
+
+```python
+>>> import ansys.grantami.backend.soap as gdl
+gdl # Contains the Foundation API
+```
+
+#### Versionchanged
+Changed in version 5.0: The Foundation API is provided as a separate package called `ansys.grantami.backend.soap`. It is a dependency of
+`ansys.grantami.core` and is installed automatically during MI Scripting Toolkit installation. It may be installed separately
+if required.
+
+The Foundation API provides a low-level wrapper around the base functionality provided by the Server Layer SOAP API. As
+a result, a detailed knowledge of both the Service Layer SOAP API and working with web APIs in general is required. Care
+is needed around managing request size and sequencing to achieve satisfactory performance and stability.
+
+However, this granularity can be a benefit if it is used correctly. For example, the Foundation API may be appropriate
+in the following situations:
+
+* Making changes in bulk without consideration to the current state of the data. For example, deleting all data in a
+ certain attribute regardless if it is populated or not.
+* When full control is needed over the requests made to the server to optimize performance for a specific use case.
+* When needing to access functionality that is not yet exposed in the Streamlined API.
+
+#### WARNING
+Only use the Foundation API after consultation with your ACE representative to confirm that it is necessary for your
+use case.
+
+Additional Foundation API information:
+
+* [Foundation API reference](../foundation_api.md): All the classes and functions that make up the interface.
+* [Foundation API example notebooks](../examples/foundation_examples.md): Examples for the Foundation API.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/performance_optimization.md b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/performance_optimization.md
index a4fdc6f065..25a1b0fe21 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/performance_optimization.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/performance_optimization.md
@@ -33,11 +33,11 @@ becomes significant.
The first steps in any MI Scripting Toolkit script are to connect to Granta MI and fetch a database and table. The three objects,
and the fastest ways of acquiring them, are as follows:
-1. [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session): [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session) is the fastest way to create a session.
-2. [`Database`](./../api/database.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Database): [`Session.get_db()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.get_db) is the fastest way to fetch a database.
-3. [`Table`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table): [`Database.get_table()`](./../api/database.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Database.get_table) is the fastest way to fetch a table.
+1. [`Session`](../streamlined_api/session.md#ansys.grantami.core.mi.Session): [`SessionBuilder`](../streamlined_api/session.md#ansys.grantami.core.mi.SessionBuilder) is the fastest way to create a session.
+2. [`Database`](../streamlined_api/database.md#ansys.grantami.core.mi_tree_classes.Database): [`Session.get_db()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.get_db) is the fastest way to fetch a database.
+3. [`Table`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table): [`Database.get_table()`](../streamlined_api/database.md#ansys.grantami.core.mi_tree_classes.Database.get_table) is the fastest way to fetch a table.
-However, [`Session.get_db()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.get_db) and [`Database.get_table()`](./../api/database.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Database.get_table) fetch *all* databases and *all* tables (for the
+However, [`Session.get_db()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.get_db) and [`Database.get_table()`](../streamlined_api/database.md#ansys.grantami.core.mi_tree_classes.Database.get_table) fetch *all* databases and *all* tables (for the
selected database) loaded on the server, cache the results, and then return the requested database or table. Because the
results are cached, those calls to Granta MI are not repeated when the objects are accessed again. As a result, it
is not necessary to pass references to database and tables between functions, as long as the session itself is shared.
@@ -61,7 +61,7 @@ table = db.get_table("Design Data")
There are many search methods in the Streamlined API that return records that match a user-defined attribute-based
criterion or text-based criterion. However, there are some record properties that are not searchable, for example
-queries based on details of the tree structure of a table. In this case, use [`Table.all_records()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.all_records) to fetch all
+queries based on details of the tree structure of a table. In this case, use [`Table.all_records()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.all_records) to fetch all
records in the table with the children of each record pre-cached. Then apply your own search filters to the record list
using standard Python operations:
@@ -73,18 +73,18 @@ recs = table.all_records(include_folders=True, include_generics=True)
filtered_recs = [r for r in recs if len(r.children) > 3]
```
-This approach can be used to filter on the following [`Record`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record) properties:
+This approach can be used to filter on the following [`Record`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record) properties:
-* [`name`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.name)
-* [`short_name`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.short_name)
-* [`color`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.color)
-* [`type`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.type)
-* [`history_guid`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.history_guid)
-* [`record_guid`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.record_guid)
-* [`parent`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.parent)
-* [`children`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.children)
+* [`name`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.name)
+* [`short_name`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.short_name)
+* [`color`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.color)
+* [`type`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.type)
+* [`history_guid`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.history_guid)
+* [`record_guid`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.record_guid)
+* [`parent`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.parent)
+* [`children`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.children)
-These properties are pre-populated on all [`Record`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record) objects returned by the [`Table.all_records()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.all_records) method.
+These properties are pre-populated on all [`Record`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record) objects returned by the [`Table.all_records()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.all_records) method.
Other properties will require additional calls to Granta MI unless the appropriate ‘bulk fetch’ methods are used before
the properties are accessed. See [Table bulk operations]() and [Session bulk operations]() for more information about
these methods.
@@ -95,9 +95,9 @@ these methods.
To create records:
-1. Use [`Table.path_from()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.path_from) or [`Table.paths_from()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.paths_from) to create the required tree structure if required.
-2. Use [`Table.create_record()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.create_record) to create record objects, and optionally add attribute values and links.
-3. Import the records using [`Session.update()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.update).
+1. Use [`Table.path_from()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.path_from) or [`Table.paths_from()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.paths_from) to create the required tree structure if required.
+2. Use [`Table.create_record()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.create_record) to create record objects, and optionally add attribute values and links.
+3. Import the records using [`Session.update()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.update).
@@ -110,11 +110,11 @@ ensure:
separate requests.
* that folder names are unique before creation or the operation will fail.
-Using the dedicated method for creating a tree structure, [`Table.path_from()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.path_from), overcomes these issues. All levels
+Using the dedicated method for creating a tree structure, [`Table.path_from()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.path_from), overcomes these issues. All levels
of a hierarchy can be created in a single operation, and no exceptions or warnings are generated if a folder already
exists with the same name. The record color can also be specified, which is applied to all records or folders created by
the method. The method returns the last node specified in the path, allowing it to be provided as the `parent`
-argument to the [`Table.create_record()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.create_record) method.
+argument to the [`Table.create_record()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.create_record) method.
Firstly, an example of creating a new folder structure. Create three new folders with the names “our”, “new”, and
“path”:
@@ -167,7 +167,7 @@ Fuchsia
### Step 2: Creating and populating records
-The [`Table.create_record()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.create_record) method creates a new record object in Python only, and does not push that record to the
+The [`Table.create_record()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.create_record) method creates a new record object in Python only, and does not push that record to the
server. These records can therefore be modified, for example by adding attribute values:
```python
@@ -188,7 +188,7 @@ for material_name in material_names:
### Step 3: Importing records and data
-The [`Session.update()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.update) method is used to import changes to attribute values, and by default accepts multiple
+The [`Session.update()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.update) method is used to import changes to attribute values, and by default accepts multiple
records to update which are passed to Granta MI in an appropriately batched request:
```python
@@ -196,10 +196,10 @@ records = mi.update(records)
```
However, after importing records, the default behavior also re-exports the updated records to ensure the
-[`Record`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record) objects reflect the latest state of the Granta MI server.
+[`Record`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record) objects reflect the latest state of the Granta MI server.
-This behavior can be suppressed by calling [`Session.update()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.update) with `refresh_attributes=False`. Then either export
-only the required attributes with [`Table.bulk_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_fetch) (see [Bulk fetching attributes]() section for more
+This behavior can be suppressed by calling [`Session.update()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.update) with `refresh_attributes=False`. Then either export
+only the required attributes with [`Table.bulk_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) (see [Bulk fetching attributes]() section for more
information):
```python
@@ -207,7 +207,7 @@ records = mi.update(records, refresh_attributes=False)
table.bulk_fetch(records, attributes=["Material name"])
```
-Alternatively, omit the [`Table.bulk_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_fetch) step entirely if the [`Record`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record) objects are no longer required:
+Alternatively, omit the [`Table.bulk_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) step entirely if the [`Record`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record) objects are no longer required:
```python
mi.update(records, refresh_attributes=False)
@@ -217,13 +217,14 @@ mi.update(records, refresh_attributes=False)
## Table bulk operations
-The following bulk operations are implemented on the [`Table`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table) object and are used to group requests to to improve
+The following bulk operations are implemented on the [`Table`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table) object and are used to group requests to to improve
script performance:
-* [`Table.bulk_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_fetch)
-* [`Table.bulk_link_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_link_fetch)
-* [`Table.bulk_fetch_associated_records()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_fetch_associated_records)
-* [`Table.bulk_fetch_data_revision_history()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_fetch_data_revision_history)
+* [`Table.bulk_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch)
+* [`Table.bulk_link_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_link_fetch)
+* [`Table.bulk_fetch_associated_records()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch_associated_records)
+* [`Table.bulk_fetch_data_revision_history()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch_data_revision_history)
+* [`Table.bulk_fetch_all_record_versions()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch_all_record_versions)
The `bulk_fetch` and `bulk_link_fetch` methods are described in more detail in the following subsections.
@@ -231,15 +232,15 @@ The `bulk_fetch` and `bulk_link_fetch` methods are described in more detail in t
### Bulk fetching attributes
-Accessing [`Record.attributes`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.attributes) causes the Streamlined API to check to see if the `attributes` property has been
+Accessing [`Record.attributes`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.attributes) causes the Streamlined API to check to see if the `attributes` property has been
populated yet. If not, it automatically populates it by exporting all the attributes for that record. This is
inefficient if only specific attributes are needed.
-Instead, the [`Table.bulk_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_fetch) method should be used to ensure only the required attributes are fetched. Also,
+Instead, the [`Table.bulk_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) method should be used to ensure only the required attributes are fetched. Also,
attributes can be requested for multiple records, which fetches the data in a smaller number of batched requests.
#### NOTE
-The [`Table.bulk_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_fetch) method does not return a value. Instead, the appropriate properties in the provided
+The [`Table.bulk_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) method does not return a value. Instead, the appropriate properties in the provided
records are updated in-place.
This example shows how to fetch a single attribute value for all records in a table. In this case, the table contains
@@ -251,15 +252,15 @@ This example shows how to fetch a single attribute value for all records in a ta
1000
```
-The first code example shows accessing the [`Record.attributes`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.attributes) property directly. This example contains the
+The first code example shows accessing the [`Record.attributes`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.attributes) property directly. This example contains the
fewest lines of code, but is the least efficient approach because all attributes are fetched for each record separately.
```python
density_values = [r.attributes["Density"].value for r in records]
```
-To improve performance, use the [`Table.bulk_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_fetch) method to fetch all attributes for all records in a smaller
-number of requests before accessing the [`Record.attributes`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.attributes) dictionary. By default, [`Table.bulk_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_fetch)
+To improve performance, use the [`Table.bulk_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch) method to fetch all attributes for all records in a smaller
+number of requests before accessing the [`Record.attributes`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.attributes) dictionary. By default, [`Table.bulk_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_fetch)
groups records into batches of 100, and requests all attributes for those records. Performance is improved, but unused
attributes are still being fetched:
@@ -304,16 +305,16 @@ density_values = [r.attributes["Density"].value for r in records]
### Bulk fetching record links
-Record link groups are accessed similarly to attributes. Accessing [`Record.links`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.links) causes the Streamlined API
+Record link groups are accessed similarly to attributes. Accessing [`Record.links`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.links) causes the Streamlined API
to check if the `links` property has been populated yet. If not, it automatically exports all record link groups for
the record. This is inefficient if only specific record link groups are needed.
-Instead, the [`Table.bulk_link_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_link_fetch) method should be used to ensure only the required record link groups are
+Instead, the [`Table.bulk_link_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_link_fetch) method should be used to ensure only the required record link groups are
fetched. Also, record link groups can be requested for multiple records, which fetches the data in a smaller number of
batched requests.
#### NOTE
-The [`Table.bulk_link_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_link_fetch) method does not return a value. Instead, the appropriate properties in the
+The [`Table.bulk_link_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_link_fetch) method does not return a value. Instead, the appropriate properties in the
provided records are updated in-place.
This example shows how to fetch the links in a single record link group for all records in a table. In this case, the
@@ -325,7 +326,7 @@ table contains 1,000 records.
1000
```
-The first code example shows accessing the [`Record.links`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.links) property directly. This example contains
+The first code example shows accessing the [`Record.links`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.links) property directly. This example contains
the fewest lines of code, but is the least efficient approach because all record link groups are fetched for each record
separately:
@@ -337,9 +338,9 @@ for record in records:
linked_test_data_record_guids |= guids
```
-To improve performance, use the [`Table.bulk_link_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_link_fetch) method to fetch all record links for all records in a
-smaller number of requests before accessing the [`Record.links`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.links) dictionary. By default,
-[`Table.bulk_link_fetch()`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table.bulk_link_fetch) groups records into batches of 100, and requests all record link groups for those
+To improve performance, use the [`Table.bulk_link_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_link_fetch) method to fetch all record links for all records in a
+smaller number of requests before accessing the [`Record.links`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.links) dictionary. By default,
+[`Table.bulk_link_fetch()`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table.bulk_link_fetch) groups records into batches of 100, and requests all record link groups for those
records. Performance is improved, but unused record link groups are still being fetched:
```python
@@ -392,24 +393,24 @@ for record in records:
## Session bulk operations
-The following bulk operations are implemented on the [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session) object and are used to group requests to to
+The following bulk operations are implemented on the [`Session`](../streamlined_api/session.md#ansys.grantami.core.mi.Session) object and are used to group requests to to
improve script performance:
-* [`Session.bulk_fetch_release_states()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.bulk_fetch_release_states)
-* [`Session.bulk_delete_or_withdraw_records()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.bulk_delete_or_withdraw_records)
+* [`Session.bulk_fetch_release_states()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.bulk_fetch_release_states)
+* [`Session.bulk_delete_or_withdraw_records()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.bulk_delete_or_withdraw_records)
### Fetching release states
-Accessing [`Record.release_state`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.release_state) causes the Streamlined API to check if the `release_state` property has been
+Accessing [`Record.release_state`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.release_state) causes the Streamlined API to check if the `release_state` property has been
populated yet. If not, it automatically exports the release state and release history for the record. This is
inefficient if the property is accessed for multiple records in a short space of time, for example within a loop or
comprehension.
-Instead, the [`Session.bulk_fetch_release_states()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.bulk_fetch_release_states) method should be used to request the revision information for
+Instead, the [`Session.bulk_fetch_release_states()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.bulk_fetch_release_states) method should be used to request the revision information for
multiple records in a smaller number of batched requests. Additionally, since the `bulk_fetch_release_states` method
-is implemented on the [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session) object, release states can be fetched for records in multiple tables and
+is implemented on the [`Session`](../streamlined_api/session.md#ansys.grantami.core.mi.Session) object, release states can be fetched for records in multiple tables and
databases simultaneously.
This method can also be parallelized and batched by using the appropriate arguments, see the API guide for more details.
@@ -430,8 +431,8 @@ The first example fetches the release states for records individually, with one
release_states = {r.name: r.release_state for r in records}
```
-To improve performance, fetch the release states in bulk first before accessing the [`Record.release_state`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.release_state)
-property. By default, [`Session.bulk_fetch_release_states()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.bulk_fetch_release_states) groups records into batches of 100:
+To improve performance, fetch the release states in bulk first before accessing the [`Record.release_state`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.release_state)
+property. By default, [`Session.bulk_fetch_release_states()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.bulk_fetch_release_states) groups records into batches of 100:
```python
# 10 record version export requests, each to export record versions for 100 records, executed sequentially
@@ -459,13 +460,13 @@ release_states = {r.name: r.release_state for r in records}
### Deleting records
-Calling [`Record.delete_or_withdraw_record_on_server()`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.delete_or_withdraw_record_on_server) causes the Streamlined API to immediately delete or
+Calling [`Record.delete_or_withdraw_record_on_server()`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.delete_or_withdraw_record_on_server) causes the Streamlined API to immediately delete or
withdraw the record on the server. This is inefficient if multiple records are deleted or withdrawn in a short space of
time, for example within a loop or comprehension.
-Instead, the [`Session.bulk_delete_or_withdraw_records()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.bulk_delete_or_withdraw_records) method should be used to delete or withdraw multiple
+Instead, the [`Session.bulk_delete_or_withdraw_records()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.bulk_delete_or_withdraw_records) method should be used to delete or withdraw multiple
records in smaller number of batched requests. Additionally, since the `bulk_delete_or_withdraw_records` method
-is implemented on the [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session) object, records in multiple tables and databases can be deleted or withdrawn
+is implemented on the [`Session`](../streamlined_api/session.md#ansys.grantami.core.mi.Session) object, records in multiple tables and databases can be deleted or withdrawn
simultaneously.
This method can also be parallelized and batched by using the appropriate arguments, see the API guide for more details.
@@ -507,3 +508,33 @@ mi.bulk_delete_or_withdraw_records(
max_num_threads=3,
)
```
+
+
+
+## Batch sizes
+
+As described in the table and session bulk operations section on this page, MI Scripting Toolkit performance can be improved
+significantly through the use of bulk operations. The performance increase is dependent on the chosen batch size and
+degree of parallelism for bulk operations, captured in the `batch_size` and `max_num_threads` properties for bulk
+methods respectively. There is an optimal value for both of these settings which depends on the operation type, the
+schema structure [1](#id2), and the complexity of the operation.
+
+If `batch_size` is too small, then the overhead of sending and receiving requests and responses becomes significant,
+which reduces performance. However, if `batch_size` is too large, the request may time out. Equally, if
+`max_num_threads` is too small, then the server is under-utilized. However, if `max_num_threads` is too large, the
+server may become saturated, slowing down performance for all users.
+
+To cope with large `batch_size` and `max_num_threads` values, the operation timeout can be increased through use of
+the [`SessionConfiguration`](../streamlined_api/session.md#ansys.grantami.core.mi.SessionConfiguration) `timeout` parameter, but this can hamper development by increasing the time taken
+to receive invalid or null responses also. Additionally, [timeout errors](exceptions.md#timeout-errors) have to be handled
+carefully to avoid interacting with the database in an inconsistent state.
+
+The default `batch_size` value for each bulk operation is chosen as a starting point, with parallelization disabled by
+default. These settings will result in improved performance when compared to making each request individually, but there
+is still often significant scope for further performance improvement. A common approach is to measure the time taken to
+complete a request as a function of `batch_size` and `max_num_threads` to find an optimal value.
+
+However, you should always leave some margin for error between the expected request duration and the allowed timeout to
+account for variable server load and changes in both the schema structure and the amount of data stored in the database.
+
+* **[1]** Certain Granta MI attribute types take longer to export than others. For example, tabular data can take longer to export than other data types due to the need to resolve associated records and linked attribute values. In general, testing should be performed to understand how your particular database schema impacts the performance of associated scripts and tools.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/pyansys.md b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/pyansys.md
index 0655eb6ae0..97909e7059 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/pyansys.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/pyansys.md
@@ -26,8 +26,8 @@ packages as required. Example notebooks will also be provided to demonstrate the
There are currently two notebooks that demonstrate this interoperability:
-* [RecordLists and MI Scripting Toolkit](./../samples/streamlined/18_Record_Lists_Interoperability.md)
-* [JobQueue and MI Scripting Toolkit](./../samples/streamlined/19_Job_Queue_Interoperability.md)
+* [RecordLists and MI Scripting Toolkit](../samples/streamlined/18_Record_Lists_Interoperability.md)
+* [JobQueue and MI Scripting Toolkit](../samples/streamlined/19_Job_Queue_Interoperability.md)
More examples will be added as additional PyAnsys packages are released.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/streamlined_api.md b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/streamlined_api.md
deleted file mode 100644
index dc1cb16823..0000000000
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/streamlined_api.md
+++ /dev/null
@@ -1,133 +0,0 @@
-# Streamlined API structure
-
-
-
-The Streamlined [Streamlined API reference](./../api/index.md) documents all the classes and functions that make up the
-interface, and is split up into sections which represent the different logical components of the Streamlined API. These
-logical components are described in the sections below:
-
-
-
-## Session object
-
-The [Session](./../api/session.md) section documents the [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session) class. The [`Session`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session) class is instantiated by
-specifying Granta MI connection information, and the returned object represents a connection to the server. It acts as
-the root object from which most other Streamlined API objects are spawned, and is typically used to:
-
-* Get [`Database`](./../api/database.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Database) objects, which can be used to access [`Table`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table) and [`Record`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record) objects.
-* Perform text searches across all records on the server with the [`Session.search_for_records_by_text()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.search_for_records_by_text) and
- [`Session.search_for_records_by_name()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.search_for_records_by_name) methods.
-* Write changes to the Granta MI server with the [`Session.update()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.update) and [`Session.update_links()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.update_links) methods.
-
-This section also documents other classes which perform bulk activities across multiple records in different databases
-and tables.
-
-
-
-## Database and table classes
-
-The [Database](./../api/database.md) section documents the [`Database`](./../api/database.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Database) class, which represents Granta MI databases.
-[`Database`](./../api/database.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Database) objects are typically obtained by using the [`Session.get_db()`](./../api/session.md#GRANTA_MIScriptingToolkit.granta.mi.Session.get_db) method.
-
-The [Table](./../api/table.md) section documents [`Table`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table) class, which represents tables on the Granta MI server.
-[`Table`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table) objects are typically obtained by using the [`Database.get_table()`](./../api/database.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Database.get_table) method.
-
-[`Database`](./../api/database.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Database) and [`Table`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table) objects are used to:
-
-* Get [`Record`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record) objects from a [`Table`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table) object based on their location in the record tree.
-* Get [`Record`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record) objects from a [`Database`](./../api/database.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Database) or [`Table`](./../api/table.md#GRANTA_MIScriptingToolkit.granta.mi_tree_classes.Table) object by text, record name, or attribute
- value searching.
-* Access schema information, such as [`mi_meta_classes.TableLayout`](./../api/supporting.md#GRANTA_MIScriptingToolkit.granta.mi_meta_classes.TableLayout) and
- [`mi_meta_classes.LinkGroupDetails`](./../api/supporting.md#GRANTA_MIScriptingToolkit.granta.mi_meta_classes.LinkGroupDetails) objects.
-
-
-
-## Record classes
-
-The [Record](./../api/record.md) section documents the [`Record`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record) class, which represents a record on the Granta MI server.
-[`Record`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record) objects are used to:
-
-* Access and modify data stored in attributes via the [`Record.attributes`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.attributes) dictionary.
-* Access and modify properties of the record, such as [`Record.name`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.name) and [`Record.color`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.color)
-* Access links via the [`Record.links`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.links) dictionary, and modify them with the [`Record.set_links()`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.set_links) method.
-* Copy and move the record with the [`Record.copy_to()`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.copy_to) and [`Record.move_to()`](./../api/record.md#GRANTA_MIScriptingToolkit.granta.mi_record_classes.Record.move_to) methods.
-
-
-
-## Attribute definition classes
-
-The [Attribute definitions](./../api/attribute-definitions.md) section documents the [`AttributeDefinition`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinition) class and all sub-classes.
-These classes represent the *definition* of an attribute on a Granta MI server, as opposed to an instance of an
-attribute which contains data. They are not associated with a particular record, only with the table that they are
-defined in. [`AttributeDefinition`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinition) classes can be used to access the attribute name, attribute unit, and
-additional schema-level configuration based on the type of the attribute.
-
-The [`AttributeDefinition`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinition) class is subclassed according to the hierarchy described below:
-
-* [`AttributeDefinition`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinition) (no objects are direct instances of this type)
- * [`AttributeDefinitionDatetime`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionDatetime)
- * [`AttributeDefinitionDiscrete`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionDiscrete)
- * [`AttributeDefinitionFile`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionFile)
- * [`AttributeDefinitionHyperlink`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionHyperlink)
- * [`AttributeDefinitionInteger`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionInteger)
- * [`AttributeDefinitionLogical`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionLogical)
- * [`AttributeDefinitionLongText`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionLongText)
- * [`AttributeDefinitionPicture`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionPicture)
- * [`AttributeDefinitionRange`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionRange)
- * [`AttributeDefinitionShortText`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionShortText)
- * [`AttributeDefinitionTabular`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionTabular)
- * [`AttributeDefinitionMultiValue`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionMultiValue) (no objects are direct instances of this type)
- * [`AttributeDefinitionFloatFunctional`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionFloatFunctional)
- * [`AttributeDefinitionPoint`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionPoint)
- * [`AttributeDefinitionUnsupported`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionUnsupported) (no objects are direct instances of this type)
- * [`AttributeDefinitionDiscreteFunctional`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinitionDiscreteFunctional)
-
-This section also documents the [`PseudoAttributeDefinition`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.PseudoAttributeDefinition) class. Objects of this type can generally be used in
-place of [`AttributeDefinition`](./../api/attribute-definitions.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.AttributeDefinition) objects to search or export pseudo-attributes.
-
-
-
-## Attribute classes
-
-The [Attribute values](./../api/attribute-values.md) section documents the
-[`AttributeValue`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeValue) class and all sub-classes. These
-classes are analogous to the attribute definition classes, but represent attribute *values*. They are associated with
-both the table and record that they relate to. In addition to being able to access the attribute name and attribute
-unit, they can be used to access data values (if the attribute is populated for the associated record).
-
-The [`AttributeValue`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeValue) class is subclassed according to
-the hierarchy described below:
-
-* [`AttributeValue`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeValue): Base class for all attributes
- * [`AttributeBinary`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeBinary): Parent class for binary attributes (no objects are direct instances of this type)
- * [`AttributePicture`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributePicture): Picture data
- * [`AttributeFile`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeFile): File data
- * [`AttributeDate`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeDate): Datetime data
- * [`AttributeDiscrete`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeDiscrete): Discrete data
- * [`AttributeFunctional`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeFunctional): Parent class for float functional data (no objects are direct instances of this type)
- * [`FunctionalSeries`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.FunctionalSeries): Float functional series data
- * [`FunctionalGrid`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.FunctionalGrid): Float functional gridded data
- * [`AttributeHyperlink`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeHyperlink): Hyperlink data
- * [`AttributeInteger`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeInteger): Integer data
- * [`AttributeLogical`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeLogical): Logical data
- * [`AttributePoint`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributePoint): Point (optionally with parameter) data
- * [`AttributeRange`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeRange): Range data
- * [`AttributeTabular`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeTabular): Tabular data
- * [`AttributeShortText`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeShortText): Short text data
- * [`AttributeLongText`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeLongText): Long text data
- * [`AttributeUnsupported`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.AttributeUnsupported): Unsupported data
- * [`PseudoAttributeValue`](./../api/attribute-values.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.PseudoAttributeValue): Pseudo-attribute value class covering all pseudo-attribute types
-
-
-
-## Sub-attribute classes
-
-The [Schema and supporting items](./../api/supporting.md) section documents classes that are used by attribute objects but are not attributes
-themselves. This includes:
-
-* The [`ParameterDefinition`](./../api/supporting.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_classes.ParameterDefinition) section, which documents the classes used to describe parameters.
-* The [`ObjectHistory`](./../api/supporting.md#GRANTA_MIScriptingToolkit.granta.mi_meta_classes.ObjectHistory), [`RecordVersionHistory`](./../api/supporting.md#GRANTA_MIScriptingToolkit.granta.mi_meta_classes.RecordVersionHistory), and [`DataRevisionHistory`](./../api/supporting.md#GRANTA_MIScriptingToolkit.granta.mi_meta_classes.DataRevisionHistory) classes, which are used
- to describe revision information of certain items within a Granta MI database.
-* The [`Hyperlink`](./../api/supporting.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.Hyperlink) class, which describes a Granta MI hyperlink attribute’s URL, target, and description.
-* The [`BinaryType`](./../api/supporting.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.BinaryType), [`Picture`](./../api/supporting.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.Picture), and [`File`](./../api/supporting.md#GRANTA_MIScriptingToolkit.granta.mi_attribute_value_classes.File) classes, which contain binary data, and provide
- methods or saving and loading that data to/from disk.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/streamlined_api_structure.md b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/streamlined_api_structure.md
new file mode 100644
index 0000000000..fbd95bd570
--- /dev/null
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/streamlined_api_structure.md
@@ -0,0 +1,250 @@
+# Streamlined API structure
+
+
+
+
+
+## [Session](../streamlined_api/session.md)
+
+Includes [`Session`](../streamlined_api/session.md#ansys.grantami.core.mi.Session) and [`SessionBuilder`](../streamlined_api/session.md#ansys.grantami.core.mi.SessionBuilder) classes.
+
+The [`SessionBuilder`](../streamlined_api/session.md#ansys.grantami.core.mi.SessionBuilder) class is used to specify Granta MI connection information, and returns a [`Session`](../streamlined_api/session.md#ansys.grantami.core.mi.Session)
+object once the connection to the server is complete.
+
+The [`Session`](../streamlined_api/session.md#ansys.grantami.core.mi.Session) object acts as the root object from which most other Streamlined API objects are spawned, and is
+typically used to:
+
+* Get [`Database`](../streamlined_api/database.md#ansys.grantami.core.mi_tree_classes.Database) objects, which can be used to access [`Table`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table) and [`Record`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record) objects.
+* Perform text searches across all records on the server with the [`Session.search_for_records_by_text()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.search_for_records_by_text) and
+ [`Session.search_for_records_by_name()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.search_for_records_by_name) methods.
+* Write changes to the Granta MI server with the [`Session.update()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.update) and [`Session.update_links()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.update_links) methods.
+* Perform bulk activities across multiple records, optionally in different databases and tables.
+
+
+
+## [Database](../streamlined_api/database.md) and [Table](../streamlined_api/table.md)
+
+Includes the [`Database`](../streamlined_api/database.md#ansys.grantami.core.mi_tree_classes.Database) and [`Table`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table) classes.
+
+The [`Database`](../streamlined_api/database.md#ansys.grantami.core.mi_tree_classes.Database) class represents Granta MI databases. [`Database`](../streamlined_api/database.md#ansys.grantami.core.mi_tree_classes.Database) objects are typically obtained by using
+the [`Session.get_db()`](../streamlined_api/session.md#ansys.grantami.core.mi.Session.get_db) method.
+
+The [`Table`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table) class represents Granta MI tables. [`Table`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table) objects are typically obtained by using the
+[`Database.get_table()`](../streamlined_api/database.md#ansys.grantami.core.mi_tree_classes.Database.get_table) method.
+
+[`Database`](../streamlined_api/database.md#ansys.grantami.core.mi_tree_classes.Database) and [`Table`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table) objects are used to:
+
+* Get [`Record`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record) objects from a [`Table`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table) object based on their location in the record tree.
+* Get [`Record`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record) objects from a [`Database`](../streamlined_api/database.md#ansys.grantami.core.mi_tree_classes.Database) or [`Table`](../streamlined_api/table.md#ansys.grantami.core.mi_tree_classes.Table) object by text, record name, or attribute
+ value searching.
+* Access schema information, such as [`mi_meta_classes.TableLayout`](../streamlined_api/supporting.md#ansys.grantami.core.mi_meta_classes.TableLayout) and
+ [`mi_meta_classes.LinkGroupDetails`](../streamlined_api/supporting.md#ansys.grantami.core.mi_meta_classes.LinkGroupDetails) objects.
+
+
+
+## [Record](../streamlined_api/record.md)
+
+Includes the [`Record`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record) class.
+
+The [`Record`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record) class represents Granta MI records.
+
+[`Record`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record) objects are used to:
+
+* Access and modify data stored in attributes via the [`Record.attributes`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.attributes) dictionary.
+* Access and modify properties of the record, such as [`Record.name`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.name) and [`Record.color`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.color)
+* Access links via the [`Record.links`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.links) dictionary, and modify them with the [`Record.set_links()`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.set_links) method.
+* Copy and move the record with the [`Record.copy_to()`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.copy_to) and [`Record.move_to()`](../streamlined_api/record.md#ansys.grantami.core.mi_record_classes.Record.move_to) methods.
+
+
+
+## [Attribute definitions](../streamlined_api/attribute-definitions.md)
+
+Includes the [`PseudoAttributeDefinition`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.PseudoAttributeDefinition) and [`AttributeDefinition`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class, and all
+[`AttributeDefinition`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) sub-classes. The [`AttributeDefinition`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) class is subclassed according to the
+hierarchy described below:
+
+* [`AttributeDefinition`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) (no objects are direct instances of this type)
+ * [`AttributeDefinitionDate`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionDate)
+ * [`AttributeDefinitionDiscrete`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionDiscrete)
+ * [`AttributeDefinitionFile`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionFile)
+ * [`AttributeDefinitionHyperlink`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionHyperlink)
+ * [`AttributeDefinitionInteger`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionInteger)
+ * [`AttributeDefinitionLogical`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionLogical)
+ * [`AttributeDefinitionLongText`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionLongText)
+ * [`AttributeDefinitionPicture`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionPicture)
+ * [`AttributeDefinitionRange`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionRange)
+ * [`AttributeDefinitionShortText`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionShortText)
+ * [`AttributeDefinitionTabular`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionTabular)
+ * [`AttributeDefinitionMultiValue`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionMultiValue) (no objects are direct instances of this type)
+ * [`AttributeDefinitionFloatFunctional`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionFloatFunctional)
+ * [`AttributeDefinitionPoint`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionPoint)
+ * [`AttributeDefinitionUnsupported`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionUnsupported) (no objects are direct instances of this type)
+ * [`AttributeDefinitionDiscreteFunctional`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinitionDiscreteFunctional)
+
+These [`AttributeDefinition`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) classes represent the *definition* of an attribute on a Granta MI server, as opposed
+to an instance of an attribute which contains data. They are not associated with a particular record, only with the
+table that they are defined in.
+
+[`AttributeDefinition`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) objects are used to access the attribute name, attribute unit, and additional schema-level
+configuration based on the type of the attribute.
+
+[`PseudoAttributeDefinition`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.PseudoAttributeDefinition) objects can generally be used in place of [`AttributeDefinition`](../streamlined_api/attribute-definitions.md#ansys.grantami.core.mi_attribute_classes.AttributeDefinition) objects to
+search or export pseudo-attributes.
+
+
+
+## [Attribute values](../streamlined_api/attribute-values.md)
+
+Includes the [`AttributeValue`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class and all sub-classes. The
+[`AttributeValue`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) class is subclassed according to the hierarchy
+described below:
+
+* [`AttributeValue`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue): Base class for all attributes
+ * [`AttributeBinary`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeBinary): Parent class for binary attributes (no objects are direct instances of this type)
+ * [`AttributePicture`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributePicture): Picture data
+ * [`AttributeFile`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFile): File data
+ * [`AttributeDate`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeDate): Datetime data
+ * [`AttributeDiscrete`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeDiscrete): Parent class for discrete attributes (no objects are direct instances of this type)
+ * [`AttributeDiscreteSingle`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeDiscreteSingle): Single-valued discrete data
+ * [`AttributeDiscreteMulti`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeDiscreteMulti): Multi-valued discrete data
+ * [`AttributeFunctionalSeriesPoint`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesPoint): Float functional series data
+ * [`AttributeFunctionalSeriesRange`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalSeriesRange): Ranged float functional series data
+ * [`AttributeFunctionalGridPoint`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridPoint): Float functional gridded data
+ * [`AttributeFunctionalGridRange`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeFunctionalGridRange): Ranged float functional gridded data
+ * [`AttributeHyperlink`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeHyperlink): Hyperlink data
+ * [`AttributeInteger`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeInteger): Integer data
+ * [`AttributeLogical`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeLogical): Logical data
+ * [`AttributePoint`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributePoint): Parent class for point attributes (no objects are direct instances of this type)
+ * [`AttributePointSingle`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributePointSingle): Single-valued point data
+ * [`AttributePointMulti`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributePointMulti): Multi-valued point data
+ * [`AttributeRange`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeRange): Range data
+ * [`AttributeTabular`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular): [Tabular data](#tabular-attribute-values)
+ * [`AttributeShortText`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeShortText): Short text data
+ * [`AttributeLongText`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeLongText): Long text data
+ * [`AttributeUnsupported`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeUnsupported): Unsupported data
+ * [`PseudoAttributeValue`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.PseudoAttributeValue): Pseudo-attribute value class covering all pseudo-attribute types
+
+These [`AttributeValue`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) classes are analogous to the attribute
+definition classes, but represent attribute *values*. They are associated with both the table and record that they
+relate to. In addition to being able to access the attribute name and attribute unit, they can be used to access data
+values (if the attribute is populated for the associated record).
+
+
+
+## [Schema and supporting items](../streamlined_api/supporting.md)
+
+Includes:
+
+* The [Schema](../streamlined_api/supporting.md#api-guide-misc-schema) section. Includes classes used to describe aspects of a database schema.
+* The [Parameters](../streamlined_api/supporting.md#api-guide-misc-parameters) section. Includes classes used to describe parameters at all levels of the Granta
+ MI object hierarchy.
+* The [Item history](../streamlined_api/supporting.md#api-guide-misc-object-history) section. Includes classes used to describe revision information of
+ items within a Granta MI database.
+* The [`SearchCriterion`](../streamlined_api/supporting.md#ansys.grantami.core.mi_meta_classes.SearchCriterion) class. Used to specify search criteria when searching for records by pseudo-attribute
+ value.
+
+Also includes sections describing classes used with specific types of attribute values. These contain similar
+information to the corresponding [`AttributeValue`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeValue) classes, but
+are not directly associated with a record.
+
+* [Media attribute values](../streamlined_api/supporting.md#api-guide-misc-media-attribute-values): File and picture attribute values.
+* [Numeric attribute values](../streamlined_api/supporting.md#api-guide-misc-numeric-attribute-values): Multi-valued point attributes and precision information.
+* [Functional attribute values](../streamlined_api/supporting.md#api-guide-misc-functional-attribute-values): Float functional series and float functional grid attribute values.
+
+
+
+
+
+## [Tabular attribute value items](../streamlined_api/tabular.md)
+
+
+
+### Tabular rows
+
+A tabular attribute consists of zero or more rows, each represented by a
+[`TabularRow`](../streamlined_api/tabular.md#ansys.grantami.core.mi_attribute_value_classes.TabularRow) object. This provides access to individual cells, either as a tuple via
+the [`cells`](../streamlined_api/tabular.md#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells) property, or by using the
+[`cells_by_column`](../streamlined_api/tabular.md#ansys.grantami.core.mi_attribute_value_classes.TabularRow.cells_by_column) property as a mapping from column names to cell values.
+
+
+
+### Tabular cells
+
+Cells within a tabular row are represented by specific cell value classes, depending on the type of data stored in the
+cell. These classes include:
+
+* The [`ShortTextValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.ShortTextValue) class, which describes a short text cell, and
+ includes the text value.
+* The [`LongTextValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LongTextValue) class, which describes a long text cell, and
+ includes the text value.
+* The [`LogicalValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LogicalValue) class, which describes a logical cell, and includes
+ the boolean value.
+* The [`IntegerValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.IntegerValue) class, which describes an integer cell, and includes
+ the integer value.
+* The [`DateValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.DateValue) class, which describes a date cell, and includes the
+ date value.
+* The [`PictureValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.PictureValue) class, which describes a binary data cell, and includes
+ the binary data, URL, and MIME file type. This class also enables saving the picture to a file.
+* The [`FileValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.FileValue) class, which describes a file cell, and includes
+ the binary data, URL, MIME file type, file name, and description. This class also enables saving the file.
+* The [`PointValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.PointValue) class, which describes a Point cell, and includes the
+ attribute’s value and associated unit.
+ Note that tabular cells can only contain a single point value, and are not associated with parameters.
+* The [`RangeValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.RangeValue) class, which describes a Range cell, and includes the
+ value, inclusivity, and associated unit.
+* The [`DiscreteValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.DiscreteValue) class, which describes a Discrete cell, and includes
+ the value and the order.
+* The [`HyperlinkValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.HyperlinkValue) class, which describes a Hyperlink cell, and
+ includes URL, target, and description.
+
+Each of these classes has a corresponding Local cell version which is mutable, this allows local cell data to be set.
+Some of these local versions have additional properties to simplify working with them. These are:
+
+* The [`LocalShortTextValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalShortTextValue) class is a mutable short text cell which allows local cell data to be set.
+* The [`LocalLongTextValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalLongTextValue) class is a mutable long text cell which allows local cell data to be set.
+* The [`LocalLogicalValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalLogicalValue) class is a mutable logical cell which allows local cell data to be set.
+* The [`LocalIntegerValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalIntegerValue) class is a mutable integer cell which allows local cell data to be set.
+* The [`LocalDateValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalDateValue) class is a mutable date cell which allows local cell data to be set.
+* The [`LocalPictureValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalPictureValue) class is a mutable binary data cell which allows local cell data to be set and
+ includes methods for loading binary data from files.
+* The [`LocalFileValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalFileValue) class is a mutable file cell which allows local cell data to be set and
+ includes methods for loading file data with file name and description properties.
+* The [`LocalPointValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalPointValue) class exposes the `default_unit` property, which returns the
+ default unit for the point value as defined for the column in the attribute definition.
+* The [`LocalRangeValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalRangeValue) class exposes the `default_unit` property, which returns the
+ default unit for the range value as defined for the column in the attribute definition.
+* The [`LocalDiscreteValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalDiscreteValue) class exposes the `possible_discrete_values` property,
+ which returns the possible discrete values for the column in the attribute definition.
+* The [`LocalHyperlinkValue`](../streamlined_api/tabular.md#ansys.grantami.core._mi_tabular_value_classes.LocalHyperlinkValue) exposes no additional properties.
+
+Functional cells are not supported in tabular attributes, and are represented as [`UnsupportedType`](../streamlined_api/supporting.md#ansys.grantami.core.mi_attribute_value_classes.UnsupportedType) objects.
+As an alternative, linked records for each row can be accessed [`AttributeTabular.linked_records`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.linked_records) and the
+functional data can be exported for these records.
+
+
+
+### Destructive editing
+
+Since v5.0, Scripting Toolkit will always try to update tabular attribute values via an update operation, by only
+updating the modified cells and leaving the tabular rows and unmodified cells in place. However, there are some tabular
+data modifications which cannot be performed as an update operation, and instead the tabular value must be completely
+re-created. This is referred to as ‘destructive editing’.
+
+Destructive editing should be avoided because:
+
+* This can be slow for attributes with File or Picture attributes, especially if many rows are present.
+* Users of Data Updater will face conflicts when applying subsequent updates.
+
+The following actions cause destructive editing, because they can only be accomplished by re-creating the tabular
+attribute value:
+
+* [`AttributeTabular.swap_rows()`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.swap_rows)
+* [`TabularRow.set_linking_value()`](../streamlined_api/tabular.md#ansys.grantami.core.mi_attribute_value_classes.TabularRow.set_linking_value) for an exported row
+
+By default, using one of these methods will raise a [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError) to inform the user that a destructive action
+has been performed. To allow the destructive action, first call the method
+[`enable_destructive_editing()`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.enable_destructive_editing). See the API guide for more details,
+including additional considerations when performing destructive editing with binary data.
+
+Destructive editing may also be forced for a tabular attribute by calling [`force_destructive_editing()`](../streamlined_api/attribute-values.md#ansys.grantami.core.mi_attribute_value_classes.AttributeTabular.force_destructive_editing) before
+importing the data.
diff --git a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/versioning.md b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/versioning.md
index f11614b4fc..3a9101079f 100644
--- a/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/versioning.md
+++ b/2026R1/scripting-toolkit-dev-portal-26-r1/user_guide/versioning.md
@@ -2,10 +2,31 @@
-The Streamlined API has a stable interface and changes follow [Semantic Versioning](https://semver.org/) where-ever
-possible. Outside of major releases, only backwards-compatible changes will be made. It is sometimes necessary to make
-backwards-incompatible changes without a new major release, but the old will always be deprecated for at least
-two versions before the changes are implemented. Deprecated behavior will be documented in the [API reference](./../api/index.md) and
-will raise an `APIDeprecationWarning` when the behavior is encountered.
+
-Historical changes to the Streamlined API are documented in [Planned changes and deprecations](./../changelog.md#upgrading).
+## Streamlined API
+
+The Streamlined API follows a versioning strategy similar to numpy’s [NEP 23 policy](https://numpy.org/neps/nep-0023-backwards-compatibility.html#nep23). Version numbers follow
+the same MAJOR.MINOR.PATCH structure as with [Semantic Versioning](https://semver.org/), but whereas Semantic Versioning only
+allows breaking changes with MAJOR releases, the Streamlined API may introduce breaking changes with MAJOR and MINOR
+releases.
+
+However, these changes are always deprecated for at least two MINOR releases prior to being introduced. The deprecation
+is communicated in the API documentation, the changelog, and where possible by issuing an `APIDeprecationWarning` at
+runtime when the deprecated functionality is used. This versioning strategy is intended to give a tradeoff between
+stability and being able to rapidly evolve the API to meet user needs within a rigid release schedule.
+
+[Planned changes and deprecations](../release_notes/deprecations.md#planned-changes) lists the latest planned breaking changes in upcoming releases of the Streamlined API. Historical
+changes are documented in [Upgrading from earlier versions](../release_notes/breaking_changes.md#upgrading).
+
+
+
+## Foundation API
+
+The Foundation API does not follow Semantic Versioning, and breaking changes may be introduced with any Granta MI
+release.
+
+The version number includes the interface version of the underlying Service Layer SOAP API that it targets, for example
+version `23.10.0.170` is based on the SOAP API version 23/10. The third and fourth version number elements `0.170`
+can be considered equivalent to MAJOR and MINOR elements in Semantic Versioning. Breaking changes will trigger a new
+MAJOR version, while new functionality that does not break existing functionality will trigger a new MINOR version.