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 model builder dependency managing module.
14
-
15
- This must be kept independent of SageMaker PySDK
16
- """
17
-
18
- from __future__ import absolute_import
19
-
20
- from pathlib import Path
21
1
import logging
22
2
import subprocess
23
3
import sys
24
4
import re
5
+ from pathlib import Path
25
6
26
7
_SUPPORTED_SUFFIXES = [".txt" ]
27
- # TODO : Move PKL_FILE_NAME to common location
28
8
PKL_FILE_NAME = "serve.pkl"
29
9
30
10
logger = logging .getLogger (__name__ )
31
11
32
12
33
13
def capture_dependencies (dependencies : dict , work_dir : Path , capture_all : bool = False ):
34
- """Placeholder docstring"""
14
+ """Capture dependencies and print output."""
15
+ print (f"Capturing dependencies: { dependencies } , work_dir: { work_dir } , capture_all: { capture_all } " )
16
+
35
17
path = work_dir .joinpath ("requirements.txt" )
36
18
if "auto" in dependencies and dependencies ["auto" ]:
37
19
command = [
@@ -45,6 +27,8 @@ def capture_dependencies(dependencies: dict, work_dir: Path, capture_all: bool =
45
27
46
28
if capture_all :
47
29
command .append ("--capture_all" )
30
+
31
+ print (f"Running subprocess with command: { command } " )
48
32
49
33
subprocess .run (
50
34
command ,
@@ -55,62 +39,83 @@ def capture_dependencies(dependencies: dict, work_dir: Path, capture_all: bool =
55
39
with open (path , "r" ) as f :
56
40
autodetect_depedencies = f .read ().splitlines ()
57
41
autodetect_depedencies .append ("sagemaker[huggingface]>=2.199" )
42
+ print (f"Auto-detected dependencies: { autodetect_depedencies } " )
58
43
else :
59
44
autodetect_depedencies = ["sagemaker[huggingface]>=2.199" ]
45
+ print (f"No auto-detection, using default dependencies: { autodetect_depedencies } " )
60
46
61
47
module_version_dict = _parse_dependency_list (autodetect_depedencies )
48
+ print (f"Parsed auto-detected dependencies: { module_version_dict } " )
62
49
63
50
if "requirements" in dependencies :
64
51
module_version_dict = _process_customer_provided_requirements (
65
52
requirements_file = dependencies ["requirements" ], module_version_dict = module_version_dict
66
53
)
54
+ print (f"After processing customer-provided requirements: { module_version_dict } " )
55
+
67
56
if "custom" in dependencies :
68
57
module_version_dict = _process_custom_dependencies (
69
58
custom_dependencies = dependencies .get ("custom" ), module_version_dict = module_version_dict
70
59
)
60
+ print (f"After processing custom dependencies: { module_version_dict } " )
61
+
71
62
with open (path , "w" ) as f :
72
63
for module , version in module_version_dict .items ():
73
64
f .write (f"{ module } { version } \n " )
65
+ print (f"Final dependencies written to { path } " )
74
66
75
67
76
68
def _process_custom_dependencies (custom_dependencies : list , module_version_dict : dict ):
77
- """Placeholder docstring"""
69
+ """Process custom dependencies and print output."""
70
+ print (f"Processing custom dependencies: { custom_dependencies } " )
71
+
78
72
custom_module_version_dict = _parse_dependency_list (custom_dependencies )
73
+ print (f"Parsed custom dependencies: { custom_module_version_dict } " )
74
+
79
75
module_version_dict .update (custom_module_version_dict )
76
+ print (f"Updated module_version_dict with custom dependencies: { module_version_dict } " )
77
+
80
78
return module_version_dict
81
79
82
80
83
81
def _process_customer_provided_requirements (requirements_file : str , module_version_dict : dict ):
84
- """Placeholder docstring"""
82
+ """Process customer-provided requirements and print output."""
83
+ print (f"Processing customer-provided requirements from file: { requirements_file } " )
84
+
85
85
requirements_file = Path (requirements_file )
86
86
if not requirements_file .is_file () or not _is_valid_requirement_file (requirements_file ):
87
87
raise Exception (f"Path: { requirements_file } to requirements.txt doesn't exist" )
88
+
88
89
logger .debug ("Packaging provided requirements.txt from %s" , requirements_file )
89
90
with open (requirements_file , "r" ) as f :
90
91
custom_dependencies = f .read ().splitlines ()
92
+
93
+ print (f"Customer-provided dependencies: { custom_dependencies } " )
91
94
92
95
module_version_dict .update (_parse_dependency_list (custom_dependencies ))
96
+ print (f"Updated module_version_dict with customer-provided requirements: { module_version_dict } " )
97
+
93
98
return module_version_dict
94
99
95
100
96
101
def _is_valid_requirement_file (path ):
97
- """Placeholder docstring"""
98
- # In the future, we can also check the if the content of customer provided file has valid format
102
+ """Check if the requirements file is valid and print result."""
103
+ print (f"Validating requirement file: { path } " )
104
+
99
105
for suffix in _SUPPORTED_SUFFIXES :
100
106
if path .name .endswith (suffix ):
107
+ print (f"File { path } is valid with suffix { suffix } " )
101
108
return True
109
+
110
+ print (f"File { path } is not valid" )
102
111
return False
103
112
104
113
105
114
def _parse_dependency_list (depedency_list : list ) -> dict :
106
- """Placeholder docstring"""
107
-
108
- # Divide a string into 2 part, first part is the module name
109
- # and second part is its version constraint or the url
110
- # checkout tests/unit/sagemaker/serve/detector/test_dependency_manager.py
111
- # for examples
115
+ """Parse the dependency list and print output."""
116
+ print (f"Parsing dependency list: { depedency_list } " )
117
+
112
118
pattern = r"^([\w.-]+)(@[^,\n]+|((?:[<>=!~]=?[\w.*-]+,?)+)?)$"
113
-
114
119
module_version_dict = {}
115
120
116
121
for dependency in depedency_list :
@@ -119,10 +124,10 @@ def _parse_dependency_list(depedency_list: list) -> dict:
119
124
match = re .match (pattern , dependency )
120
125
if match :
121
126
package = match .group (1 )
122
- # Group 2 is either a URL or version constraint, if present
123
127
url_or_version = match .group (2 ) if match .group (2 ) else ""
124
128
module_version_dict .update ({package : url_or_version })
125
129
else :
126
130
module_version_dict .update ({dependency : "" })
127
-
131
+
132
+ print (f"Parsed module_version_dict: { module_version_dict } " )
128
133
return module_version_dict
0 commit comments