sagemaker-core 1.0.47__py3-none-any.whl → 2.1.1__py3-none-any.whl

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 (363) hide show
  1. sagemaker/core/__init__.py +16 -0
  2. sagemaker/core/_studio.py +116 -0
  3. sagemaker/core/_version.py +11 -0
  4. sagemaker/core/accept_types.py +131 -0
  5. sagemaker/core/analytics.py +744 -0
  6. sagemaker/core/apiutils/__init__.py +13 -0
  7. sagemaker/core/apiutils/_base_types.py +228 -0
  8. sagemaker/core/apiutils/_boto_functions.py +130 -0
  9. sagemaker/core/apiutils/_utils.py +34 -0
  10. sagemaker/core/base_deserializers.py +35 -0
  11. sagemaker/core/base_serializers.py +35 -0
  12. sagemaker/core/clarify/__init__.py +2898 -0
  13. sagemaker/core/collection.py +467 -0
  14. sagemaker/core/common_utils.py +2281 -0
  15. sagemaker/core/compute_resource_requirements/__init__.py +18 -0
  16. sagemaker/core/compute_resource_requirements/resource_requirements.py +94 -0
  17. sagemaker/core/config/__init__.py +181 -0
  18. sagemaker/core/config/config.py +238 -0
  19. sagemaker/core/config/config_manager.py +595 -0
  20. sagemaker/core/config/config_schema.py +1220 -0
  21. sagemaker/core/config/config_utils.py +297 -0
  22. {sagemaker_core/main → sagemaker/core}/config_schema.py +410 -4
  23. sagemaker/core/constants.py +73 -0
  24. sagemaker/core/content_types.py +137 -0
  25. sagemaker/core/debugger/__init__.py +39 -0
  26. sagemaker/core/debugger/debugger.py +945 -0
  27. sagemaker/core/debugger/framework_profile.py +292 -0
  28. sagemaker/core/debugger/metrics_config.py +468 -0
  29. sagemaker/core/debugger/profiler.py +42 -0
  30. sagemaker/core/debugger/profiler_config.py +190 -0
  31. sagemaker/core/debugger/profiler_constants.py +40 -0
  32. sagemaker/core/debugger/utils.py +148 -0
  33. sagemaker/core/deprecations.py +254 -0
  34. sagemaker/core/deserializers/__init__.py +10 -0
  35. sagemaker/core/deserializers/base.py +424 -0
  36. sagemaker/core/deserializers/implementations.py +157 -0
  37. sagemaker/core/drift_check_baselines.py +106 -0
  38. sagemaker/core/enums.py +51 -0
  39. sagemaker/core/environment_variables.py +101 -0
  40. sagemaker/core/exceptions.py +108 -0
  41. sagemaker/core/experiments/__init__.py +53 -0
  42. sagemaker/core/experiments/_api_types.py +251 -0
  43. sagemaker/core/experiments/_environment.py +124 -0
  44. sagemaker/core/experiments/_helper.py +294 -0
  45. sagemaker/core/experiments/_metrics.py +333 -0
  46. sagemaker/core/experiments/_run_context.py +58 -0
  47. sagemaker/core/experiments/_utils.py +216 -0
  48. sagemaker/core/experiments/experiment.py +244 -0
  49. sagemaker/core/experiments/run.py +970 -0
  50. sagemaker/core/experiments/trial.py +296 -0
  51. sagemaker/core/experiments/trial_component.py +387 -0
  52. sagemaker/core/explainer/__init__.py +24 -0
  53. sagemaker/core/explainer/clarify_explainer_config.py +298 -0
  54. sagemaker/core/explainer/explainer_config.py +44 -0
  55. sagemaker/core/fw_utils.py +1176 -0
  56. sagemaker/core/git_utils.py +349 -0
  57. sagemaker/core/helper/pipeline_variable.py +82 -0
  58. sagemaker/core/helper/session_helper.py +2965 -0
  59. sagemaker/core/huggingface/__init__.py +29 -0
  60. sagemaker/core/huggingface/llm_utils.py +150 -0
  61. sagemaker/core/huggingface/processing.py +139 -0
  62. sagemaker/core/huggingface/training_compiler/config.py +167 -0
  63. sagemaker/core/hyperparameters.py +172 -0
  64. sagemaker/core/image_retriever/__init__.py +3 -0
  65. sagemaker/core/image_retriever/image_retriever.py +640 -0
  66. sagemaker/core/image_retriever/image_retriever_utils.py +511 -0
  67. sagemaker/core/image_retriever/test.py +7 -0
  68. sagemaker/core/image_uri_config/__init__.py +13 -0
  69. sagemaker/core/image_uri_config/autogluon.json +1335 -0
  70. sagemaker/core/image_uri_config/blazingtext.json +50 -0
  71. sagemaker/core/image_uri_config/chainer.json +104 -0
  72. sagemaker/core/image_uri_config/clarify.json +39 -0
  73. sagemaker/core/image_uri_config/coach-mxnet.json +70 -0
  74. sagemaker/core/image_uri_config/coach-tensorflow.json +186 -0
  75. sagemaker/core/image_uri_config/data-wrangler.json +91 -0
  76. sagemaker/core/image_uri_config/debugger.json +34 -0
  77. sagemaker/core/image_uri_config/detailed-profiler.json +18 -0
  78. sagemaker/core/image_uri_config/djl-deepspeed.json +385 -0
  79. sagemaker/core/image_uri_config/djl-fastertransformer.json +167 -0
  80. sagemaker/core/image_uri_config/djl-lmi.json +136 -0
  81. sagemaker/core/image_uri_config/djl-neuronx.json +258 -0
  82. sagemaker/core/image_uri_config/djl-tensorrtllm.json +262 -0
  83. sagemaker/core/image_uri_config/factorization-machines.json +50 -0
  84. sagemaker/core/image_uri_config/forecasting-deepar.json +50 -0
  85. sagemaker/core/image_uri_config/huggingface-llm-neuronx.json +660 -0
  86. sagemaker/core/image_uri_config/huggingface-llm.json +1158 -0
  87. sagemaker/core/image_uri_config/huggingface-neuron.json +52 -0
  88. sagemaker/core/image_uri_config/huggingface-neuronx.json +510 -0
  89. sagemaker/core/image_uri_config/huggingface-tei-cpu.json +298 -0
  90. sagemaker/core/image_uri_config/huggingface-tei.json +298 -0
  91. sagemaker/core/image_uri_config/huggingface-training-compiler.json +195 -0
  92. sagemaker/core/image_uri_config/huggingface.json +2138 -0
  93. sagemaker/core/image_uri_config/hyperpod-recipes-neuron.json +52 -0
  94. sagemaker/core/image_uri_config/image-classification-neo.json +43 -0
  95. sagemaker/core/image_uri_config/image-classification.json +50 -0
  96. sagemaker/core/image_uri_config/inferentia-mxnet.json +88 -0
  97. sagemaker/core/image_uri_config/inferentia-pytorch.json +127 -0
  98. sagemaker/core/image_uri_config/inferentia-tensorflow.json +88 -0
  99. sagemaker/core/image_uri_config/instance_gpu_info.json +782 -0
  100. sagemaker/core/image_uri_config/ipinsights.json +50 -0
  101. sagemaker/core/image_uri_config/kmeans.json +50 -0
  102. sagemaker/core/image_uri_config/knn.json +50 -0
  103. sagemaker/core/image_uri_config/lda.json +26 -0
  104. sagemaker/core/image_uri_config/linear-learner.json +50 -0
  105. sagemaker/core/image_uri_config/model-monitor.json +42 -0
  106. sagemaker/core/image_uri_config/mxnet.json +1154 -0
  107. sagemaker/core/image_uri_config/neo-mxnet.json +64 -0
  108. sagemaker/core/image_uri_config/neo-pytorch.json +341 -0
  109. sagemaker/core/image_uri_config/neo-tensorflow.json +109 -0
  110. sagemaker/core/image_uri_config/ntm.json +50 -0
  111. sagemaker/core/image_uri_config/object-detection.json +50 -0
  112. sagemaker/core/image_uri_config/object2vec.json +50 -0
  113. sagemaker/core/image_uri_config/pca.json +50 -0
  114. sagemaker/core/image_uri_config/pytorch-neuron.json +43 -0
  115. sagemaker/core/image_uri_config/pytorch-smp.json +218 -0
  116. sagemaker/core/image_uri_config/pytorch-training-compiler.json +80 -0
  117. sagemaker/core/image_uri_config/pytorch.json +3101 -0
  118. sagemaker/core/image_uri_config/randomcutforest.json +50 -0
  119. sagemaker/core/image_uri_config/ray-pytorch.json +46 -0
  120. sagemaker/core/image_uri_config/ray-tensorflow.json +194 -0
  121. sagemaker/core/image_uri_config/sagemaker-base-python.json +46 -0
  122. sagemaker/core/image_uri_config/sagemaker-distribution.json +37 -0
  123. sagemaker/core/image_uri_config/sagemaker-geospatial.json +13 -0
  124. sagemaker/core/image_uri_config/sagemaker-tritonserver.json +212 -0
  125. sagemaker/core/image_uri_config/semantic-segmentation.json +50 -0
  126. sagemaker/core/image_uri_config/seq2seq.json +50 -0
  127. sagemaker/core/image_uri_config/sklearn.json +446 -0
  128. sagemaker/core/image_uri_config/spark.json +280 -0
  129. sagemaker/core/image_uri_config/sparkml-serving.json +97 -0
  130. sagemaker/core/image_uri_config/stabilityai.json +53 -0
  131. sagemaker/core/image_uri_config/tensorflow.json +5086 -0
  132. sagemaker/core/image_uri_config/vw.json +25 -0
  133. sagemaker/core/image_uri_config/xgboost-neo.json +43 -0
  134. sagemaker/core/image_uri_config/xgboost.json +888 -0
  135. sagemaker/core/image_uris.py +810 -0
  136. sagemaker/core/inference_config.py +144 -0
  137. sagemaker/core/inference_recommender/__init__.py +18 -0
  138. sagemaker/core/inference_recommender/inference_recommender_mixin.py +622 -0
  139. sagemaker/core/inputs.py +366 -0
  140. sagemaker/core/instance_group.py +61 -0
  141. sagemaker/core/instance_types.py +164 -0
  142. sagemaker/core/instance_types_gpu_info.py +43 -0
  143. sagemaker/core/interactive_apps/__init__.py +41 -0
  144. sagemaker/core/interactive_apps/base_interactive_app.py +204 -0
  145. sagemaker/core/interactive_apps/detail_profiler_app.py +139 -0
  146. sagemaker/core/interactive_apps/tensorboard.py +149 -0
  147. sagemaker/core/iterators.py +186 -0
  148. sagemaker/core/job.py +380 -0
  149. sagemaker/core/jumpstart/__init__.py +156 -0
  150. sagemaker/core/jumpstart/accessors.py +390 -0
  151. sagemaker/core/jumpstart/artifacts/__init__.py +69 -0
  152. sagemaker/core/jumpstart/artifacts/environment_variables.py +252 -0
  153. sagemaker/core/jumpstart/artifacts/hyperparameters.py +120 -0
  154. sagemaker/core/jumpstart/artifacts/image_uris.py +139 -0
  155. sagemaker/core/jumpstart/artifacts/incremental_training.py +87 -0
  156. sagemaker/core/jumpstart/artifacts/instance_types.py +223 -0
  157. sagemaker/core/jumpstart/artifacts/kwargs.py +289 -0
  158. sagemaker/core/jumpstart/artifacts/metric_definitions.py +117 -0
  159. sagemaker/core/jumpstart/artifacts/model_packages.py +202 -0
  160. sagemaker/core/jumpstart/artifacts/model_uris.py +252 -0
  161. sagemaker/core/jumpstart/artifacts/payloads.py +96 -0
  162. sagemaker/core/jumpstart/artifacts/predictors.py +540 -0
  163. sagemaker/core/jumpstart/artifacts/resource_names.py +86 -0
  164. sagemaker/core/jumpstart/artifacts/resource_requirements.py +162 -0
  165. sagemaker/core/jumpstart/artifacts/script_uris.py +172 -0
  166. sagemaker/core/jumpstart/cache.py +663 -0
  167. sagemaker/core/jumpstart/configs.py +50 -0
  168. sagemaker/core/jumpstart/constants.py +198 -0
  169. sagemaker/core/jumpstart/deserializers.py +81 -0
  170. sagemaker/core/jumpstart/document.py +76 -0
  171. sagemaker/core/jumpstart/enums.py +168 -0
  172. sagemaker/core/jumpstart/exceptions.py +236 -0
  173. sagemaker/core/jumpstart/factory/utils.py +833 -0
  174. sagemaker/core/jumpstart/filters.py +597 -0
  175. sagemaker/core/jumpstart/hub/__init__.py +0 -0
  176. sagemaker/core/jumpstart/hub/constants.py +16 -0
  177. sagemaker/core/jumpstart/hub/hub.py +291 -0
  178. sagemaker/core/jumpstart/hub/interfaces.py +936 -0
  179. sagemaker/core/jumpstart/hub/parser_utils.py +70 -0
  180. sagemaker/core/jumpstart/hub/parsers.py +288 -0
  181. sagemaker/core/jumpstart/hub/types.py +35 -0
  182. sagemaker/core/jumpstart/hub/utils.py +260 -0
  183. sagemaker/core/jumpstart/models.py +499 -0
  184. sagemaker/core/jumpstart/notebook_utils.py +575 -0
  185. sagemaker/core/jumpstart/parameters.py +20 -0
  186. sagemaker/core/jumpstart/payload_utils.py +239 -0
  187. sagemaker/core/jumpstart/region_config.json +163 -0
  188. sagemaker/core/jumpstart/search.py +171 -0
  189. sagemaker/core/jumpstart/serializers.py +81 -0
  190. sagemaker/core/jumpstart/session_utils.py +234 -0
  191. sagemaker/core/jumpstart/types.py +3044 -0
  192. sagemaker/core/jumpstart/utils.py +1731 -0
  193. sagemaker/core/jumpstart/validators.py +257 -0
  194. sagemaker/core/lambda_helper.py +312 -0
  195. sagemaker/core/lineage/__init__.py +42 -0
  196. sagemaker/core/lineage/_api_types.py +239 -0
  197. sagemaker/core/lineage/_utils.py +49 -0
  198. sagemaker/core/lineage/action.py +345 -0
  199. sagemaker/core/lineage/artifact.py +646 -0
  200. sagemaker/core/lineage/association.py +190 -0
  201. sagemaker/core/lineage/context.py +505 -0
  202. sagemaker/core/lineage/lineage_trial_component.py +191 -0
  203. sagemaker/core/lineage/query.py +732 -0
  204. sagemaker/core/lineage/visualizer.py +346 -0
  205. sagemaker/core/local/__init__.py +18 -0
  206. sagemaker/core/local/data.py +413 -0
  207. sagemaker/core/local/entities.py +678 -0
  208. sagemaker/core/local/exceptions.py +17 -0
  209. sagemaker/core/local/image.py +1243 -0
  210. sagemaker/core/local/local_session.py +739 -0
  211. sagemaker/core/local/utils.py +245 -0
  212. sagemaker/core/logs.py +181 -0
  213. sagemaker/core/metadata_properties.py +56 -0
  214. sagemaker/core/metric_definitions.py +91 -0
  215. sagemaker/core/mlflow/__init__.py +38 -0
  216. sagemaker/core/mlflow/forward_sagemaker_metrics.py +44 -0
  217. sagemaker/core/model_card/__init__.py +26 -0
  218. sagemaker/core/model_life_cycle.py +51 -0
  219. sagemaker/core/model_metrics.py +160 -0
  220. sagemaker/core/model_monitor/__init__.py +66 -0
  221. sagemaker/core/model_monitor/clarify_model_monitoring.py +1495 -0
  222. sagemaker/core/model_monitor/cron_expression_generator.py +82 -0
  223. sagemaker/core/model_monitor/data_capture_config.py +115 -0
  224. sagemaker/core/model_monitor/data_quality_monitoring_config.py +66 -0
  225. sagemaker/core/model_monitor/dataset_format.py +102 -0
  226. sagemaker/core/model_monitor/model_monitoring.py +4266 -0
  227. sagemaker/core/model_monitor/monitoring_alert.py +76 -0
  228. sagemaker/core/model_monitor/monitoring_files.py +506 -0
  229. sagemaker/core/model_monitor/utils.py +793 -0
  230. sagemaker/core/model_registry.py +480 -0
  231. sagemaker/core/model_uris.py +97 -0
  232. sagemaker/core/modules/__init__.py +19 -0
  233. sagemaker/core/modules/configs.py +226 -0
  234. sagemaker/core/modules/constants.py +37 -0
  235. sagemaker/core/modules/distributed.py +182 -0
  236. sagemaker/core/modules/local_core/__init__.py +0 -0
  237. sagemaker/core/modules/local_core/local_container.py +605 -0
  238. sagemaker/core/modules/templates.py +83 -0
  239. sagemaker/core/modules/train/__init__.py +14 -0
  240. sagemaker/core/modules/train/container_drivers/__init__.py +14 -0
  241. sagemaker/core/modules/train/container_drivers/common/__init__.py +14 -0
  242. sagemaker/core/modules/train/container_drivers/common/utils.py +213 -0
  243. sagemaker/core/modules/train/container_drivers/distributed_drivers/__init__.py +14 -0
  244. sagemaker/core/modules/train/container_drivers/distributed_drivers/basic_script_driver.py +81 -0
  245. sagemaker/core/modules/train/container_drivers/distributed_drivers/mpi_driver.py +123 -0
  246. sagemaker/core/modules/train/container_drivers/distributed_drivers/mpi_utils.py +302 -0
  247. sagemaker/core/modules/train/container_drivers/distributed_drivers/torchrun_driver.py +129 -0
  248. sagemaker/core/modules/train/container_drivers/scripts/__init__.py +14 -0
  249. sagemaker/core/modules/train/container_drivers/scripts/environment.py +305 -0
  250. sagemaker/core/modules/train/sm_recipes/__init__.py +0 -0
  251. sagemaker/core/modules/train/sm_recipes/utils.py +330 -0
  252. sagemaker/core/modules/types.py +19 -0
  253. sagemaker/core/modules/utils.py +194 -0
  254. sagemaker/core/network.py +185 -0
  255. sagemaker/core/parameter.py +173 -0
  256. sagemaker/core/payloads.py +185 -0
  257. sagemaker/core/processing.py +1597 -0
  258. sagemaker/core/remote_function/__init__.py +19 -0
  259. sagemaker/core/remote_function/checkpoint_location.py +47 -0
  260. sagemaker/core/remote_function/client.py +1285 -0
  261. sagemaker/core/remote_function/core/__init__.py +0 -0
  262. sagemaker/core/remote_function/core/_custom_dispatch_table.py +72 -0
  263. sagemaker/core/remote_function/core/pipeline_variables.py +353 -0
  264. sagemaker/core/remote_function/core/serialization.py +422 -0
  265. sagemaker/core/remote_function/core/stored_function.py +226 -0
  266. sagemaker/core/remote_function/custom_file_filter.py +128 -0
  267. sagemaker/core/remote_function/errors.py +104 -0
  268. sagemaker/core/remote_function/invoke_function.py +172 -0
  269. sagemaker/core/remote_function/job.py +2140 -0
  270. sagemaker/core/remote_function/logging_config.py +38 -0
  271. sagemaker/core/remote_function/runtime_environment/__init__.py +14 -0
  272. sagemaker/core/remote_function/runtime_environment/bootstrap_runtime_environment.py +605 -0
  273. sagemaker/core/remote_function/runtime_environment/mpi_utils_remote.py +252 -0
  274. sagemaker/core/remote_function/runtime_environment/runtime_environment_manager.py +554 -0
  275. sagemaker/core/remote_function/runtime_environment/spark_app.py +18 -0
  276. sagemaker/core/remote_function/spark_config.py +149 -0
  277. sagemaker/core/resource_requirements.py +168 -0
  278. {sagemaker_core/main → sagemaker/core}/resources.py +20121 -11728
  279. sagemaker/core/s3/__init__.py +41 -0
  280. sagemaker/core/s3/client.py +367 -0
  281. sagemaker/core/s3/utils.py +175 -0
  282. sagemaker/core/script_uris.py +93 -0
  283. sagemaker/core/serializers/__init__.py +11 -0
  284. sagemaker/core/serializers/base.py +510 -0
  285. sagemaker/core/serializers/implementations.py +159 -0
  286. sagemaker/core/serializers/utils.py +223 -0
  287. sagemaker/core/serverless_inference_config.py +63 -0
  288. sagemaker/core/session_settings.py +55 -0
  289. sagemaker/core/shapes/__init__.py +3 -0
  290. sagemaker/core/shapes/model_card_shapes.py +159 -0
  291. {sagemaker_core/main → sagemaker/core/shapes}/shapes.py +6384 -1865
  292. sagemaker/core/spark/__init__.py +16 -0
  293. sagemaker/core/spark/defaults.py +16 -0
  294. sagemaker/core/spark/processing.py +1380 -0
  295. sagemaker/core/telemetry/__init__.py +23 -0
  296. sagemaker/core/telemetry/constants.py +84 -0
  297. sagemaker/core/telemetry/telemetry_logging.py +284 -0
  298. sagemaker/core/tools/__init__.py +1 -0
  299. {sagemaker_core → sagemaker/core}/tools/codegen.py +4 -4
  300. {sagemaker_core → sagemaker/core}/tools/constants.py +23 -15
  301. {sagemaker_core → sagemaker/core}/tools/data_extractor.py +1 -1
  302. {sagemaker_core → sagemaker/core}/tools/method.py +1 -1
  303. sagemaker/core/tools/model_card/generate_model_card_from_schema.py +562 -0
  304. {sagemaker_core → sagemaker/core}/tools/resources_codegen.py +165 -98
  305. {sagemaker_core → sagemaker/core}/tools/resources_extractor.py +5 -13
  306. {sagemaker_core → sagemaker/core}/tools/shapes_codegen.py +16 -17
  307. {sagemaker_core → sagemaker/core}/tools/shapes_extractor.py +29 -67
  308. {sagemaker_core → sagemaker/core}/tools/templates.py +39 -17
  309. sagemaker/core/training/__init__.py +14 -0
  310. sagemaker/core/training/configs.py +333 -0
  311. sagemaker/core/training/constants.py +37 -0
  312. sagemaker/core/training/utils.py +77 -0
  313. sagemaker/core/training_compiler/__init__.py +16 -0
  314. sagemaker/core/training_compiler/config.py +197 -0
  315. sagemaker/core/training_compiler_config.py +197 -0
  316. sagemaker/core/transformer.py +793 -0
  317. sagemaker/core/user_agent.py +76 -0
  318. sagemaker/core/utilities/__init__.py +24 -0
  319. sagemaker/core/utilities/cache.py +169 -0
  320. sagemaker/core/utilities/search_expression.py +133 -0
  321. sagemaker/core/utils/__init__.py +48 -0
  322. sagemaker/core/utils/code_injection/__init__.py +0 -0
  323. {sagemaker_core/main → sagemaker/core/utils}/code_injection/codec.py +2 -2
  324. {sagemaker_core/main → sagemaker/core/utils}/code_injection/shape_dag.py +6479 -136
  325. {sagemaker_core/main → sagemaker/core/utils}/exceptions.py +8 -8
  326. sagemaker_core/main/default_configs_helper.py → sagemaker/core/utils/intelligent_defaults_helper.py +5 -6
  327. {sagemaker_core/main → sagemaker/core/utils}/logs.py +1 -2
  328. {sagemaker_core/main → sagemaker/core/utils}/utils.py +25 -20
  329. sagemaker/core/workflow/__init__.py +152 -0
  330. sagemaker/core/workflow/conditions.py +313 -0
  331. sagemaker/core/workflow/entities.py +58 -0
  332. sagemaker/core/workflow/execution_variables.py +89 -0
  333. sagemaker/core/workflow/functions.py +193 -0
  334. sagemaker/core/workflow/parameters.py +222 -0
  335. sagemaker/core/workflow/pipeline_context.py +394 -0
  336. sagemaker/core/workflow/pipeline_definition_config.py +31 -0
  337. sagemaker/core/workflow/properties.py +285 -0
  338. sagemaker/core/workflow/step_outputs.py +65 -0
  339. sagemaker/core/workflow/utilities.py +507 -0
  340. sagemaker/lineage/__init__.py +33 -0
  341. sagemaker/lineage/action.py +28 -0
  342. sagemaker/lineage/artifact.py +28 -0
  343. sagemaker/lineage/context.py +28 -0
  344. sagemaker/lineage/lineage_trial_component.py +28 -0
  345. {sagemaker_core-1.0.47.dist-info → sagemaker_core-2.1.1.dist-info}/METADATA +28 -9
  346. sagemaker_core-2.1.1.dist-info/RECORD +355 -0
  347. sagemaker_core-2.1.1.dist-info/top_level.txt +1 -0
  348. sagemaker_core/__init__.py +0 -4
  349. sagemaker_core/_version.py +0 -3
  350. sagemaker_core/helper/session_helper.py +0 -769
  351. sagemaker_core/resources/__init__.py +0 -1
  352. sagemaker_core/shapes/__init__.py +0 -1
  353. sagemaker_core/tools/__init__.py +0 -1
  354. sagemaker_core-1.0.47.dist-info/RECORD +0 -35
  355. sagemaker_core-1.0.47.dist-info/top_level.txt +0 -1
  356. {sagemaker_core → sagemaker/core}/helper/__init__.py +0 -0
  357. {sagemaker_core/main → sagemaker/core/huggingface/training_compiler}/__init__.py +0 -0
  358. {sagemaker_core/main/code_injection → sagemaker/core/jumpstart/factory}/__init__.py +0 -0
  359. {sagemaker_core/main → sagemaker/core/utils}/code_injection/base.py +0 -0
  360. {sagemaker_core/main → sagemaker/core/utils}/code_injection/constants.py +0 -0
  361. {sagemaker_core/main → sagemaker/core/utils}/user_agent.py +0 -0
  362. {sagemaker_core-1.0.47.dist-info → sagemaker_core-2.1.1.dist-info}/WHEEL +0 -0
  363. {sagemaker_core-1.0.47.dist-info → sagemaker_core-2.1.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,769 +0,0 @@
1
- # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License"). You
4
- # may not use this file except in compliance with the License. A copy of
5
- # the License is located at
6
- #
7
- # http://aws.amazon.com/apache2.0/
8
- #
9
- # or in the "license" file accompanying this file. This file is
10
- # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
- # ANY KIND, either express or implied. See the License for the specific
12
- # language governing permissions and limitations under the License.
13
- from __future__ import absolute_import, annotations, print_function
14
-
15
- import json
16
- import logging
17
- import os
18
- import re
19
- from functools import reduce
20
- from typing import Dict, Optional
21
-
22
- import boto3
23
- import botocore
24
- import botocore.config
25
- from botocore.exceptions import ClientError
26
-
27
- # Setting LOGGER for backward compatibility, in case users import it...
28
- logger = LOGGER = logging.getLogger("sagemaker")
29
-
30
- NOTEBOOK_METADATA_FILE = "/opt/ml/metadata/resource-metadata.json"
31
- MODEL_MONITOR_ONE_TIME_SCHEDULE = "NOW"
32
- _STATUS_CODE_TABLE = {
33
- "COMPLETED": "Completed",
34
- "INPROGRESS": "InProgress",
35
- "IN_PROGRESS": "InProgress",
36
- "FAILED": "Failed",
37
- "STOPPED": "Stopped",
38
- "STOPPING": "Stopping",
39
- "STARTING": "Starting",
40
- "PENDING": "Pending",
41
- }
42
- EP_LOGGER_POLL = 10
43
- DEFAULT_EP_POLL = 30
44
-
45
-
46
- class LogState(object):
47
- """Placeholder docstring"""
48
-
49
- STARTING = 1
50
- WAIT_IN_PROGRESS = 2
51
- TAILING = 3
52
- JOB_COMPLETE = 4
53
- COMPLETE = 5
54
-
55
-
56
- class Session(object): # pylint: disable=too-many-public-methods
57
- """Manage interactions with the Amazon SageMaker APIs and any other AWS services needed.
58
-
59
- This class provides convenient methods for manipulating entities and resources that Amazon
60
- SageMaker uses, such as training jobs, endpoints, and input datasets in S3.
61
- AWS service calls are delegated to an underlying Boto3 session, which by default
62
- is initialized using the AWS configuration chain. When you make an Amazon SageMaker API call
63
- that accesses an S3 bucket location and one is not specified, the ``Session`` creates a default
64
- bucket based on a naming convention which includes the current AWS account ID.
65
- """
66
-
67
- def __init__(
68
- self,
69
- boto_session=None,
70
- sagemaker_client=None,
71
- sagemaker_runtime_client=None,
72
- sagemaker_featurestore_runtime_client=None,
73
- default_bucket=None,
74
- sagemaker_metrics_client=None,
75
- default_bucket_prefix: str = None,
76
- ):
77
- """Initialize a SageMaker ``Session``.
78
-
79
- Args:
80
- boto_session (boto3.session.Session): The underlying Boto3 session which AWS service
81
- calls are delegated to (default: None). If not provided, one is created with
82
- default AWS configuration chain.
83
- sagemaker_client (boto3.SageMaker.Client): Client which makes Amazon SageMaker service
84
- calls other than ``InvokeEndpoint`` (default: None). Estimators created using this
85
- ``Session`` use this client. If not provided, one will be created using this
86
- instance's ``boto_session``.
87
- sagemaker_runtime_client (boto3.SageMakerRuntime.Client): Client which makes
88
- ``InvokeEndpoint`` calls to Amazon SageMaker (default: None). Predictors created
89
- using this ``Session`` use this client. If not provided, one will be created using
90
- this instance's ``boto_session``.
91
- sagemaker_featurestore_runtime_client (boto3.SageMakerFeatureStoreRuntime.Client):
92
- Client which makes SageMaker FeatureStore record related calls to Amazon SageMaker
93
- (default: None). If not provided, one will be created using
94
- this instance's ``boto_session``.
95
- default_bucket (str): The default Amazon S3 bucket to be used by this session.
96
- This will be created the next time an Amazon S3 bucket is needed (by calling
97
- :func:`default_bucket`).
98
- If not provided, it will be fetched from the sagemaker_config. If not configured
99
- there either, a default bucket will be created based on the following format:
100
- "sagemaker-{region}-{aws-account-id}".
101
- Example: "sagemaker-my-custom-bucket".
102
- sagemaker_metrics_client (boto3.SageMakerMetrics.Client):
103
- Client which makes SageMaker Metrics related calls to Amazon SageMaker
104
- (default: None). If not provided, one will be created using
105
- this instance's ``boto_session``.
106
- default_bucket_prefix (str): The default prefix to use for S3 Object Keys. (default:
107
- None). If provided and where applicable, it will be used by the SDK to construct
108
- default S3 URIs, in the format:
109
- `s3://{default_bucket}/{default_bucket_prefix}/<rest of object key>`
110
- This parameter can also be specified via `{sagemaker_config}` instead of here. If
111
- not provided here or within `{sagemaker_config}`, default S3 URIs will have the
112
- format: `s3://{default_bucket}/<rest of object key>`
113
- """
114
-
115
- # sagemaker_config is validated and initialized inside :func:`_initialize`,
116
- # so if default_bucket is None and the sagemaker_config has a default S3 bucket configured,
117
- # _default_bucket_name_override will be set again inside :func:`_initialize`.
118
- self.endpoint_arn = None
119
- self._default_bucket = None
120
- self._default_bucket_name_override = default_bucket
121
- # this may also be set again inside :func:`_initialize` if it is None
122
- self.default_bucket_prefix = default_bucket_prefix
123
- self._default_bucket_set_by_sdk = False
124
-
125
- self.s3_resource = None
126
- self.s3_client = None
127
- self.resource_groups_client = None
128
- self.resource_group_tagging_client = None
129
- self._config = None
130
- self.lambda_client = None
131
-
132
- self._initialize(
133
- boto_session=boto_session,
134
- sagemaker_client=sagemaker_client,
135
- sagemaker_runtime_client=sagemaker_runtime_client,
136
- sagemaker_featurestore_runtime_client=sagemaker_featurestore_runtime_client,
137
- sagemaker_metrics_client=sagemaker_metrics_client,
138
- )
139
-
140
- def _initialize(
141
- self,
142
- boto_session,
143
- sagemaker_client,
144
- sagemaker_runtime_client,
145
- sagemaker_featurestore_runtime_client,
146
- sagemaker_metrics_client,
147
- ):
148
- """Initialize this SageMaker Session.
149
-
150
- Creates or uses a boto_session, sagemaker_client and sagemaker_runtime_client.
151
- Sets the region_name.
152
- """
153
-
154
- self.boto_session = boto_session or boto3.DEFAULT_SESSION or boto3.Session()
155
-
156
- self._region_name = self.boto_session.region_name
157
- if self._region_name is None:
158
- raise ValueError(
159
- "Must setup local AWS configuration with a region supported by SageMaker."
160
- )
161
-
162
- # Make use of user_agent_extra field of the botocore_config object
163
- # to append SageMaker Python SDK specific user_agent suffix
164
- # to the current User-Agent header value from boto3
165
- # This config will also make sure that user_agent never fails to log the User-Agent string
166
- # even if boto User-Agent header format is updated in the future
167
- # Ref: https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html
168
-
169
- # Create sagemaker_client with the botocore_config object
170
- # This config is customized to append SageMaker Python SDK specific user_agent suffix
171
- self.sagemaker_client = sagemaker_client or self.boto_session.client("sagemaker")
172
-
173
- if sagemaker_runtime_client is not None:
174
- self.sagemaker_runtime_client = sagemaker_runtime_client
175
- else:
176
- config = botocore.config.Config(read_timeout=80)
177
- self.sagemaker_runtime_client = self.boto_session.client(
178
- "runtime.sagemaker", config=config
179
- )
180
-
181
- if sagemaker_featurestore_runtime_client:
182
- self.sagemaker_featurestore_runtime_client = sagemaker_featurestore_runtime_client
183
- else:
184
- self.sagemaker_featurestore_runtime_client = self.boto_session.client(
185
- "sagemaker-featurestore-runtime"
186
- )
187
-
188
- if sagemaker_metrics_client:
189
- self.sagemaker_metrics_client = sagemaker_metrics_client
190
- else:
191
- self.sagemaker_metrics_client = self.boto_session.client("sagemaker-metrics")
192
-
193
- self.s3_client = self.boto_session.client("s3", region_name=self.boto_region_name)
194
- self.s3_resource = self.boto_session.resource("s3", region_name=self.boto_region_name)
195
-
196
- self.local_mode = False
197
-
198
- def account_id(self) -> str:
199
- """Get the AWS account id of the caller.
200
-
201
- Returns:
202
- AWS account ID.
203
- """
204
- region = self.boto_session.region_name
205
- sts_client = self.boto_session.client(
206
- "sts", region_name=region, endpoint_url=sts_regional_endpoint(region)
207
- )
208
- return sts_client.get_caller_identity()["Account"]
209
-
210
- @property
211
- def config(self) -> Dict | None:
212
- """The config for the local mode, unused in a normal session"""
213
- return self._config
214
-
215
- @config.setter
216
- def config(self, value: Dict | None):
217
- """The config for the local mode, unused in a normal session"""
218
- self._config = value
219
-
220
- @property
221
- def boto_region_name(self):
222
- """Placeholder docstring"""
223
- return self._region_name
224
-
225
- def get_caller_identity_arn(self):
226
- """Returns the ARN user or role whose credentials are used to call the API.
227
-
228
- Returns:
229
- str: The ARN user or role
230
- """
231
- if os.path.exists(NOTEBOOK_METADATA_FILE):
232
- with open(NOTEBOOK_METADATA_FILE, "rb") as f:
233
- metadata = json.loads(f.read())
234
- instance_name = metadata.get("ResourceName")
235
- domain_id = metadata.get("DomainId")
236
- user_profile_name = metadata.get("UserProfileName")
237
- execution_role_arn = metadata.get("ExecutionRoleArn")
238
- try:
239
- if domain_id is None:
240
- instance_desc = self.sagemaker_client.describe_notebook_instance(
241
- NotebookInstanceName=instance_name
242
- )
243
- return instance_desc["RoleArn"]
244
-
245
- # find execution role from the metadata file if present
246
- if execution_role_arn is not None:
247
- return execution_role_arn
248
-
249
- user_profile_desc = self.sagemaker_client.describe_user_profile(
250
- DomainId=domain_id, UserProfileName=user_profile_name
251
- )
252
-
253
- # First, try to find role in userSettings
254
- if user_profile_desc.get("UserSettings", {}).get("ExecutionRole"):
255
- return user_profile_desc["UserSettings"]["ExecutionRole"]
256
-
257
- # If not found, fallback to the domain
258
- domain_desc = self.sagemaker_client.describe_domain(DomainId=domain_id)
259
- return domain_desc["DefaultUserSettings"]["ExecutionRole"]
260
- except ClientError:
261
- logger.debug(
262
- "Couldn't call 'describe_notebook_instance' to get the Role "
263
- "ARN of the instance %s.",
264
- instance_name,
265
- )
266
-
267
- assumed_role = self.boto_session.client(
268
- "sts",
269
- region_name=self.boto_region_name,
270
- endpoint_url=sts_regional_endpoint(self.boto_region_name),
271
- ).get_caller_identity()["Arn"]
272
-
273
- role = re.sub(r"^(.+)sts::(\d+):assumed-role/(.+?)/.*$", r"\1iam::\2:role/\3", assumed_role)
274
-
275
- # Call IAM to get the role's path
276
- role_name = role[role.rfind("/") + 1 :]
277
- try:
278
- role = self.boto_session.client("iam").get_role(RoleName=role_name)["Role"]["Arn"]
279
- except ClientError:
280
- logger.warning(
281
- "Couldn't call 'get_role' to get Role ARN from role name %s to get Role path.",
282
- role_name,
283
- )
284
-
285
- # This conditional has been present since the inception of SageMaker
286
- # Guessing this conditional's purpose was to handle lack of IAM permissions
287
- # https://github.com/aws/sagemaker-python-sdk/issues/2089#issuecomment-791802713
288
- if "AmazonSageMaker-ExecutionRole" in assumed_role:
289
- logger.warning(
290
- "Assuming role was created in SageMaker AWS console, "
291
- "as the name contains `AmazonSageMaker-ExecutionRole`. "
292
- "Defaulting to Role ARN with service-role in path. "
293
- "If this Role ARN is incorrect, please add "
294
- "IAM read permissions to your role or supply the "
295
- "Role Arn directly."
296
- )
297
- role = re.sub(
298
- r"^(.+)sts::(\d+):assumed-role/(.+?)/.*$",
299
- r"\1iam::\2:role/service-role/\3",
300
- assumed_role,
301
- )
302
-
303
- return role
304
-
305
- def upload_data(self, path, bucket=None, key_prefix="data", callback=None, extra_args=None):
306
- """Upload local file or directory to S3.
307
-
308
- If a single file is specified for upload, the resulting S3 object key is
309
- ``{key_prefix}/{filename}`` (filename does not include the local path, if any specified).
310
- If a directory is specified for upload, the API uploads all content, recursively,
311
- preserving relative structure of subdirectories. The resulting object key names are:
312
- ``{key_prefix}/{relative_subdirectory_path}/filename``.
313
-
314
- Args:
315
- path (str): Path (absolute or relative) of local file or directory to upload.
316
- bucket (str): Name of the S3 Bucket to upload to (default: None). If not specified, the
317
- default bucket of the ``Session`` is used (if default bucket does not exist, the
318
- ``Session`` creates it).
319
- key_prefix (str): Optional S3 object key name prefix (default: 'data'). S3 uses the
320
- prefix to create a directory structure for the bucket content that it display in
321
- the S3 console.
322
- extra_args (dict): Optional extra arguments that may be passed to the upload operation.
323
- Similar to ExtraArgs parameter in S3 upload_file function. Please refer to the
324
- ExtraArgs parameter documentation here:
325
- https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-uploading-files.html#the-extraargs-parameter
326
-
327
- Returns:
328
- str: The S3 URI of the uploaded file(s). If a file is specified in the path argument,
329
- the URI format is: ``s3://{bucket name}/{key_prefix}/{original_file_name}``.
330
- If a directory is specified in the path argument, the URI format is
331
- ``s3://{bucket name}/{key_prefix}``.
332
- """
333
- bucket, key_prefix = self.determine_bucket_and_prefix(
334
- bucket=bucket, key_prefix=key_prefix, sagemaker_session=self
335
- )
336
-
337
- # Generate a tuple for each file that we want to upload of the form (local_path, s3_key).
338
- files = []
339
- key_suffix = None
340
- if os.path.isdir(path):
341
- for dirpath, _, filenames in os.walk(path):
342
- for name in filenames:
343
- local_path = os.path.join(dirpath, name)
344
- s3_relative_prefix = (
345
- "" if path == dirpath else os.path.relpath(dirpath, start=path) + "/"
346
- )
347
- s3_key = "{}/{}{}".format(key_prefix, s3_relative_prefix, name)
348
- files.append((local_path, s3_key))
349
- else:
350
- _, name = os.path.split(path)
351
- s3_key = "{}/{}".format(key_prefix, name)
352
- files.append((path, s3_key))
353
- key_suffix = name
354
-
355
- if self.s3_resource is None:
356
- s3 = self.boto_session.resource("s3", region_name=self.boto_region_name)
357
- else:
358
- s3 = self.s3_resource
359
-
360
- for local_path, s3_key in files:
361
- s3.Object(bucket, s3_key).upload_file(
362
- local_path, Callback=callback, ExtraArgs=extra_args
363
- )
364
-
365
- s3_uri = "s3://{}/{}".format(bucket, key_prefix)
366
- # If a specific file was used as input (instead of a directory), we return the full S3 key
367
- # of the uploaded object. This prevents unintentionally using other files under the same
368
- # prefix during training.
369
- if key_suffix:
370
- s3_uri = "{}/{}".format(s3_uri, key_suffix)
371
- return s3_uri
372
-
373
- def read_s3_file(self, bucket, key_prefix):
374
- """Read a single file from S3.
375
-
376
- Args:
377
- bucket (str): Name of the S3 Bucket to download from.
378
- key_prefix (str): S3 object key name prefix.
379
-
380
- Returns:
381
- str: The body of the s3 file as a string.
382
- """
383
- if self.s3_client is None:
384
- s3 = self.boto_session.client("s3", region_name=self.boto_region_name)
385
- else:
386
- s3 = self.s3_client
387
-
388
- # Explicitly passing a None kms_key to boto3 throws a validation error.
389
- s3_object = s3.get_object(Bucket=bucket, Key=key_prefix)
390
-
391
- return s3_object["Body"].read().decode("utf-8")
392
-
393
- def default_bucket(self):
394
- """Return the name of the default bucket to use in relevant Amazon SageMaker interactions.
395
-
396
- This function will create the s3 bucket if it does not exist.
397
-
398
- Returns:
399
- str: The name of the default bucket. If the name was not explicitly specified through
400
- the Session or sagemaker_config, the bucket will take the form:
401
- ``sagemaker-{region}-{AWS account ID}``.
402
- """
403
-
404
- if self._default_bucket:
405
- return self._default_bucket
406
-
407
- region = self.boto_session.region_name
408
-
409
- default_bucket = self._default_bucket_name_override
410
- if not default_bucket:
411
- default_bucket = self.generate_default_sagemaker_bucket_name(self.boto_session)
412
- self._default_bucket_set_by_sdk = True
413
-
414
- self._create_s3_bucket_if_it_does_not_exist(
415
- bucket_name=default_bucket,
416
- region=region,
417
- )
418
-
419
- self._default_bucket = default_bucket
420
-
421
- return self._default_bucket
422
-
423
- def _create_s3_bucket_if_it_does_not_exist(self, bucket_name, region):
424
- """Creates an S3 Bucket if it does not exist.
425
-
426
- Also swallows a few common exceptions that indicate that the bucket already exists or
427
- that it is being created.
428
-
429
- Args:
430
- bucket_name (str): Name of the S3 bucket to be created.
431
- region (str): The region in which to create the bucket.
432
-
433
- Raises:
434
- botocore.exceptions.ClientError: If S3 throws an unexpected exception during bucket
435
- creation.
436
- If the exception is due to the bucket already existing or
437
- already being created, no exception is raised.
438
- """
439
- if self.s3_resource is None:
440
- s3 = self.boto_session.resource("s3", region_name=region)
441
- else:
442
- s3 = self.s3_resource
443
-
444
- bucket = s3.Bucket(name=bucket_name)
445
- if bucket.creation_date is None:
446
- self.general_bucket_check_if_user_has_permission(bucket_name, s3, bucket, region, True)
447
-
448
- elif self._default_bucket_set_by_sdk:
449
- self.general_bucket_check_if_user_has_permission(bucket_name, s3, bucket, region, False)
450
-
451
- expected_bucket_owner_id = self.account_id()
452
- self.expected_bucket_owner_id_bucket_check(bucket_name, s3, expected_bucket_owner_id)
453
-
454
- def expected_bucket_owner_id_bucket_check(self, bucket_name, s3, expected_bucket_owner_id):
455
- """Checks if the bucket belongs to a particular owner and throws a Client Error if it is not
456
-
457
- Args:
458
- bucket_name (str): Name of the S3 bucket
459
- s3 (str): S3 object from boto session
460
- expected_bucket_owner_id (str): Owner ID string
461
-
462
- """
463
- try:
464
- s3.meta.client.head_bucket(
465
- Bucket=bucket_name, ExpectedBucketOwner=expected_bucket_owner_id
466
- )
467
- except ClientError as e:
468
- error_code = e.response["Error"]["Code"]
469
- message = e.response["Error"]["Message"]
470
- if error_code == "403" and message == "Forbidden":
471
- LOGGER.error(
472
- "Since default_bucket param was not set, SageMaker Python SDK tried to use "
473
- "%s bucket. "
474
- "This bucket cannot be configured to use as it is not owned by Account %s. "
475
- "To unblock it's recommended to use custom default_bucket "
476
- "parameter in sagemaker.Session",
477
- bucket_name,
478
- expected_bucket_owner_id,
479
- )
480
- raise
481
-
482
- def general_bucket_check_if_user_has_permission(
483
- self, bucket_name, s3, bucket, region, bucket_creation_date_none
484
- ):
485
- """Checks if the person running has the permissions to the bucket
486
-
487
- If there is any other error that comes up with calling head bucket, it is raised up here
488
- If there is no bucket , it will create one
489
-
490
- Args:
491
- bucket_name (str): Name of the S3 bucket
492
- s3 (str): S3 object from boto session
493
- region (str): The region in which to create the bucket.
494
- bucket_creation_date_none (bool):Indicating whether S3 bucket already exists or not
495
- """
496
- try:
497
- s3.meta.client.head_bucket(Bucket=bucket_name)
498
- except ClientError as e:
499
- error_code = e.response["Error"]["Code"]
500
- message = e.response["Error"]["Message"]
501
- # bucket does not exist or forbidden to access
502
- if bucket_creation_date_none:
503
- if error_code == "404" and message == "Not Found":
504
- self.create_bucket_for_not_exist_error(bucket_name, region, s3)
505
- elif error_code == "403" and message == "Forbidden":
506
- LOGGER.error(
507
- "Bucket %s exists, but access is forbidden. Please try again after "
508
- "adding appropriate access.",
509
- bucket.name,
510
- )
511
- raise
512
- else:
513
- raise
514
-
515
- def create_bucket_for_not_exist_error(self, bucket_name, region, s3):
516
- """Creates the S3 bucket in the given region
517
-
518
- Args:
519
- bucket_name (str): Name of the S3 bucket
520
- s3 (str): S3 object from boto session
521
- region (str): The region in which to create the bucket.
522
- """
523
- # bucket does not exist, create one
524
- try:
525
- if region == "us-east-1":
526
- # 'us-east-1' cannot be specified because it is the default region:
527
- # https://github.com/boto/boto3/issues/125
528
- s3.create_bucket(Bucket=bucket_name)
529
- else:
530
- s3.create_bucket(
531
- Bucket=bucket_name,
532
- CreateBucketConfiguration={"LocationConstraint": region},
533
- )
534
-
535
- logger.info("Created S3 bucket: %s", bucket_name)
536
- except ClientError as e:
537
- error_code = e.response["Error"]["Code"]
538
- message = e.response["Error"]["Message"]
539
-
540
- if error_code == "OperationAborted" and "conflicting conditional operation" in message:
541
- # If this bucket is already being concurrently created,
542
- # we don't need to create it again.
543
- pass
544
- else:
545
- raise
546
-
547
- def generate_default_sagemaker_bucket_name(self, boto_session):
548
- """Generates a name for the default sagemaker S3 bucket.
549
-
550
- Args:
551
- boto_session (boto3.session.Session): The underlying Boto3 session which AWS service
552
- """
553
- region = boto_session.region_name
554
- account = boto_session.client(
555
- "sts", region_name=region, endpoint_url=sts_regional_endpoint(region)
556
- ).get_caller_identity()["Account"]
557
- return "sagemaker-{}-{}".format(region, account)
558
-
559
- def determine_bucket_and_prefix(
560
- self, bucket: Optional[str] = None, key_prefix: Optional[str] = None, sagemaker_session=None
561
- ):
562
- """Helper function that returns the correct S3 bucket and prefix to use depending on the inputs.
563
-
564
- Args:
565
- bucket (Optional[str]): S3 Bucket to use (if it exists)
566
- key_prefix (Optional[str]): S3 Object Key Prefix to use or append to (if it exists)
567
- sagemaker_session (sagemaker.session.Session): Session to fetch a default bucket and
568
- prefix from, if bucket doesn't exist. Expected to exist
569
-
570
- Returns: The correct S3 Bucket and S3 Object Key Prefix that should be used
571
- """
572
- if bucket:
573
- final_bucket = bucket
574
- final_key_prefix = key_prefix
575
- else:
576
- final_bucket = sagemaker_session.default_bucket()
577
-
578
- # default_bucket_prefix (if it exists) should be appended if (and only if) 'bucket' does not
579
- # exist and we are using the Session's default_bucket.
580
- final_key_prefix = s3_path_join(sagemaker_session.default_bucket_prefix, key_prefix)
581
-
582
- # We should not append default_bucket_prefix even if the bucket exists but is equal to the
583
- # default_bucket, because either:
584
- # (1) the bucket was explicitly passed in by the user and just happens to be the same as the
585
- # default_bucket (in which case we don't want to change the user's input), or
586
- # (2) the default_bucket was fetched from Session earlier already (and the default prefix
587
- # should have been fetched then as well), and then this function was
588
- # called with it. If we appended the default prefix here, we would be appending it more than
589
- # once in total.
590
-
591
- return final_bucket, final_key_prefix
592
-
593
-
594
- def s3_path_join(*args, with_end_slash: bool = False):
595
- """Returns the arguments joined by a slash ("/"), similar to ``os.path.join()`` (on Unix).
596
-
597
- Behavior of this function:
598
- - If the first argument is "s3://", then that is preserved.
599
- - The output by default will have no slashes at the beginning or end. There is one exception
600
- (see `with_end_slash`). For example, `s3_path_join("/foo", "bar/")` will yield
601
- `"foo/bar"` and `s3_path_join("foo", "bar", with_end_slash=True)` will yield `"foo/bar/"`
602
- - Any repeat slashes will be removed in the output (except for "s3://" if provided at the
603
- beginning). For example, `s3_path_join("s3://", "//foo/", "/bar///baz")` will yield
604
- `"s3://foo/bar/baz"`.
605
- - Empty or None arguments will be skipped. For example
606
- `s3_path_join("foo", "", None, "bar")` will yield `"foo/bar"`
607
-
608
- Alternatives to this function that are NOT recommended for S3 paths:
609
- - `os.path.join(...)` will have different behavior on Unix machines vs non-Unix machines
610
- - `pathlib.PurePosixPath(...)` will apply potentially unintended simplification of single
611
- dots (".") and root directories. (for example
612
- `pathlib.PurePosixPath("foo", "/bar/./", "baz")` would yield `"/bar/baz"`)
613
- - `"{}/{}/{}".format(...)` and similar may result in unintended repeat slashes
614
-
615
- Args:
616
- *args: The strings to join with a slash.
617
- with_end_slash (bool): (default: False) If true and if the path is not empty, appends a "/"
618
- to the end of the path
619
-
620
- Returns:
621
- str: The joined string, without a slash at the end unless with_end_slash is True.
622
- """
623
- delimiter = "/"
624
-
625
- non_empty_args = list(filter(lambda item: item is not None and item != "", args))
626
-
627
- merged_path = ""
628
- for index, path in enumerate(non_empty_args):
629
- if (
630
- index == 0
631
- or (merged_path and merged_path[-1] == delimiter)
632
- or (path and path[0] == delimiter)
633
- ):
634
- # dont need to add an extra slash because either this is the beginning of the string,
635
- # or one (or more) slash already exists
636
- merged_path += path
637
- else:
638
- merged_path += delimiter + path
639
-
640
- if with_end_slash and merged_path and merged_path[-1] != delimiter:
641
- merged_path += delimiter
642
-
643
- # At this point, merged_path may include slashes at the beginning and/or end. And some of the
644
- # provided args may have had duplicate slashes inside or at the ends.
645
- # For backwards compatibility reasons, these need to be filtered out (done below). In the
646
- # future, if there is a desire to support multiple slashes for S3 paths throughout the SDK,
647
- # one option is to create a new optional argument (or a new function) that only executes the
648
- # logic above.
649
- filtered_path = merged_path
650
-
651
- # remove duplicate slashes
652
- if filtered_path:
653
-
654
- def duplicate_delimiter_remover(sequence, next_char):
655
- if sequence[-1] == delimiter and next_char == delimiter:
656
- return sequence
657
- return sequence + next_char
658
-
659
- if filtered_path.startswith("s3://"):
660
- filtered_path = reduce(
661
- duplicate_delimiter_remover, filtered_path[5:], filtered_path[:5]
662
- )
663
- else:
664
- filtered_path = reduce(duplicate_delimiter_remover, filtered_path)
665
-
666
- # remove beginning slashes
667
- filtered_path = filtered_path.lstrip(delimiter)
668
-
669
- # remove end slashes
670
- if not with_end_slash and filtered_path != "s3://":
671
- filtered_path = filtered_path.rstrip(delimiter)
672
-
673
- return filtered_path
674
-
675
-
676
- def botocore_resolver():
677
- """Get the DNS suffix for the given region.
678
-
679
- Args:
680
- region (str): AWS region name
681
-
682
- Returns:
683
- str: the DNS suffix
684
- """
685
- loader = botocore.loaders.create_loader()
686
- return botocore.regions.EndpointResolver(loader.load_data("endpoints"))
687
-
688
-
689
- def sts_regional_endpoint(region):
690
- """Get the AWS STS endpoint specific for the given region.
691
-
692
- We need this function because the AWS SDK does not yet honor
693
- the ``region_name`` parameter when creating an AWS STS client.
694
-
695
- For the list of regional endpoints, see
696
- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#id_credentials_region-endpoints.
697
-
698
- Args:
699
- region (str): AWS region name
700
-
701
- Returns:
702
- str: AWS STS regional endpoint
703
- """
704
- endpoint_data = botocore_resolver().construct_endpoint("sts", region)
705
- if region == "il-central-1" and not endpoint_data:
706
- endpoint_data = {"hostname": "sts.{}.amazonaws.com".format(region)}
707
- return "https://{}".format(endpoint_data["hostname"])
708
-
709
-
710
- def get_execution_role(sagemaker_session=None, use_default=False):
711
- """Return the role ARN whose credentials are used to call the API.
712
-
713
- Throws an exception if role doesn't exist.
714
-
715
- Args:
716
- sagemaker_session (Session): Current sagemaker session.
717
- use_default (bool): Use a default role if ``get_caller_identity_arn`` does not
718
- return a correct role. This default role will be created if needed.
719
- Defaults to ``False``.
720
-
721
- Returns:
722
- (str): The role ARN
723
- """
724
- if not sagemaker_session:
725
- sagemaker_session = Session()
726
- arn = sagemaker_session.get_caller_identity_arn()
727
-
728
- if ":role/" in arn:
729
- return arn
730
-
731
- if use_default:
732
- default_role_name = "AmazonSageMaker-DefaultRole"
733
-
734
- LOGGER.warning("Using default role: %s", default_role_name)
735
-
736
- boto3_session = sagemaker_session.boto_session
737
- permissions_policy = json.dumps(
738
- {
739
- "Version": "2012-10-17",
740
- "Statement": [
741
- {
742
- "Effect": "Allow",
743
- "Principal": {"Service": ["sagemaker.amazonaws.com"]},
744
- "Action": "sts:AssumeRole",
745
- }
746
- ],
747
- }
748
- )
749
- iam_client = boto3_session.client("iam")
750
- try:
751
- iam_client.get_role(RoleName=default_role_name)
752
- except iam_client.exceptions.NoSuchEntityException:
753
- iam_client.create_role(
754
- RoleName=default_role_name, AssumeRolePolicyDocument=str(permissions_policy)
755
- )
756
-
757
- LOGGER.warning("Created new sagemaker execution role: %s", default_role_name)
758
-
759
- iam_client.attach_role_policy(
760
- PolicyArn="arn:aws:iam::aws:policy/AmazonSageMakerFullAccess",
761
- RoleName=default_role_name,
762
- )
763
- return iam_client.get_role(RoleName=default_role_name)["Role"]["Arn"]
764
-
765
- message = (
766
- "The current AWS identity is not a role: {}, therefore it cannot be used as a "
767
- "SageMaker execution role"
768
- )
769
- raise ValueError(message.format(arn))