albert 1.10.0__tar.gz → 1.10.0rc1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. {albert-1.10.0 → albert-1.10.0rc1}/.circleci/config.yml +29 -5
  2. {albert-1.10.0 → albert-1.10.0rc1}/PKG-INFO +1 -1
  3. {albert-1.10.0 → albert-1.10.0rc1}/docs/concepts.md +11 -11
  4. {albert-1.10.0 → albert-1.10.0rc1}/mkdocs.yml +1 -5
  5. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/__init__.py +1 -1
  6. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/custom_templates.py +0 -3
  7. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/data_templates.py +264 -118
  8. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/entity_types.py +3 -19
  9. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/inventory.py +1 -1
  10. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/parameters.py +0 -1
  11. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/property_data.py +280 -384
  12. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/reports.py +0 -4
  13. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/tasks.py +1 -2
  14. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/worksheets.py +0 -3
  15. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/shared/models/base.py +1 -3
  16. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/shared/models/patch.py +1 -1
  17. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/batch_data.py +2 -4
  18. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/cas.py +1 -3
  19. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/custom_fields.py +1 -3
  20. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/data_templates.py +12 -60
  21. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/inventory.py +4 -6
  22. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/lists.py +1 -3
  23. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/notebooks.py +2 -4
  24. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/parameter_groups.py +1 -3
  25. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/property_data.py +5 -64
  26. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/sheets.py +14 -16
  27. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/tags.py +1 -3
  28. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/tasks.py +7 -4
  29. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/workflows.py +2 -4
  30. albert-1.10.0rc1/src/albert/utils/data_template.py +436 -0
  31. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/utils/tasks.py +3 -3
  32. albert-1.10.0/docs/examples/property_data.md +0 -184
  33. albert-1.10.0/docs/examples/tasks.md +0 -46
  34. albert-1.10.0/src/albert/utils/data_template.py +0 -791
  35. albert-1.10.0/src/albert/utils/property_data.py +0 -638
  36. {albert-1.10.0 → albert-1.10.0rc1}/.gitignore +0 -0
  37. {albert-1.10.0 → albert-1.10.0rc1}/.pre-commit-config.yaml +0 -0
  38. {albert-1.10.0 → albert-1.10.0rc1}/.vscode/settings.json +0 -0
  39. {albert-1.10.0 → albert-1.10.0rc1}/CHANGELOG.md +0 -0
  40. {albert-1.10.0 → albert-1.10.0rc1}/CONTRIBUTING.md +0 -0
  41. {albert-1.10.0 → albert-1.10.0rc1}/LICENSE +0 -0
  42. {albert-1.10.0 → albert-1.10.0rc1}/README.md +0 -0
  43. {albert-1.10.0 → albert-1.10.0rc1}/docs/CONTRIBUTING.md +0 -0
  44. {albert-1.10.0 → albert-1.10.0rc1}/docs/albert.md +0 -0
  45. {albert-1.10.0 → albert-1.10.0rc1}/docs/assets/Vector_Favicon_Blue.svg +0 -0
  46. {albert-1.10.0 → albert-1.10.0rc1}/docs/assets/Wordmark_Black.png +0 -0
  47. {albert-1.10.0 → albert-1.10.0rc1}/docs/assets/Wordmark_White.png +0 -0
  48. {albert-1.10.0 → albert-1.10.0rc1}/docs/authentication.md +0 -0
  49. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/activities.md +0 -0
  50. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/attachments.md +0 -0
  51. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/base.md +0 -0
  52. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/batch_data.md +0 -0
  53. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/btdataset.md +0 -0
  54. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/btinsight.md +0 -0
  55. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/btmodel.md +0 -0
  56. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/cas.md +0 -0
  57. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/companies.md +0 -0
  58. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/custom_fields.md +0 -0
  59. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/custom_templates.md +0 -0
  60. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/data_columns.md +0 -0
  61. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/data_templates.md +0 -0
  62. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/entity_types.md +0 -0
  63. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/files.md +0 -0
  64. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/hazards.md +0 -0
  65. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/inventory.md +0 -0
  66. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/links.md +0 -0
  67. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/lists.md +0 -0
  68. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/locations.md +0 -0
  69. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/lots.md +0 -0
  70. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/notebooks.md +0 -0
  71. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/notes.md +0 -0
  72. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/parameter_groups.md +0 -0
  73. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/parameters.md +0 -0
  74. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/pricings.md +0 -0
  75. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/product_design.md +0 -0
  76. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/projects.md +0 -0
  77. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/property_data.md +0 -0
  78. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/reports.md +0 -0
  79. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/roles.md +0 -0
  80. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/storage_classes.md +0 -0
  81. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/storage_locations.md +0 -0
  82. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/substances.md +0 -0
  83. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/tags.md +0 -0
  84. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/tasks.md +0 -0
  85. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/un_numbers.md +0 -0
  86. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/units.md +0 -0
  87. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/users.md +0 -0
  88. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/workflows.md +0 -0
  89. {albert-1.10.0 → albert-1.10.0rc1}/docs/collections/worksheets.md +0 -0
  90. {albert-1.10.0 → albert-1.10.0rc1}/docs/configuration.md +0 -0
  91. {albert-1.10.0 → albert-1.10.0rc1}/docs/credentials.md +0 -0
  92. {albert-1.10.0 → albert-1.10.0rc1}/docs/index.md +0 -0
  93. {albert-1.10.0 → albert-1.10.0rc1}/docs/installation.md +0 -0
  94. {albert-1.10.0 → albert-1.10.0rc1}/docs/migration.md +0 -0
  95. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/activities.md +0 -0
  96. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/attachments.md +0 -0
  97. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/batch_data.md +0 -0
  98. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/btdataset.md +0 -0
  99. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/btinsight.md +0 -0
  100. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/btmodel.md +0 -0
  101. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/cas.md +0 -0
  102. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/companies.md +0 -0
  103. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/custom_fields.md +0 -0
  104. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/custom_templates.md +0 -0
  105. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/data_columns.md +0 -0
  106. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/data_templates.md +0 -0
  107. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/entity_types.md +0 -0
  108. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/files.md +0 -0
  109. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/hazards.md +0 -0
  110. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/identifiers.md +0 -0
  111. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/inventory.md +0 -0
  112. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/links.md +0 -0
  113. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/lists.md +0 -0
  114. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/locations.md +0 -0
  115. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/lots.md +0 -0
  116. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/notebooks.md +0 -0
  117. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/notes.md +0 -0
  118. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/parameter_groups.md +0 -0
  119. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/parameters.md +0 -0
  120. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/pricings.md +0 -0
  121. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/product_design.md +0 -0
  122. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/projects.md +0 -0
  123. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/property_data.md +0 -0
  124. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/reports.md +0 -0
  125. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/roles.md +0 -0
  126. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/sheets.md +0 -0
  127. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/storage_classes.md +0 -0
  128. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/storage_locations.md +0 -0
  129. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/substances.md +0 -0
  130. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/tags.md +0 -0
  131. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/tasks.md +0 -0
  132. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/un_numbers.md +0 -0
  133. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/units.md +0 -0
  134. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/users.md +0 -0
  135. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/workflows.md +0 -0
  136. {albert-1.10.0 → albert-1.10.0rc1}/docs/resources/worksheets.md +0 -0
  137. {albert-1.10.0 → albert-1.10.0rc1}/docs/sso.md +0 -0
  138. {albert-1.10.0 → albert-1.10.0rc1}/docs/styles/extra.css +0 -0
  139. {albert-1.10.0 → albert-1.10.0rc1}/pyproject.toml +0 -0
  140. {albert-1.10.0 → albert-1.10.0rc1}/scripts/validate_release_tag.py +0 -0
  141. {albert-1.10.0 → albert-1.10.0rc1}/scripts/validate_version_bump.py +0 -0
  142. {albert-1.10.0 → albert-1.10.0rc1}/setup.sh +0 -0
  143. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/client.py +0 -0
  144. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/__init__.py +0 -0
  145. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/activities.py +0 -0
  146. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/attachments.py +0 -0
  147. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/base.py +0 -0
  148. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/batch_data.py +0 -0
  149. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/btdataset.py +0 -0
  150. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/btinsight.py +0 -0
  151. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/btmodel.py +0 -0
  152. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/cas.py +0 -0
  153. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/companies.py +0 -0
  154. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/custom_fields.py +0 -0
  155. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/data_columns.py +0 -0
  156. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/files.py +0 -0
  157. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/hazards.py +0 -0
  158. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/links.py +0 -0
  159. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/lists.py +0 -0
  160. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/locations.py +0 -0
  161. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/lots.py +0 -0
  162. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/notebooks.py +0 -0
  163. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/notes.py +0 -0
  164. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/parameter_groups.py +0 -0
  165. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/pricings.py +0 -0
  166. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/product_design.py +0 -0
  167. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/projects.py +0 -0
  168. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/report_templates.py +0 -0
  169. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/roles.py +0 -0
  170. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/storage_classes.py +0 -0
  171. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/storage_locations.py +0 -0
  172. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/substance.py +0 -0
  173. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/tags.py +0 -0
  174. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/un_numbers.py +0 -0
  175. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/units.py +0 -0
  176. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/users.py +0 -0
  177. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/collections/workflows.py +0 -0
  178. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/__init__.py +0 -0
  179. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/auth/__init__.py +0 -0
  180. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/auth/_listener.py +0 -0
  181. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/auth/_manager.py +0 -0
  182. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/auth/credentials.py +0 -0
  183. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/auth/sso.py +0 -0
  184. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/base.py +0 -0
  185. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/logging.py +0 -0
  186. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/pagination.py +0 -0
  187. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/session.py +0 -0
  188. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/shared/__init__.py +0 -0
  189. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/shared/enums.py +0 -0
  190. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/shared/identifiers.py +0 -0
  191. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/core/shared/types.py +0 -0
  192. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/exceptions.py +0 -0
  193. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/__init__.py +0 -0
  194. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/_mixins.py +0 -0
  195. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/acls.py +0 -0
  196. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/activities.py +0 -0
  197. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/attachments.py +0 -0
  198. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/btdataset.py +0 -0
  199. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/btinsight.py +0 -0
  200. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/btmodel.py +0 -0
  201. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/companies.py +0 -0
  202. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/custom_templates.py +0 -0
  203. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/data_columns.py +0 -0
  204. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/entity_types.py +0 -0
  205. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/facet.py +0 -0
  206. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/files.py +0 -0
  207. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/hazards.py +0 -0
  208. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/links.py +0 -0
  209. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/locations.py +0 -0
  210. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/lots.py +0 -0
  211. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/notes.py +0 -0
  212. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/parameters.py +0 -0
  213. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/pricings.py +0 -0
  214. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/product_design.py +0 -0
  215. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/projects.py +0 -0
  216. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/report_templates.py +0 -0
  217. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/reports.py +0 -0
  218. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/roles.py +0 -0
  219. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/storage_classes.py +0 -0
  220. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/storage_locations.py +0 -0
  221. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/substance.py +0 -0
  222. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/tagged_base.py +0 -0
  223. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/un_numbers.py +0 -0
  224. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/units.py +0 -0
  225. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/users.py +0 -0
  226. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/worker_jobs.py +0 -0
  227. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/resources/worksheets.py +0 -0
  228. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/utils/__init__.py +0 -0
  229. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/utils/_auth.py +0 -0
  230. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/utils/_patch.py +0 -0
  231. {albert-1.10.0 → albert-1.10.0rc1}/src/albert/utils/inventory.py +0 -0
  232. {albert-1.10.0 → albert-1.10.0rc1}/tests/__init__.py +0 -0
  233. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/__init__.py +0 -0
  234. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_activities.py +0 -0
  235. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_attachments.py +0 -0
  236. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_batch_data.py +0 -0
  237. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_btdataset.py +0 -0
  238. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_btinsight.py +0 -0
  239. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_btmodel.py +0 -0
  240. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_cas.py +0 -0
  241. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_company.py +0 -0
  242. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_custom_fields.py +0 -0
  243. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_custom_templates.py +0 -0
  244. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_data_columns.py +0 -0
  245. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_data_templates.py +0 -0
  246. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_entity_types.py +0 -0
  247. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_files.py +0 -0
  248. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_hazards.py +0 -0
  249. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_inventory.py +0 -0
  250. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_links.py +0 -0
  251. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_lists.py +0 -0
  252. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_locations.py +0 -0
  253. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_lots.py +0 -0
  254. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_notebooks.py +0 -0
  255. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_notes.py +0 -0
  256. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_parameter_groups.py +0 -0
  257. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_parameters.py +0 -0
  258. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_pricings.py +0 -0
  259. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_product_design.py +0 -0
  260. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_projects.py +0 -0
  261. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_property_data.py +0 -0
  262. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_report_templates.py +0 -0
  263. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_reports.py +0 -0
  264. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_roles.py +0 -0
  265. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_storage_classes.py +0 -0
  266. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_storage_locations.py +0 -0
  267. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_substance.py +0 -0
  268. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_tags.py +0 -0
  269. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_tasks.py +0 -0
  270. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_un_number.py +0 -0
  271. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_units.py +0 -0
  272. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_users.py +0 -0
  273. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_workflows.py +0 -0
  274. {albert-1.10.0 → albert-1.10.0rc1}/tests/collections/test_worksheet.py +0 -0
  275. {albert-1.10.0 → albert-1.10.0rc1}/tests/conftest.py +0 -0
  276. {albert-1.10.0 → albert-1.10.0rc1}/tests/core/shared/__init__.py +0 -0
  277. {albert-1.10.0 → albert-1.10.0rc1}/tests/core/shared/test_identifiers.py +0 -0
  278. {albert-1.10.0 → albert-1.10.0rc1}/tests/core/shared/test_types.py +0 -0
  279. {albert-1.10.0 → albert-1.10.0rc1}/tests/core/test_auth.py +0 -0
  280. {albert-1.10.0 → albert-1.10.0rc1}/tests/data/SDS_HCL.pdf +0 -0
  281. {albert-1.10.0 → albert-1.10.0rc1}/tests/data/dontpanic.jpg +0 -0
  282. {albert-1.10.0 → albert-1.10.0rc1}/tests/resources/test_inventory.py +0 -0
  283. {albert-1.10.0 → albert-1.10.0rc1}/tests/resources/test_lots.py +0 -0
  284. {albert-1.10.0 → albert-1.10.0rc1}/tests/resources/test_notebooks.py +0 -0
  285. {albert-1.10.0 → albert-1.10.0rc1}/tests/resources/test_sheets.py +0 -0
  286. {albert-1.10.0 → albert-1.10.0rc1}/tests/seeding.py +0 -0
  287. {albert-1.10.0 → albert-1.10.0rc1}/tests/utils/fake_session.py +0 -0
  288. {albert-1.10.0 → albert-1.10.0rc1}/tests/utils/test_patches.py +0 -0
@@ -12,6 +12,29 @@ commands:
12
12
  command: curl -LsSf https://astral.sh/uv/install.sh | sh
13
13
 
14
14
  jobs:
15
+ snyk_app_scan:
16
+ executor:
17
+ name: python/default
18
+ tag: "3.10.15"
19
+ steps:
20
+ - checkout
21
+ - add_ssh_keys:
22
+ fingerprints:
23
+ - "SHA256:8xP/cfKKsXJOx9XDojfxU3nx9NRtDCEVSVm0uL6qL5I"
24
+ - install_uv
25
+ - run:
26
+ name: Export dependencies
27
+ command: |
28
+ uv sync
29
+ uv export > requirements_lock.txt
30
+ uv pip compile requirements_lock.txt > requirements.txt
31
+ uv pip install --system -r requirements.txt
32
+ - snyk/scan:
33
+ fail-on-issues: true
34
+ monitor-on-build: true
35
+ severity-threshold: high
36
+ token-variable: SNYK_TOKEN
37
+
15
38
  test:
16
39
  executor:
17
40
  name: python/default
@@ -123,11 +146,9 @@ jobs:
123
146
  exit 0
124
147
  fi
125
148
 
126
- SEMVER_REGEX='^v[0-9]+\.[0-9]+\.[0-9]+(?:(?:a|b|rc|dev)[0-9]+|-[0-9A-Za-z]+(?:\.[0-9A-Za-z]+)*)?$'
127
-
128
- if [[ "$CIRCLE_TAG" =~ $SEMVER_REGEX ]]; then
149
+ if [[ "$CIRCLE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
129
150
  VERSION="${CIRCLE_TAG#v}"
130
- echo "Semver tag detected. Deploying $VERSION with alias: latest"
151
+ echo "Stable semver tag detected. Deploying $VERSION with alias: latest"
131
152
  uv run mike deploy --push --update-aliases "$VERSION" latest
132
153
  else
133
154
  echo "Non-semver release tag. Skipping docs deployment."
@@ -138,6 +159,9 @@ jobs:
138
159
  workflows:
139
160
  main:
140
161
  jobs:
162
+ - snyk_app_scan:
163
+ name: Snyk App Scan
164
+ context: dev
141
165
  - test:
142
166
  name: Test
143
167
  context: dev
@@ -181,6 +205,6 @@ workflows:
181
205
  - Validate Release Tag
182
206
  filters:
183
207
  tags:
184
- only: /^v[0-9]+\.[0-9]+\.[0-9]+(?:(?:a|b|rc|dev)[0-9]+|-[0-9A-Za-z]+(?:\.[0-9A-Za-z]+)*)?$/
208
+ only: /^v[0-9]+\.[0-9]+\.[0-9]+$/
185
209
  branches:
186
210
  ignore: /.*/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: albert
3
- Version: 1.10.0
3
+ Version: 1.10.0rc1
4
4
  Summary: The official Python SDK for the Albert Invent platform.
5
5
  Project-URL: Homepage, https://www.albertinvent.com/
6
6
  Project-URL: Documentation, https://docs.developer.albertinvent.com/albert-python
@@ -67,7 +67,7 @@ project = Project(
67
67
  )
68
68
 
69
69
  # Or pass full object and let SDK convert
70
- location = client.locations.get_by_id(id="loc123")
70
+ location = client.locations.get_by_id("loc123")
71
71
  project = Project(
72
72
  description="Example",
73
73
  locations=[location] # Automatically converted
@@ -198,15 +198,15 @@ Tags are searchable and help categorize content.
198
198
 
199
199
  Concepts you should know:
200
200
 
201
- | Concept | Purpose |
202
- | --------------------- | -------------------------------------- |
203
- | Resource Models | Define the structure of data entities |
204
- | Resource Collections | Manage CRUD operations for each model |
205
- | EntityLink | Represents foreign key references |
206
- | Custom Fields & Lists | Add structured metadata to resources |
207
- | SerializeAsEntityLink | Allows transparent references or links |
208
- | Authentication | Supports static token, OAuth2, and SSO |
209
- | Partial Records | Lightweight search results |
210
- | Tags and Metadata | Categorize and extend data |
201
+ | Concept | Purpose |
202
+ |-------------------------|----------------------------------------------|
203
+ | Resource Models | Define the structure of data entities |
204
+ | Resource Collections | Manage CRUD operations for each model |
205
+ | EntityLink | Represents foreign key references |
206
+ | Custom Fields & Lists | Add structured metadata to resources |
207
+ | SerializeAsEntityLink | Allows transparent references or links |
208
+ | Authentication | Supports static token, OAuth2, and SSO |
209
+ | Partial Records | Lightweight search results |
210
+ | Tags and Metadata | Categorize and extend data |
211
211
 
212
212
  These concepts form the foundation of working effectively with the Albert SDK.
@@ -40,7 +40,6 @@ theme:
40
40
  - navigation.sections # Sidebar sections
41
41
  - navigation.top # Scroll-to-top button
42
42
  - navigation.tracking # Highlight section in sidebar
43
- - navigation.collapse
44
43
  - search.suggest # Smart search suggestions
45
44
  - toc.follow # Highlight TOC entry while scrolling
46
45
 
@@ -127,7 +126,7 @@ nav:
127
126
  - SDK Reference:
128
127
  - Clients:
129
128
  - Albert Client: albert.md
130
- - Authentication:
129
+ - Authenticaton:
131
130
  - Albert Client Credentials: credentials.md
132
131
  - Albert SSO Client: sso.md
133
132
  - Collections:
@@ -218,9 +217,6 @@ nav:
218
217
  - Worksheets:
219
218
  - Worksheets: resources/worksheets.md
220
219
  - Sheets: resources/sheets.md
221
- - Examples:
222
- - Property Data: examples/property_data.md
223
- - Tasks: examples/tasks.md
224
220
 
225
221
  validation:
226
222
  omitted_files: warn
@@ -4,4 +4,4 @@ from albert.core.auth.sso import AlbertSSOClient
4
4
 
5
5
  __all__ = ["Albert", "AlbertClientCredentials", "AlbertSSOClient"]
6
6
 
7
- __version__ = "1.10.0"
7
+ __version__ = "1.10.0rc1"
@@ -1,7 +1,5 @@
1
1
  from collections.abc import Iterator
2
2
 
3
- from pydantic import validate_call
4
-
5
3
  from albert.collections.base import BaseCollection
6
4
  from albert.core.logging import logger
7
5
  from albert.core.pagination import AlbertPaginator
@@ -30,7 +28,6 @@ class CustomTemplatesCollection(BaseCollection):
30
28
  super().__init__(session=session)
31
29
  self.base_path = f"/api/{CustomTemplatesCollection._api_version}/customtemplates"
32
30
 
33
- @validate_call
34
31
  def get_by_id(self, *, id: CustomTemplateId) -> CustomTemplate:
35
32
  """Get a Custom Template by ID
36
33
 
@@ -1,14 +1,17 @@
1
1
  from collections.abc import Iterator
2
2
  from itertools import islice
3
+ from pathlib import Path
3
4
 
4
5
  from pydantic import Field, validate_call
5
6
 
7
+ from albert.collections.attachments import AttachmentCollection
6
8
  from albert.collections.base import BaseCollection
9
+ from albert.collections.files import FileCollection
7
10
  from albert.core.logging import logger
8
11
  from albert.core.pagination import AlbertPaginator
9
12
  from albert.core.session import AlbertSession
10
13
  from albert.core.shared.enums import OrderBy, PaginationMode
11
- from albert.core.shared.identifiers import DataColumnId, DataTemplateId, UserId
14
+ from albert.core.shared.identifiers import AttachmentId, DataColumnId, DataTemplateId, UserId
12
15
  from albert.core.shared.models.patch import (
13
16
  GeneralPatchDatum,
14
17
  GeneralPatchPayload,
@@ -17,21 +20,25 @@ from albert.core.shared.models.patch import (
17
20
  )
18
21
  from albert.exceptions import AlbertHTTPError
19
22
  from albert.resources.data_templates import (
20
- CurveExample,
21
23
  DataColumnValue,
22
24
  DataTemplate,
23
25
  DataTemplateSearchItem,
24
- ImageExample,
25
26
  ParameterValue,
26
27
  )
27
28
  from albert.resources.parameter_groups import DataType, EnumValidationValue, ValueValidation
29
+ from albert.resources.tasks import ImportMode
28
30
  from albert.utils._patch import generate_data_template_patches
29
31
  from albert.utils.data_template import (
30
- add_parameter_enums,
31
- build_curve_example,
32
- build_image_example,
32
+ build_curve_import_patch_payload,
33
+ create_curve_import_job,
34
+ derive_curve_csv_mapping,
35
+ exec_curve_script,
36
+ get_script_attachment,
33
37
  get_target_data_column,
38
+ prepare_curve_input_attachment,
39
+ validate_data_column_type,
34
40
  )
41
+ from albert.utils.tasks import CSV_EXTENSIONS, fetch_csv_table_rows
35
42
 
36
43
 
37
44
  class DCPatchDatum(PGPatchPayload):
@@ -90,6 +97,255 @@ class DataTemplateCollection(BaseCollection):
90
97
  else:
91
98
  return self.add_parameters(data_template_id=dt.id, parameters=parameter_values)
92
99
 
100
+ @validate_call
101
+ def import_curve_data(
102
+ self,
103
+ *,
104
+ data_template_id: DataTemplateId,
105
+ data_column_id: DataColumnId | None = None,
106
+ data_column_name: str | None = None,
107
+ mode: ImportMode = ImportMode.CSV,
108
+ field_mapping: dict[str, str] | None = None,
109
+ file_path: str | Path | None = None,
110
+ attachment_id: AttachmentId | None = None,
111
+ ) -> DataTemplate:
112
+ """Import curve data in a data template column.
113
+
114
+ Parameters
115
+ ----------
116
+ data_template_id : DataTemplateId
117
+ Target data template Id.
118
+ data_column_id : DataColumnId | None, optional
119
+ Specific data column to upload the curve data to. Provide exactly one of ``data_column_id`` or
120
+ ``data_column_name``.
121
+ data_column_name : str | None, optional
122
+ Case-insensitive data column display name. Provide exactly one of the column
123
+ identifier or name.
124
+ mode : ImportMode, optional
125
+ Import mode. ``ImportMode.SCRIPT`` runs the attached automation script and requires
126
+ a script attachment on the data template; ``ImportMode.CSV`` ingests the
127
+ uploaded CSV directly. Defaults to ``ImportMode.CSV``.
128
+ field_mapping : dict[str, str] | None, optional
129
+ Optional manual mapping from CSV headers to curve result column names on the target column. Example: ``{"visc": "Viscosity"}`` maps the
130
+ "visc" CSV header to the "Viscosity" curve result column. Mappings are matched
131
+ case-insensitively and override auto-detection. In ``ImportMode.SCRIPT`` this applies to the headers emitted by the script before ingestion.
132
+ attachment_id : AttachmentId | None, optional
133
+ Existing attachment to use. Exactly one of ``attachment_id`` or ``file_path`` must be provided.
134
+ file_path : str | Path | None, optional
135
+ Local file to upload and attach to a new note on the data template. Exactly one of
136
+ ``attachment_id`` or ``file_path`` must be provided.
137
+ Returns
138
+ -------
139
+ DataTemplate
140
+ The data template refreshed after the curve import job completes.
141
+
142
+ Examples
143
+ --------
144
+ !!! example "Import curve data from a CSV file"
145
+ ```python
146
+ dt = client.data_templates.import_curve_data(
147
+ data_template_id="DT123",
148
+ data_column_name="APHA Color",
149
+ mode=ImportMode.CSV,
150
+ file_path="path/to/curve.csv",
151
+ field_mapping={"visc": "Viscosity"},
152
+ )
153
+ ```
154
+ """
155
+ data_template = self.get_by_id(id=data_template_id)
156
+ target_column = get_target_data_column(
157
+ data_template=data_template,
158
+ data_template_id=data_template_id,
159
+ data_column_id=data_column_id,
160
+ data_column_name=data_column_name,
161
+ )
162
+ validate_data_column_type(target_column=target_column)
163
+ column_id = target_column.data_column_id
164
+ attachment_collection = AttachmentCollection(session=self.session)
165
+
166
+ script_attachment_signed_url: str | None = None
167
+
168
+ if mode is ImportMode.SCRIPT:
169
+ script_attachment, script_extensions = get_script_attachment(
170
+ attachment_collection=attachment_collection,
171
+ data_template_id=data_template_id,
172
+ column_id=column_id,
173
+ )
174
+ if not script_extensions:
175
+ raise ValueError("Script attachment must define allowed extensions.")
176
+ script_attachment_signed_url = script_attachment.signed_url
177
+ allowed_extensions = set(script_extensions)
178
+ else:
179
+ allowed_extensions = set(CSV_EXTENSIONS)
180
+ raw_attachment = prepare_curve_input_attachment(
181
+ attachment_collection=attachment_collection,
182
+ data_template_id=data_template_id,
183
+ column_id=column_id,
184
+ allowed_extensions=allowed_extensions,
185
+ file_path=file_path,
186
+ attachment_id=attachment_id,
187
+ require_signed_url=mode is ImportMode.SCRIPT,
188
+ )
189
+ raw_key = raw_attachment.key
190
+ if raw_attachment.id is None:
191
+ raise ValueError("Curve input attachment did not return an identifier.")
192
+ resolved_attachment_id = AttachmentId(raw_attachment.id)
193
+
194
+ processed_input_key: str = raw_key
195
+ column_headers: dict[str, str] = {}
196
+
197
+ if mode is ImportMode.SCRIPT:
198
+ file_collection = FileCollection(session=self.session)
199
+ processed_input_key, column_headers = exec_curve_script(
200
+ session=self.session,
201
+ api_version=self._api_version,
202
+ data_template_id=data_template_id,
203
+ column_id=column_id,
204
+ raw_attachment=raw_attachment,
205
+ file_collection=file_collection,
206
+ script_attachment_signed_url=script_attachment_signed_url,
207
+ )
208
+ else:
209
+ table_rows = fetch_csv_table_rows(
210
+ session=self.session,
211
+ attachment_id=resolved_attachment_id,
212
+ headers_only=True,
213
+ )
214
+ header_row = table_rows[0]
215
+ if not isinstance(header_row, dict):
216
+ raise ValueError("Unexpected CSV header format returned by preview endpoint.")
217
+ column_headers = {
218
+ key: value
219
+ for key, value in header_row.items()
220
+ if isinstance(key, str) and isinstance(value, str) and value
221
+ }
222
+
223
+ csv_mapping = derive_curve_csv_mapping(
224
+ target_column=target_column,
225
+ column_headers=column_headers,
226
+ field_mapping=field_mapping,
227
+ )
228
+
229
+ job_id, partition_uuid, s3_output_key = create_curve_import_job(
230
+ session=self.session,
231
+ data_template_id=data_template_id,
232
+ column_id=column_id,
233
+ csv_mapping=csv_mapping,
234
+ raw_attachment=raw_attachment,
235
+ processed_input_key=processed_input_key,
236
+ )
237
+
238
+ patch_payload = build_curve_import_patch_payload(
239
+ target_column=target_column,
240
+ job_id=job_id,
241
+ csv_mapping=csv_mapping,
242
+ raw_attachment=raw_attachment,
243
+ partition_uuid=partition_uuid,
244
+ s3_output_key=s3_output_key,
245
+ )
246
+ self.session.patch(
247
+ f"{self.base_path}/{data_template_id}",
248
+ json=patch_payload.model_dump(by_alias=True, mode="json", exclude_none=True),
249
+ )
250
+
251
+ return self.get_by_id(id=data_template_id)
252
+
253
+ def _add_param_enums(
254
+ self,
255
+ *,
256
+ data_template_id: DataTemplateId,
257
+ new_parameters: list[ParameterValue],
258
+ ) -> list[EnumValidationValue]:
259
+ """Adds enum values to a parameter."""
260
+
261
+ data_template = self.get_by_id(id=data_template_id)
262
+ existing_parameters = data_template.parameter_values
263
+ enums_by_sequence = {}
264
+ for parameter in new_parameters:
265
+ this_sequence = next(
266
+ (
267
+ p.sequence
268
+ for p in existing_parameters
269
+ if p.id == parameter.id and p.short_name == parameter.short_name
270
+ ),
271
+ None,
272
+ )
273
+ enum_patches = []
274
+ if (
275
+ parameter.validation
276
+ and len(parameter.validation) > 0
277
+ and isinstance(parameter.validation[0].value, list)
278
+ ):
279
+ existing_validation = (
280
+ [x for x in existing_parameters if x.sequence == parameter.sequence]
281
+ if existing_parameters
282
+ else []
283
+ )
284
+ existing_enums = (
285
+ [
286
+ x
287
+ for x in existing_validation[0].validation[0].value
288
+ if isinstance(x, EnumValidationValue) and x.id is not None
289
+ ]
290
+ if (
291
+ existing_validation
292
+ and len(existing_validation) > 0
293
+ and existing_validation[0].validation
294
+ and len(existing_validation[0].validation) > 0
295
+ and existing_validation[0].validation[0].value
296
+ and isinstance(existing_validation[0].validation[0].value, list)
297
+ )
298
+ else []
299
+ )
300
+ updated_enums = (
301
+ [
302
+ x
303
+ for x in parameter.validation[0].value
304
+ if isinstance(x, EnumValidationValue)
305
+ ]
306
+ if parameter.validation[0].value
307
+ else []
308
+ )
309
+
310
+ deleted_enums = [
311
+ x for x in existing_enums if x.id not in [y.id for y in updated_enums]
312
+ ]
313
+
314
+ new_enums = [
315
+ x for x in updated_enums if x.id not in [y.id for y in existing_enums]
316
+ ]
317
+
318
+ matching_enums = [
319
+ x for x in updated_enums if x.id in [y.id for y in existing_enums]
320
+ ]
321
+
322
+ for new_enum in new_enums:
323
+ enum_patches.append({"operation": "add", "text": new_enum.text})
324
+ for deleted_enum in deleted_enums:
325
+ enum_patches.append({"operation": "delete", "id": deleted_enum.id})
326
+ for matching_enum in matching_enums:
327
+ if (
328
+ matching_enum.text
329
+ != [x for x in existing_enums if x.id == matching_enum.id][0].text
330
+ ):
331
+ enum_patches.append(
332
+ {
333
+ "operation": "update",
334
+ "id": matching_enum.id,
335
+ "text": matching_enum.text,
336
+ }
337
+ )
338
+
339
+ if len(enum_patches) > 0:
340
+ enum_response = self.session.put(
341
+ f"{self.base_path}/{data_template_id}/parameters/{this_sequence}/enums",
342
+ json=enum_patches,
343
+ )
344
+ enums_by_sequence[this_sequence] = [
345
+ EnumValidationValue(**x) for x in enum_response.json()
346
+ ]
347
+ return enums_by_sequence
348
+
93
349
  @validate_call
94
350
  def get_by_id(self, *, id: DataTemplateId) -> DataTemplate:
95
351
  """Get a data template by its ID.
@@ -107,7 +363,6 @@ class DataTemplateCollection(BaseCollection):
107
363
  response = self.session.get(f"{self.base_path}/{id}")
108
364
  return DataTemplate(**response.json())
109
365
 
110
- @validate_call
111
366
  def get_by_ids(self, *, ids: list[DataTemplateId]) -> list[DataTemplate]:
112
367
  """Get a list of data templates by their IDs.
113
368
 
@@ -147,7 +402,6 @@ class DataTemplateCollection(BaseCollection):
147
402
  return t.hydrate()
148
403
  return None
149
404
 
150
- @validate_call
151
405
  def add_data_columns(
152
406
  self, *, data_template_id: DataTemplateId, data_columns: list[DataColumnValue]
153
407
  ) -> DataTemplate:
@@ -191,7 +445,6 @@ class DataTemplateCollection(BaseCollection):
191
445
  )
192
446
  return self.get_by_id(id=data_template_id)
193
447
 
194
- @validate_call
195
448
  def add_parameters(
196
449
  self, *, data_template_id: DataTemplateId, parameters: list[ParameterValue]
197
450
  ) -> DataTemplate:
@@ -240,9 +493,7 @@ class DataTemplateCollection(BaseCollection):
240
493
  if param.id in initial_enum_values:
241
494
  param.validation[0].value = initial_enum_values[param.id]
242
495
  param.validation[0].datatype = DataType.ENUM
243
- add_parameter_enums(
244
- session=self.session,
245
- base_path=self.base_path,
496
+ self._add_param_enums(
246
497
  data_template_id=data_template_id,
247
498
  new_parameters=[param],
248
499
  )
@@ -313,12 +564,6 @@ class DataTemplateCollection(BaseCollection):
313
564
  -------
314
565
  DataTemplate
315
566
  The Updated DataTemplate object.
316
-
317
- Warnings
318
- --------
319
- Only scalar data column values (text, number, dropdown) can be updated using this function. Use
320
- `set_curve_example` / `set_image_example` to set example values for other data column types.
321
-
322
567
  """
323
568
 
324
569
  existing = self.get_by_id(id=data_template.id)
@@ -394,9 +639,7 @@ class DataTemplateCollection(BaseCollection):
394
639
  param.validation[0].datatype = DataType.ENUM # Add this line
395
640
 
396
641
  # Add enum values to newly created parameters
397
- add_parameter_enums(
398
- session=self.session,
399
- base_path=self.base_path,
642
+ self._add_param_enums(
400
643
  data_template_id=existing.id,
401
644
  new_parameters=returned_parameters,
402
645
  )
@@ -480,7 +723,6 @@ class DataTemplateCollection(BaseCollection):
480
723
  )
481
724
  return self.get_by_id(id=data_template.id)
482
725
 
483
- @validate_call
484
726
  def delete(self, *, id: DataTemplateId) -> None:
485
727
  """Deletes a data template by its ID.
486
728
 
@@ -549,99 +791,3 @@ class DataTemplateCollection(BaseCollection):
549
791
  yield from hydrated_templates
550
792
  except AlbertHTTPError as e:
551
793
  logger.warning(f"Error hydrating batch {batch}: {e}")
552
-
553
- @validate_call
554
- def set_curve_example(
555
- self,
556
- *,
557
- data_template_id: DataTemplateId,
558
- data_column_id: DataColumnId | None = None,
559
- data_column_name: str | None = None,
560
- example: CurveExample,
561
- ) -> DataTemplate:
562
- """Set a curve example on a Curve data column.
563
-
564
- Parameters
565
- ----------
566
- data_template_id : DataTemplateId
567
- Target data template ID.
568
- data_column_id : DataColumnId, optional
569
- Target curve column ID (provide exactly one of id or name).
570
- data_column_name : str, optional
571
- Target curve column name (provide exactly one of id or name).
572
- example : CurveExample
573
- Curve example payload
574
-
575
- Returns
576
- -------
577
- DataTemplate
578
- The updated data template after the example is applied.
579
- """
580
- data_template = self.get_by_id(id=data_template_id)
581
- target_column = get_target_data_column(
582
- data_template=data_template,
583
- data_template_id=data_template_id,
584
- data_column_id=data_column_id,
585
- data_column_name=data_column_name,
586
- )
587
- payload = build_curve_example(
588
- session=self.session,
589
- data_template_id=data_template_id,
590
- example=example,
591
- target_column=target_column,
592
- )
593
- if not payload.data:
594
- return data_template
595
- self.session.patch(
596
- f"{self.base_path}/{data_template_id}",
597
- json=payload.model_dump(mode="json", by_alias=True, exclude_none=True),
598
- )
599
- return self.get_by_id(id=data_template_id)
600
-
601
- @validate_call
602
- def set_image_example(
603
- self,
604
- *,
605
- data_template_id: DataTemplateId,
606
- data_column_id: DataColumnId | None = None,
607
- data_column_name: str | None = None,
608
- example: ImageExample,
609
- ) -> DataTemplate:
610
- """Set an image example on a Image data column.
611
-
612
- Parameters
613
- ----------
614
- data_template_id : DataTemplateId
615
- Target data template ID.
616
- data_column_id : DataColumnId, optional
617
- Target image column ID (provide exactly one of id or name).
618
- data_column_name : str, optional
619
- Target image column name (provide exactly one of id or name).
620
- example : ImageExample
621
- Image example payload
622
-
623
- Returns
624
- -------
625
- DataTemplate
626
- The updated data template after the example is applied.
627
- """
628
- data_template = self.get_by_id(id=data_template_id)
629
- target_column = get_target_data_column(
630
- data_template=data_template,
631
- data_template_id=data_template_id,
632
- data_column_id=data_column_id,
633
- data_column_name=data_column_name,
634
- )
635
- payload = build_image_example(
636
- session=self.session,
637
- data_template_id=data_template_id,
638
- example=example,
639
- target_column=target_column,
640
- )
641
- if not payload.data:
642
- return data_template
643
- self.session.patch(
644
- f"{self.base_path}/{data_template_id}",
645
- json=payload.model_dump(mode="json", by_alias=True, exclude_none=True),
646
- )
647
- return self.get_by_id(id=data_template_id)