sagemaker-core 1.0.62__py3-none-any.whl → 2.3.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 (358) hide show
  1. sagemaker/__init__.py +2 -0
  2. sagemaker/core/__init__.py +16 -0
  3. sagemaker/core/_studio.py +116 -0
  4. sagemaker/core/_version.py +11 -0
  5. sagemaker/core/accept_types.py +131 -0
  6. sagemaker/core/analytics.py +744 -0
  7. sagemaker/core/apiutils/__init__.py +13 -0
  8. sagemaker/core/apiutils/_base_types.py +228 -0
  9. sagemaker/core/apiutils/_boto_functions.py +130 -0
  10. sagemaker/core/apiutils/_utils.py +34 -0
  11. sagemaker/core/base_deserializers.py +35 -0
  12. sagemaker/core/base_serializers.py +35 -0
  13. sagemaker/core/clarify/__init__.py +2898 -0
  14. sagemaker/core/collection.py +467 -0
  15. sagemaker/core/common_utils.py +2399 -0
  16. sagemaker/core/compute_resource_requirements/__init__.py +18 -0
  17. sagemaker/core/compute_resource_requirements/resource_requirements.py +94 -0
  18. sagemaker/core/config/__init__.py +181 -0
  19. sagemaker/core/config/config.py +238 -0
  20. sagemaker/core/config/config_manager.py +595 -0
  21. sagemaker/core/config/config_schema.py +1220 -0
  22. sagemaker/core/config/config_utils.py +297 -0
  23. {sagemaker_core/main → sagemaker/core}/config_schema.py +408 -3
  24. sagemaker/core/constants.py +73 -0
  25. sagemaker/core/content_types.py +137 -0
  26. sagemaker/core/debugger/__init__.py +39 -0
  27. sagemaker/core/debugger/debugger.py +945 -0
  28. sagemaker/core/debugger/framework_profile.py +292 -0
  29. sagemaker/core/debugger/metrics_config.py +468 -0
  30. sagemaker/core/debugger/profiler.py +42 -0
  31. sagemaker/core/debugger/profiler_config.py +190 -0
  32. sagemaker/core/debugger/profiler_constants.py +40 -0
  33. sagemaker/core/debugger/utils.py +148 -0
  34. sagemaker/core/deprecations.py +254 -0
  35. sagemaker/core/deserializers/__init__.py +10 -0
  36. sagemaker/core/deserializers/base.py +424 -0
  37. sagemaker/core/deserializers/implementations.py +157 -0
  38. sagemaker/core/drift_check_baselines.py +106 -0
  39. sagemaker/core/enums.py +51 -0
  40. sagemaker/core/environment_variables.py +101 -0
  41. sagemaker/core/exceptions.py +108 -0
  42. sagemaker/core/experiments/__init__.py +53 -0
  43. sagemaker/core/experiments/_api_types.py +251 -0
  44. sagemaker/core/experiments/_environment.py +124 -0
  45. sagemaker/core/experiments/_helper.py +294 -0
  46. sagemaker/core/experiments/_metrics.py +333 -0
  47. sagemaker/core/experiments/_run_context.py +58 -0
  48. sagemaker/core/experiments/_utils.py +216 -0
  49. sagemaker/core/experiments/experiment.py +247 -0
  50. sagemaker/core/experiments/run.py +970 -0
  51. sagemaker/core/experiments/trial.py +296 -0
  52. sagemaker/core/experiments/trial_component.py +387 -0
  53. sagemaker/core/explainer/__init__.py +24 -0
  54. sagemaker/core/explainer/clarify_explainer_config.py +298 -0
  55. sagemaker/core/explainer/explainer_config.py +44 -0
  56. sagemaker/core/fw_utils.py +1220 -0
  57. sagemaker/core/git_utils.py +415 -0
  58. sagemaker/core/helper/pipeline_variable.py +82 -0
  59. sagemaker/core/helper/session_helper.py +2977 -0
  60. sagemaker/core/hyperparameters.py +172 -0
  61. sagemaker/core/image_retriever/__init__.py +3 -0
  62. sagemaker/core/image_retriever/image_retriever.py +640 -0
  63. sagemaker/core/image_retriever/image_retriever_utils.py +509 -0
  64. sagemaker/core/image_retriever/test.py +7 -0
  65. sagemaker/core/image_uri_config/autogluon.json +1335 -0
  66. sagemaker/core/image_uri_config/blazingtext.json +50 -0
  67. sagemaker/core/image_uri_config/chainer.json +104 -0
  68. sagemaker/core/image_uri_config/clarify.json +39 -0
  69. sagemaker/core/image_uri_config/coach-mxnet.json +70 -0
  70. sagemaker/core/image_uri_config/coach-tensorflow.json +186 -0
  71. sagemaker/core/image_uri_config/data-wrangler.json +91 -0
  72. sagemaker/core/image_uri_config/debugger.json +34 -0
  73. sagemaker/core/image_uri_config/detailed-profiler.json +18 -0
  74. sagemaker/core/image_uri_config/djl-deepspeed.json +385 -0
  75. sagemaker/core/image_uri_config/djl-fastertransformer.json +167 -0
  76. sagemaker/core/image_uri_config/djl-lmi.json +136 -0
  77. sagemaker/core/image_uri_config/djl-neuronx.json +258 -0
  78. sagemaker/core/image_uri_config/djl-tensorrtllm.json +262 -0
  79. sagemaker/core/image_uri_config/factorization-machines.json +50 -0
  80. sagemaker/core/image_uri_config/forecasting-deepar.json +50 -0
  81. sagemaker/core/image_uri_config/huggingface-llm-neuronx.json +770 -0
  82. sagemaker/core/image_uri_config/huggingface-llm.json +1267 -0
  83. sagemaker/core/image_uri_config/huggingface-neuron.json +52 -0
  84. sagemaker/core/image_uri_config/huggingface-neuronx.json +686 -0
  85. sagemaker/core/image_uri_config/huggingface-tei-cpu.json +298 -0
  86. sagemaker/core/image_uri_config/huggingface-tei.json +298 -0
  87. sagemaker/core/image_uri_config/huggingface-training-compiler.json +195 -0
  88. sagemaker/core/image_uri_config/huggingface-vllm-neuronx.json +38 -0
  89. sagemaker/core/image_uri_config/huggingface.json +2287 -0
  90. sagemaker/core/image_uri_config/hyperpod-recipes-neuron.json +52 -0
  91. sagemaker/core/image_uri_config/image-classification-neo.json +43 -0
  92. sagemaker/core/image_uri_config/image-classification.json +50 -0
  93. sagemaker/core/image_uri_config/inferentia-mxnet.json +88 -0
  94. sagemaker/core/image_uri_config/inferentia-pytorch.json +127 -0
  95. sagemaker/core/image_uri_config/inferentia-tensorflow.json +88 -0
  96. sagemaker/core/image_uri_config/instance_gpu_info.json +782 -0
  97. sagemaker/core/image_uri_config/ipinsights.json +50 -0
  98. sagemaker/core/image_uri_config/kmeans.json +50 -0
  99. sagemaker/core/image_uri_config/knn.json +50 -0
  100. sagemaker/core/image_uri_config/lda.json +26 -0
  101. sagemaker/core/image_uri_config/linear-learner.json +50 -0
  102. sagemaker/core/image_uri_config/model-monitor.json +42 -0
  103. sagemaker/core/image_uri_config/mxnet.json +1154 -0
  104. sagemaker/core/image_uri_config/neo-mxnet.json +64 -0
  105. sagemaker/core/image_uri_config/neo-pytorch.json +341 -0
  106. sagemaker/core/image_uri_config/neo-tensorflow.json +109 -0
  107. sagemaker/core/image_uri_config/ntm.json +50 -0
  108. sagemaker/core/image_uri_config/object-detection.json +50 -0
  109. sagemaker/core/image_uri_config/object2vec.json +50 -0
  110. sagemaker/core/image_uri_config/pca.json +50 -0
  111. sagemaker/core/image_uri_config/pytorch-neuron.json +43 -0
  112. sagemaker/core/image_uri_config/pytorch-smp.json +218 -0
  113. sagemaker/core/image_uri_config/pytorch-training-compiler.json +80 -0
  114. sagemaker/core/image_uri_config/pytorch.json +3101 -0
  115. sagemaker/core/image_uri_config/randomcutforest.json +50 -0
  116. sagemaker/core/image_uri_config/ray-pytorch.json +46 -0
  117. sagemaker/core/image_uri_config/ray-tensorflow.json +194 -0
  118. sagemaker/core/image_uri_config/sagemaker-base-python.json +46 -0
  119. sagemaker/core/image_uri_config/sagemaker-distribution.json +37 -0
  120. sagemaker/core/image_uri_config/sagemaker-geospatial.json +13 -0
  121. sagemaker/core/image_uri_config/sagemaker-tritonserver.json +252 -0
  122. sagemaker/core/image_uri_config/semantic-segmentation.json +50 -0
  123. sagemaker/core/image_uri_config/seq2seq.json +50 -0
  124. sagemaker/core/image_uri_config/sklearn.json +494 -0
  125. sagemaker/core/image_uri_config/spark.json +280 -0
  126. sagemaker/core/image_uri_config/sparkml-serving.json +97 -0
  127. sagemaker/core/image_uri_config/stabilityai.json +53 -0
  128. sagemaker/core/image_uri_config/tensorflow.json +5086 -0
  129. sagemaker/core/image_uri_config/vw.json +25 -0
  130. sagemaker/core/image_uri_config/xgboost-neo.json +43 -0
  131. sagemaker/core/image_uri_config/xgboost.json +972 -0
  132. sagemaker/core/image_uris.py +816 -0
  133. sagemaker/core/inference_config.py +144 -0
  134. sagemaker/core/inference_recommender/__init__.py +18 -0
  135. sagemaker/core/inference_recommender/inference_recommender_mixin.py +622 -0
  136. sagemaker/core/inputs.py +366 -0
  137. sagemaker/core/instance_group.py +61 -0
  138. sagemaker/core/instance_types.py +164 -0
  139. sagemaker/core/instance_types_gpu_info.py +43 -0
  140. sagemaker/core/interactive_apps/__init__.py +41 -0
  141. sagemaker/core/interactive_apps/base_interactive_app.py +204 -0
  142. sagemaker/core/interactive_apps/detail_profiler_app.py +139 -0
  143. sagemaker/core/interactive_apps/tensorboard.py +149 -0
  144. sagemaker/core/iterators.py +197 -0
  145. sagemaker/core/job.py +380 -0
  146. sagemaker/core/jumpstart/__init__.py +156 -0
  147. sagemaker/core/jumpstart/accessors.py +390 -0
  148. sagemaker/core/jumpstart/artifacts/__init__.py +69 -0
  149. sagemaker/core/jumpstart/artifacts/environment_variables.py +252 -0
  150. sagemaker/core/jumpstart/artifacts/hyperparameters.py +120 -0
  151. sagemaker/core/jumpstart/artifacts/image_uris.py +139 -0
  152. sagemaker/core/jumpstart/artifacts/incremental_training.py +87 -0
  153. sagemaker/core/jumpstart/artifacts/instance_types.py +223 -0
  154. sagemaker/core/jumpstart/artifacts/kwargs.py +289 -0
  155. sagemaker/core/jumpstart/artifacts/metric_definitions.py +117 -0
  156. sagemaker/core/jumpstart/artifacts/model_packages.py +202 -0
  157. sagemaker/core/jumpstart/artifacts/model_uris.py +252 -0
  158. sagemaker/core/jumpstart/artifacts/payloads.py +96 -0
  159. sagemaker/core/jumpstart/artifacts/predictors.py +540 -0
  160. sagemaker/core/jumpstart/artifacts/resource_names.py +86 -0
  161. sagemaker/core/jumpstart/artifacts/resource_requirements.py +162 -0
  162. sagemaker/core/jumpstart/artifacts/script_uris.py +172 -0
  163. sagemaker/core/jumpstart/cache.py +663 -0
  164. sagemaker/core/jumpstart/configs.py +50 -0
  165. sagemaker/core/jumpstart/constants.py +198 -0
  166. sagemaker/core/jumpstart/deserializers.py +81 -0
  167. sagemaker/core/jumpstart/document.py +76 -0
  168. sagemaker/core/jumpstart/enums.py +168 -0
  169. sagemaker/core/jumpstart/exceptions.py +236 -0
  170. sagemaker/core/jumpstart/factory/utils.py +833 -0
  171. sagemaker/core/jumpstart/filters.py +597 -0
  172. sagemaker/core/jumpstart/hub/constants.py +16 -0
  173. sagemaker/core/jumpstart/hub/hub.py +291 -0
  174. sagemaker/core/jumpstart/hub/interfaces.py +936 -0
  175. sagemaker/core/jumpstart/hub/parser_utils.py +70 -0
  176. sagemaker/core/jumpstart/hub/parsers.py +288 -0
  177. sagemaker/core/jumpstart/hub/types.py +35 -0
  178. sagemaker/core/jumpstart/hub/utils.py +260 -0
  179. sagemaker/core/jumpstart/models.py +501 -0
  180. sagemaker/core/jumpstart/notebook_utils.py +575 -0
  181. sagemaker/core/jumpstart/parameters.py +20 -0
  182. sagemaker/core/jumpstart/payload_utils.py +239 -0
  183. sagemaker/core/jumpstart/region_config.json +171 -0
  184. sagemaker/core/jumpstart/search.py +171 -0
  185. sagemaker/core/jumpstart/serializers.py +81 -0
  186. sagemaker/core/jumpstart/session_utils.py +234 -0
  187. sagemaker/core/jumpstart/types.py +3044 -0
  188. sagemaker/core/jumpstart/utils.py +1731 -0
  189. sagemaker/core/jumpstart/validators.py +257 -0
  190. sagemaker/core/lambda_helper.py +312 -0
  191. sagemaker/core/lineage/__init__.py +42 -0
  192. sagemaker/core/lineage/_api_types.py +239 -0
  193. sagemaker/core/lineage/_utils.py +49 -0
  194. sagemaker/core/lineage/action.py +345 -0
  195. sagemaker/core/lineage/artifact.py +646 -0
  196. sagemaker/core/lineage/association.py +190 -0
  197. sagemaker/core/lineage/context.py +505 -0
  198. sagemaker/core/lineage/lineage_trial_component.py +191 -0
  199. sagemaker/core/lineage/query.py +732 -0
  200. sagemaker/core/lineage/visualizer.py +346 -0
  201. sagemaker/core/local/__init__.py +18 -0
  202. sagemaker/core/local/data.py +423 -0
  203. sagemaker/core/local/entities.py +678 -0
  204. sagemaker/core/local/exceptions.py +17 -0
  205. sagemaker/core/local/image.py +1243 -0
  206. sagemaker/core/local/local_session.py +739 -0
  207. sagemaker/core/local/utils.py +246 -0
  208. sagemaker/core/logs.py +181 -0
  209. sagemaker/core/metadata_properties.py +56 -0
  210. sagemaker/core/metric_definitions.py +91 -0
  211. sagemaker/core/mlflow/__init__.py +38 -0
  212. sagemaker/core/mlflow/forward_sagemaker_metrics.py +44 -0
  213. sagemaker/core/model_card/__init__.py +26 -0
  214. sagemaker/core/model_life_cycle.py +51 -0
  215. sagemaker/core/model_metrics.py +160 -0
  216. sagemaker/core/model_monitor/__init__.py +66 -0
  217. sagemaker/core/model_monitor/clarify_model_monitoring.py +1497 -0
  218. sagemaker/core/model_monitor/cron_expression_generator.py +82 -0
  219. sagemaker/core/model_monitor/data_capture_config.py +115 -0
  220. sagemaker/core/model_monitor/data_quality_monitoring_config.py +66 -0
  221. sagemaker/core/model_monitor/dataset_format.py +102 -0
  222. sagemaker/core/model_monitor/model_monitoring.py +4266 -0
  223. sagemaker/core/model_monitor/monitoring_alert.py +76 -0
  224. sagemaker/core/model_monitor/monitoring_files.py +506 -0
  225. sagemaker/core/model_monitor/utils.py +793 -0
  226. sagemaker/core/model_registry.py +480 -0
  227. sagemaker/core/model_uris.py +97 -0
  228. sagemaker/core/modules/__init__.py +19 -0
  229. sagemaker/core/modules/configs.py +239 -0
  230. sagemaker/core/modules/constants.py +37 -0
  231. sagemaker/core/modules/distributed.py +182 -0
  232. sagemaker/core/modules/local_core/local_container.py +605 -0
  233. sagemaker/core/modules/templates.py +83 -0
  234. sagemaker/core/modules/train/__init__.py +14 -0
  235. sagemaker/core/modules/train/container_drivers/__init__.py +14 -0
  236. sagemaker/core/modules/train/container_drivers/common/__init__.py +14 -0
  237. sagemaker/core/modules/train/container_drivers/common/utils.py +205 -0
  238. sagemaker/core/modules/train/container_drivers/distributed_drivers/__init__.py +14 -0
  239. sagemaker/core/modules/train/container_drivers/distributed_drivers/basic_script_driver.py +81 -0
  240. sagemaker/core/modules/train/container_drivers/distributed_drivers/mpi_driver.py +123 -0
  241. sagemaker/core/modules/train/container_drivers/distributed_drivers/mpi_utils.py +302 -0
  242. sagemaker/core/modules/train/container_drivers/distributed_drivers/torchrun_driver.py +129 -0
  243. sagemaker/core/modules/train/container_drivers/scripts/__init__.py +14 -0
  244. sagemaker/core/modules/train/container_drivers/scripts/environment.py +305 -0
  245. sagemaker/core/modules/train/sm_recipes/__init__.py +0 -0
  246. sagemaker/core/modules/train/sm_recipes/utils.py +330 -0
  247. sagemaker/core/modules/types.py +19 -0
  248. sagemaker/core/modules/utils.py +194 -0
  249. sagemaker/core/network.py +185 -0
  250. sagemaker/core/parameter.py +173 -0
  251. sagemaker/core/payloads.py +185 -0
  252. sagemaker/core/processing.py +1599 -0
  253. sagemaker/core/remote_function/__init__.py +19 -0
  254. sagemaker/core/remote_function/checkpoint_location.py +47 -0
  255. sagemaker/core/remote_function/client.py +1310 -0
  256. sagemaker/core/remote_function/core/__init__.py +0 -0
  257. sagemaker/core/remote_function/core/_custom_dispatch_table.py +72 -0
  258. sagemaker/core/remote_function/core/pipeline_variables.py +347 -0
  259. sagemaker/core/remote_function/core/serialization.py +410 -0
  260. sagemaker/core/remote_function/core/stored_function.py +223 -0
  261. sagemaker/core/remote_function/custom_file_filter.py +128 -0
  262. sagemaker/core/remote_function/errors.py +102 -0
  263. sagemaker/core/remote_function/invoke_function.py +167 -0
  264. sagemaker/core/remote_function/job.py +2121 -0
  265. sagemaker/core/remote_function/logging_config.py +38 -0
  266. sagemaker/core/remote_function/runtime_environment/__init__.py +14 -0
  267. sagemaker/core/remote_function/runtime_environment/bootstrap_runtime_environment.py +605 -0
  268. sagemaker/core/remote_function/runtime_environment/mpi_utils_remote.py +252 -0
  269. sagemaker/core/remote_function/runtime_environment/runtime_environment_manager.py +554 -0
  270. sagemaker/core/remote_function/runtime_environment/spark_app.py +18 -0
  271. sagemaker/core/remote_function/spark_config.py +149 -0
  272. sagemaker/core/resource_requirements.py +168 -0
  273. {sagemaker_core/main → sagemaker/core}/resources.py +19098 -10895
  274. sagemaker/core/s3/__init__.py +41 -0
  275. sagemaker/core/s3/client.py +367 -0
  276. sagemaker/core/s3/utils.py +175 -0
  277. sagemaker/core/script_uris.py +93 -0
  278. sagemaker/core/serializers/__init__.py +11 -0
  279. sagemaker/core/serializers/base.py +510 -0
  280. sagemaker/core/serializers/implementations.py +159 -0
  281. sagemaker/core/serializers/utils.py +223 -0
  282. sagemaker/core/serverless_inference_config.py +63 -0
  283. sagemaker/core/session_settings.py +55 -0
  284. sagemaker/core/shapes/__init__.py +3 -0
  285. sagemaker/core/shapes/model_card_shapes.py +159 -0
  286. {sagemaker_core/main → sagemaker/core/shapes}/shapes.py +5810 -1806
  287. sagemaker/core/spark/__init__.py +16 -0
  288. sagemaker/core/spark/defaults.py +16 -0
  289. sagemaker/core/spark/processing.py +1380 -0
  290. sagemaker/core/telemetry/__init__.py +23 -0
  291. sagemaker/core/telemetry/constants.py +82 -0
  292. sagemaker/core/telemetry/telemetry_logging.py +285 -0
  293. sagemaker/core/tools/__init__.py +1 -0
  294. {sagemaker_core → sagemaker/core}/tools/codegen.py +4 -4
  295. {sagemaker_core → sagemaker/core}/tools/constants.py +23 -15
  296. {sagemaker_core → sagemaker/core}/tools/data_extractor.py +1 -1
  297. {sagemaker_core → sagemaker/core}/tools/method.py +1 -1
  298. sagemaker/core/tools/model_card/generate_model_card_from_schema.py +562 -0
  299. {sagemaker_core → sagemaker/core}/tools/resources_codegen.py +165 -98
  300. {sagemaker_core → sagemaker/core}/tools/resources_extractor.py +5 -13
  301. {sagemaker_core → sagemaker/core}/tools/shapes_codegen.py +16 -17
  302. {sagemaker_core → sagemaker/core}/tools/shapes_extractor.py +29 -67
  303. {sagemaker_core → sagemaker/core}/tools/templates.py +39 -17
  304. sagemaker/core/training/__init__.py +14 -0
  305. sagemaker/core/training/configs.py +345 -0
  306. sagemaker/core/training/constants.py +37 -0
  307. sagemaker/core/training/utils.py +77 -0
  308. sagemaker/core/training_compiler/__init__.py +16 -0
  309. sagemaker/core/training_compiler/config.py +197 -0
  310. sagemaker/core/training_compiler_config.py +197 -0
  311. sagemaker/core/transformer.py +793 -0
  312. sagemaker/core/user_agent.py +76 -0
  313. sagemaker/core/utilities/__init__.py +24 -0
  314. sagemaker/core/utilities/cache.py +169 -0
  315. sagemaker/core/utilities/search_expression.py +133 -0
  316. sagemaker/core/utils/__init__.py +48 -0
  317. sagemaker/core/utils/code_injection/__init__.py +0 -0
  318. {sagemaker_core/main → sagemaker/core/utils}/code_injection/codec.py +2 -2
  319. {sagemaker_core/main → sagemaker/core/utils}/code_injection/shape_dag.py +5979 -176
  320. {sagemaker_core/main → sagemaker/core/utils}/exceptions.py +8 -8
  321. sagemaker_core/main/default_configs_helper.py → sagemaker/core/utils/intelligent_defaults_helper.py +5 -6
  322. {sagemaker_core/main → sagemaker/core/utils}/logs.py +1 -2
  323. {sagemaker_core/main → sagemaker/core/utils}/utils.py +27 -22
  324. sagemaker/core/workflow/__init__.py +152 -0
  325. sagemaker/core/workflow/conditions.py +313 -0
  326. sagemaker/core/workflow/entities.py +58 -0
  327. sagemaker/core/workflow/execution_variables.py +89 -0
  328. sagemaker/core/workflow/functions.py +193 -0
  329. sagemaker/core/workflow/parameters.py +222 -0
  330. sagemaker/core/workflow/pipeline_context.py +394 -0
  331. sagemaker/core/workflow/pipeline_definition_config.py +31 -0
  332. sagemaker/core/workflow/properties.py +285 -0
  333. sagemaker/core/workflow/step_outputs.py +65 -0
  334. sagemaker/core/workflow/utilities.py +514 -0
  335. sagemaker/lineage/__init__.py +33 -0
  336. sagemaker/lineage/action.py +28 -0
  337. sagemaker/lineage/artifact.py +28 -0
  338. sagemaker/lineage/context.py +28 -0
  339. sagemaker/lineage/lineage_trial_component.py +28 -0
  340. {sagemaker_core-1.0.62.dist-info → sagemaker_core-2.3.1.dist-info}/METADATA +28 -9
  341. sagemaker_core-2.3.1.dist-info/RECORD +351 -0
  342. sagemaker_core-2.3.1.dist-info/top_level.txt +1 -0
  343. sagemaker_core/_version.py +0 -3
  344. sagemaker_core/helper/session_helper.py +0 -769
  345. sagemaker_core/resources/__init__.py +0 -1
  346. sagemaker_core/shapes/__init__.py +0 -1
  347. sagemaker_core/tools/__init__.py +0 -1
  348. sagemaker_core-1.0.62.dist-info/RECORD +0 -35
  349. sagemaker_core-1.0.62.dist-info/top_level.txt +0 -1
  350. {sagemaker_core → sagemaker/core/helper}/__init__.py +0 -0
  351. {sagemaker_core/helper → sagemaker/core/jumpstart/factory}/__init__.py +0 -0
  352. {sagemaker_core/main → sagemaker/core/jumpstart/hub}/__init__.py +0 -0
  353. {sagemaker_core/main/code_injection → sagemaker/core/modules/local_core}/__init__.py +0 -0
  354. {sagemaker_core/main → sagemaker/core/utils}/code_injection/base.py +0 -0
  355. {sagemaker_core/main → sagemaker/core/utils}/code_injection/constants.py +0 -0
  356. {sagemaker_core/main → sagemaker/core/utils}/user_agent.py +0 -0
  357. {sagemaker_core-1.0.62.dist-info → sagemaker_core-2.3.1.dist-info}/WHEEL +0 -0
  358. {sagemaker_core-1.0.62.dist-info → sagemaker_core-2.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,554 @@
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
+ """SageMaker runtime environment module. This must be kept independent of SageMaker PySDK"""
14
+
15
+ from __future__ import absolute_import
16
+
17
+
18
+ import logging
19
+ import sys
20
+ import shlex
21
+ import os
22
+ import subprocess
23
+ import time
24
+ import dataclasses
25
+ import json
26
+
27
+
28
+ class _UTCFormatter(logging.Formatter):
29
+ """Class that overrides the default local time provider in log formatter."""
30
+
31
+ converter = time.gmtime
32
+
33
+
34
+ def get_logger():
35
+ """Return a logger with the name 'sagemaker'"""
36
+ sagemaker_logger = logging.getLogger("sagemaker.remote_function")
37
+ if len(sagemaker_logger.handlers) == 0:
38
+ sagemaker_logger.setLevel(logging.INFO)
39
+ handler = logging.StreamHandler()
40
+ formatter = _UTCFormatter("%(asctime)s %(name)s %(levelname)-8s %(message)s")
41
+ handler.setFormatter(formatter)
42
+ sagemaker_logger.addHandler(handler)
43
+ # don't stream logs with the root logger handler
44
+ sagemaker_logger.propagate = 0
45
+
46
+ return sagemaker_logger
47
+
48
+
49
+ logger = get_logger()
50
+
51
+
52
+ @dataclasses.dataclass
53
+ class _DependencySettings:
54
+ """Dependency settings for the remote function.
55
+
56
+ Instructs the runtime environment script on how to handle dependencies.
57
+ If ``dependency_file`` is set, the runtime environment script will attempt
58
+ to install the dependencies. If ``dependency_file`` is not set, the runtime
59
+ environment script will assume no dependencies are required.
60
+ """
61
+
62
+ dependency_file: str = None
63
+
64
+ def to_string(self):
65
+ """Converts the dependency settings to a string."""
66
+ return json.dumps(dataclasses.asdict(self))
67
+
68
+ @staticmethod
69
+ def from_string(dependency_settings_string):
70
+ """Converts a json string to dependency settings.
71
+
72
+ Args:
73
+ dependency_settings_string (str): The json string to convert.
74
+ """
75
+ if dependency_settings_string is None:
76
+ return None
77
+ dependency_settings_dict = json.loads(dependency_settings_string)
78
+ return _DependencySettings(dependency_settings_dict.get("dependency_file"))
79
+
80
+ @staticmethod
81
+ def from_dependency_file_path(dependency_file_path):
82
+ """Converts a dependency file path to dependency settings.
83
+
84
+ Args:
85
+ dependency_file_path (str): The path to the dependency file.
86
+ """
87
+ if dependency_file_path is None:
88
+ return _DependencySettings()
89
+ if dependency_file_path == "auto_capture":
90
+ return _DependencySettings("env_snapshot.yml")
91
+ return _DependencySettings(os.path.basename(dependency_file_path))
92
+
93
+
94
+ class RuntimeEnvironmentManager:
95
+ """Runtime Environment Manager class to manage runtime environment."""
96
+
97
+ def _validate_path(self, path: str) -> str:
98
+ """Validate and sanitize file path to prevent path traversal attacks.
99
+
100
+ Args:
101
+ path (str): The file path to validate
102
+
103
+ Returns:
104
+ str: The validated absolute path
105
+
106
+ Raises:
107
+ ValueError: If the path is invalid or contains suspicious patterns
108
+ """
109
+ if not path:
110
+ raise ValueError("Path cannot be empty")
111
+
112
+ # Get absolute path to prevent path traversal
113
+ abs_path = os.path.abspath(path)
114
+
115
+ # Check for null bytes (common in path traversal attacks)
116
+ if '\x00' in path:
117
+ raise ValueError(f"Invalid path contains null byte: {path}")
118
+
119
+ return abs_path
120
+
121
+ def _validate_env_name(self, env_name: str) -> None:
122
+ """Validate conda environment name to prevent command injection.
123
+
124
+ Args:
125
+ env_name (str): The environment name to validate
126
+
127
+ Raises:
128
+ ValueError: If the environment name contains invalid characters
129
+ """
130
+ if not env_name:
131
+ raise ValueError("Environment name cannot be empty")
132
+
133
+ # Allow only alphanumeric, underscore, and hyphen
134
+ import re
135
+ if not re.match(r'^[a-zA-Z0-9_-]+$', env_name):
136
+ raise ValueError(
137
+ f"Invalid environment name '{env_name}'. "
138
+ "Only alphanumeric characters, underscores, and hyphens are allowed."
139
+ )
140
+
141
+ def snapshot(self, dependencies: str = None) -> str:
142
+ """Creates snapshot of the user's environment
143
+
144
+ If a req.txt or conda.yml file is provided, it verifies their existence and
145
+ returns the local file path
146
+ If ``auto_capture`` is set, this method will take the snapshot of
147
+ user's dependencies installed in the local runtime.
148
+ Current support for ``auto_capture``:
149
+ * conda env, generate a yml file and return it's local path
150
+
151
+ Args:
152
+ dependencies (str): Local path where dependencies file exists.
153
+
154
+ Returns:
155
+ file path of the existing or generated dependencies file
156
+ """
157
+
158
+ # No additional dependencies specified
159
+ if dependencies is None:
160
+ return None
161
+
162
+ if dependencies == "auto_capture":
163
+ return self._capture_from_local_runtime()
164
+
165
+ # Dependencies specified as either req.txt or conda_env.yml
166
+ if (
167
+ dependencies.endswith(".txt")
168
+ or dependencies.endswith(".yml")
169
+ or dependencies.endswith(".yaml")
170
+ ):
171
+ self._is_file_exists(dependencies)
172
+ return dependencies
173
+
174
+ raise ValueError(f'Invalid dependencies provided: "{dependencies}"')
175
+
176
+ def _capture_from_local_runtime(self) -> str:
177
+ """Generates dependencies list from the user's local runtime.
178
+
179
+ Raises RuntimeEnvironmentError if not able to.
180
+
181
+ Currently supports: conda environments
182
+ """
183
+
184
+ # Try to capture dependencies from the conda environment, if any.
185
+ conda_env_name = self._get_active_conda_env_name()
186
+ conda_env_prefix = self._get_active_conda_env_prefix()
187
+ if conda_env_name:
188
+ logger.info("Found conda_env_name: '%s'", conda_env_name)
189
+ elif conda_env_prefix:
190
+ logger.info("Found conda_env_prefix: '%s'", conda_env_prefix)
191
+ else:
192
+ raise ValueError("No conda environment seems to be active.")
193
+
194
+ if conda_env_name == "base":
195
+ logger.warning(
196
+ "We recommend using an environment other than base to "
197
+ "isolate your project dependencies from conda dependencies"
198
+ )
199
+
200
+ local_dependencies_path = os.path.join(os.getcwd(), "env_snapshot.yml")
201
+ self._export_conda_env_from_prefix(conda_env_prefix, local_dependencies_path)
202
+
203
+ return local_dependencies_path
204
+
205
+ def _get_active_conda_env_prefix(self) -> str:
206
+ """Returns the conda prefix from the set environment variable. None otherwise."""
207
+ return os.getenv("CONDA_PREFIX")
208
+
209
+ def _get_active_conda_env_name(self) -> str:
210
+ """Returns the conda environment name from the set environment variable. None otherwise."""
211
+ return os.getenv("CONDA_DEFAULT_ENV")
212
+
213
+ def bootstrap(
214
+ self, local_dependencies_file: str, client_python_version: str, conda_env: str = None
215
+ ):
216
+ """Bootstraps the runtime environment by installing the additional dependencies if any.
217
+
218
+ Args:
219
+ local_dependencies_file (str): path where dependencies file exists.
220
+ conda_env (str): conda environment to be activated. Default is None.
221
+
222
+ Returns: None
223
+ """
224
+
225
+ if local_dependencies_file.endswith(".txt"):
226
+ if conda_env:
227
+ self._install_req_txt_in_conda_env(conda_env, local_dependencies_file)
228
+ self._write_conda_env_to_file(conda_env)
229
+
230
+ else:
231
+ self._install_requirements_txt(local_dependencies_file, _python_executable())
232
+
233
+ elif local_dependencies_file.endswith(".yml") or local_dependencies_file.endswith(".yaml"):
234
+ if conda_env:
235
+ self._update_conda_env(conda_env, local_dependencies_file)
236
+ else:
237
+ conda_env = "sagemaker-runtime-env"
238
+ self._create_conda_env(conda_env, local_dependencies_file)
239
+ self._validate_python_version(client_python_version, conda_env)
240
+ self._write_conda_env_to_file(conda_env)
241
+
242
+ def run_pre_exec_script(self, pre_exec_script_path: str):
243
+ """Runs script of pre-execution commands if existing.
244
+
245
+ Args:
246
+ pre_exec_script_path (str): Path to pre-execution command script file.
247
+ """
248
+ if os.path.isfile(pre_exec_script_path):
249
+ logger.info("Running pre-execution commands in '%s'", pre_exec_script_path)
250
+ return_code, error_logs = _run_pre_execution_command_script(pre_exec_script_path)
251
+
252
+ if return_code:
253
+ error_message = (
254
+ f"Encountered error while running pre-execution commands. Reason: {error_logs}"
255
+ )
256
+ raise RuntimeEnvironmentError(error_message)
257
+ else:
258
+ logger.info(
259
+ "'%s' does not exist. Assuming no pre-execution commands to run",
260
+ pre_exec_script_path,
261
+ )
262
+
263
+ def change_dir_permission(self, dirs: list, new_permission: str):
264
+ """Change the permission of given directories
265
+
266
+ Args:
267
+ dirs (list[str]): A list of directories for permission update.
268
+ new_permission (str): The new permission for the given directories.
269
+ """
270
+
271
+ _ERROR_MSG_PREFIX = "Failed to change directory permissions due to: "
272
+ command = ["sudo", "chmod", "-R", new_permission] + dirs
273
+ logger.info("Executing '%s'.", " ".join(command))
274
+
275
+ try:
276
+ subprocess.run(command, check=True, stderr=subprocess.PIPE)
277
+ except subprocess.CalledProcessError as called_process_err:
278
+ err_msg = called_process_err.stderr.decode("utf-8")
279
+ raise RuntimeEnvironmentError(f"{_ERROR_MSG_PREFIX} {err_msg}")
280
+ except FileNotFoundError as file_not_found_err:
281
+ if "[Errno 2] No such file or directory: 'sudo'" in str(file_not_found_err):
282
+ raise RuntimeEnvironmentError(
283
+ f"{_ERROR_MSG_PREFIX} {file_not_found_err}. "
284
+ "Please contact the image owner to install 'sudo' in the job container "
285
+ "and provide sudo privilege to the container user."
286
+ )
287
+ raise RuntimeEnvironmentError(file_not_found_err)
288
+
289
+ def _is_file_exists(self, dependencies):
290
+ """Check whether the dependencies file exists at the given location.
291
+
292
+ Raises error if not
293
+ """
294
+ if not os.path.isfile(dependencies):
295
+ raise ValueError(f'No dependencies file named "{dependencies}" was found.')
296
+
297
+ def _install_requirements_txt(self, local_path, python_executable):
298
+ """Install requirements.txt file"""
299
+ # Validate path to prevent command injection
300
+ validated_path = self._validate_path(local_path)
301
+ cmd = [python_executable, "-m", "pip", "install", "-r", validated_path, "-U"]
302
+ logger.info("Running command: '%s' in the dir: '%s' ", " ".join(cmd), os.getcwd())
303
+ _run_shell_cmd(cmd)
304
+ logger.info("Command %s ran successfully", " ".join(cmd))
305
+
306
+ def _create_conda_env(self, env_name, local_path):
307
+ """Create conda env using conda yml file"""
308
+ # Validate inputs to prevent command injection
309
+ self._validate_env_name(env_name)
310
+ validated_path = self._validate_path(local_path)
311
+
312
+ cmd = [self._get_conda_exe(), "env", "create", "-n", env_name, "--file", validated_path]
313
+ logger.info("Creating conda environment %s using: %s.", env_name, " ".join(cmd))
314
+ _run_shell_cmd(cmd)
315
+ logger.info("Conda environment %s created successfully.", env_name)
316
+
317
+ def _install_req_txt_in_conda_env(self, env_name, local_path):
318
+ """Install requirements.txt in the given conda environment"""
319
+ # Validate inputs to prevent command injection
320
+ self._validate_env_name(env_name)
321
+ validated_path = self._validate_path(local_path)
322
+
323
+ cmd = [self._get_conda_exe(), "run", "-n", env_name, "pip", "install", "-r", validated_path, "-U"]
324
+ logger.info("Activating conda env and installing requirements: %s", " ".join(cmd))
325
+ _run_shell_cmd(cmd)
326
+ logger.info("Requirements installed successfully in conda env %s", env_name)
327
+
328
+ def _update_conda_env(self, env_name, local_path):
329
+ """Update conda env using conda yml file"""
330
+ # Validate inputs to prevent command injection
331
+ self._validate_env_name(env_name)
332
+ validated_path = self._validate_path(local_path)
333
+
334
+ cmd = [self._get_conda_exe(), "env", "update", "-n", env_name, "--file", validated_path]
335
+ logger.info("Updating conda env: %s", " ".join(cmd))
336
+ _run_shell_cmd(cmd)
337
+ logger.info("Conda env %s updated succesfully", env_name)
338
+
339
+ def _export_conda_env_from_prefix(self, prefix, local_path):
340
+ """Export the conda env to a conda yml file"""
341
+ # Validate inputs to prevent command injection
342
+ validated_prefix = self._validate_path(prefix)
343
+ validated_path = self._validate_path(local_path)
344
+
345
+ cmd = [self._get_conda_exe(), "env", "export", "-p", validated_prefix, "--no-builds"]
346
+ logger.info("Exporting conda environment: %s", " ".join(cmd))
347
+
348
+ # Capture output and write to file instead of using shell redirection
349
+ try:
350
+ process = subprocess.Popen(
351
+ cmd,
352
+ stdout=subprocess.PIPE,
353
+ stderr=subprocess.PIPE,
354
+ shell=False
355
+ )
356
+ output, error_output = process.communicate()
357
+ return_code = process.wait()
358
+
359
+ if return_code:
360
+ error_message = f"Encountered error while running command '{' '.join(cmd)}'. Reason: {error_output.decode('utf-8')}"
361
+ raise RuntimeEnvironmentError(error_message)
362
+
363
+ # Write the captured output to the file
364
+ with open(validated_path, 'w') as f:
365
+ f.write(output.decode('utf-8'))
366
+
367
+ logger.info("Conda environment %s exported successfully", validated_prefix)
368
+ except Exception as e:
369
+ raise RuntimeEnvironmentError(f"Failed to export conda environment: {str(e)}")
370
+
371
+ def _write_conda_env_to_file(self, env_name):
372
+ """Writes conda env to the text file"""
373
+
374
+ file_name = "remote_function_conda_env.txt"
375
+ file_path = os.path.join(os.getcwd(), file_name)
376
+ with open(file_path, "w") as output_file:
377
+ output_file.write(env_name)
378
+
379
+ def _get_conda_exe(self):
380
+ """Checks whether conda or mamba is available to use"""
381
+
382
+ if not subprocess.Popen(["which", "mamba"]).wait():
383
+ return "mamba"
384
+ if not subprocess.Popen(["which", "conda"]).wait():
385
+ return "conda"
386
+ raise ValueError("Neither conda nor mamba is installed on the image")
387
+
388
+ def _python_version_in_conda_env(self, env_name):
389
+ """Returns python version inside a conda environment"""
390
+ cmd = f"{self._get_conda_exe()} run -n {env_name} python --version"
391
+ try:
392
+ output = (
393
+ subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT)
394
+ .decode("utf-8")
395
+ .strip()
396
+ )
397
+ # convert 'Python 3.7.16' to [3, 7, 16]
398
+ version = output.split("Python ")[1].split(".")
399
+ return version[0] + "." + version[1]
400
+ except subprocess.CalledProcessError as e:
401
+ raise RuntimeEnvironmentError(e.output)
402
+
403
+ def _current_python_version(self):
404
+ """Returns the current python version where program is running"""
405
+
406
+ return f"{sys.version_info.major}.{sys.version_info.minor}".strip()
407
+
408
+ def _current_sagemaker_pysdk_version(self):
409
+ """Returns the current sagemaker python sdk version where program is running"""
410
+ try:
411
+ from importlib import metadata
412
+
413
+ return metadata.version("sagemaker")
414
+ except Exception:
415
+ return "3.0.0.dev0" # Development version fallback
416
+
417
+ def _validate_python_version(self, client_python_version: str, conda_env: str = None):
418
+ """Validate the python version
419
+
420
+ Validates if the python version where remote function runs
421
+ matches the one used on client side.
422
+ """
423
+ if conda_env:
424
+ job_python_version = self._python_version_in_conda_env(conda_env)
425
+ else:
426
+ job_python_version = self._current_python_version()
427
+ if client_python_version.strip() != job_python_version.strip():
428
+ raise RuntimeEnvironmentError(
429
+ f"Python version found in the container is '{job_python_version}' which "
430
+ f"does not match python version '{client_python_version}' on the local client. "
431
+ f"Please make sure that the python version used in the training container "
432
+ f"is same as the local python version."
433
+ )
434
+
435
+ def _validate_sagemaker_pysdk_version(self, client_sagemaker_pysdk_version):
436
+ """Validate the sagemaker python sdk version
437
+
438
+ Validates if the sagemaker python sdk version where remote function runs
439
+ matches the one used on client side.
440
+ Otherwise, log a warning to call out that unexpected behaviors
441
+ may occur in this case.
442
+ """
443
+ job_sagemaker_pysdk_version = self._current_sagemaker_pysdk_version()
444
+ if (
445
+ client_sagemaker_pysdk_version
446
+ and client_sagemaker_pysdk_version != job_sagemaker_pysdk_version
447
+ ):
448
+ logger.warning(
449
+ "Inconsistent sagemaker versions found: "
450
+ "sagemaker python sdk version found in the container is "
451
+ "'%s' which does not match the '%s' on the local client. "
452
+ "Please make sure that the sagemaker version used in the training container "
453
+ "is the same as the local sagemaker version in case of unexpected behaviors.",
454
+ job_sagemaker_pysdk_version,
455
+ client_sagemaker_pysdk_version,
456
+ )
457
+
458
+
459
+ def _run_and_get_output_shell_cmd(cmd: str) -> str:
460
+ """Run and return the output of the given shell command"""
461
+ return subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT).decode("utf-8")
462
+
463
+
464
+ def _run_pre_execution_command_script(script_path: str):
465
+ """This method runs a given shell script using subprocess
466
+
467
+ Raises RuntimeEnvironmentError if the shell script fails
468
+ """
469
+ current_dir = os.path.dirname(script_path)
470
+
471
+ process = subprocess.Popen(
472
+ ["/bin/bash", "-eu", script_path],
473
+ stdout=subprocess.PIPE,
474
+ stderr=subprocess.PIPE,
475
+ cwd=current_dir,
476
+ )
477
+
478
+ _log_output(process)
479
+ error_logs = _log_error(process)
480
+ return_code = process.wait()
481
+
482
+ return return_code, error_logs
483
+
484
+
485
+ def _run_shell_cmd(cmd: list):
486
+ """This method runs a given shell command using subprocess
487
+
488
+ Args:
489
+ cmd (list): Command and arguments as a list (e.g., ['pip', 'install', '-r', 'requirements.txt'])
490
+
491
+ Raises:
492
+ RuntimeEnvironmentError: If the command fails
493
+ ValueError: If cmd is not a list
494
+ """
495
+ if not isinstance(cmd, list):
496
+ raise ValueError("Command must be a list of arguments for security reasons")
497
+
498
+ process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
499
+
500
+ _log_output(process)
501
+ error_logs = _log_error(process)
502
+ return_code = process.wait()
503
+ if return_code:
504
+ error_message = f"Encountered error while running command '{' '.join(cmd)}'. Reason: {error_logs}"
505
+ raise RuntimeEnvironmentError(error_message)
506
+
507
+
508
+ def _log_output(process):
509
+ """This method takes in Popen process and logs the output of that process"""
510
+ with process.stdout as pipe:
511
+ for line in iter(pipe.readline, b""):
512
+ logger.info(str(line, "UTF-8"))
513
+
514
+
515
+ def _log_error(process):
516
+ """This method takes in Popen process and logs the error of that process.
517
+
518
+ Returns those logs as a string
519
+ """
520
+
521
+ error_logs = ""
522
+ with process.stderr as pipe:
523
+ for line in iter(pipe.readline, b""):
524
+ error_str = str(line, "UTF-8")
525
+ if "ERROR:" in error_str:
526
+ logger.error(error_str)
527
+ else:
528
+ logger.warning(error_str)
529
+ error_logs = error_logs + error_str
530
+
531
+ return error_logs
532
+
533
+
534
+ def _python_executable():
535
+ """Return the real path for the Python executable, if it exists.
536
+
537
+ Return RuntimeEnvironmentError otherwise.
538
+
539
+ Returns:
540
+ (str): The real path of the current Python executable.
541
+ """
542
+ if not sys.executable:
543
+ raise RuntimeEnvironmentError(
544
+ "Failed to retrieve the path for the Python executable binary"
545
+ )
546
+ return sys.executable
547
+
548
+
549
+ class RuntimeEnvironmentError(Exception):
550
+ """The base exception class for bootstrap env excepitons"""
551
+
552
+ def __init__(self, message):
553
+ self.message = message
554
+ super().__init__(self.message)
@@ -0,0 +1,18 @@
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
+ """This is a simple scrip of spark which invokes the pickled remote function"""
14
+ from __future__ import absolute_import
15
+
16
+ from sagemaker.core.remote_function import invoke_function
17
+
18
+ invoke_function.main()