@@ -1067,22 +1067,61 @@ def push(self, project_id: int):
10671067 """
10681068 project_dir = f"{ OPENLAYER_DIR } /{ project_id } /staging"
10691069
1070+ if self ._ready_for_push (project_dir = project_dir ):
1071+ with open (
1072+ f"{ project_dir } /commit.yaml" , "r" , encoding = "UTF-8"
1073+ ) as commit_file :
1074+ commit = yaml .safe_load (commit_file )
1075+
1076+ # Tar the project's staging area
1077+ with tempfile .TemporaryDirectory () as tmp_dir :
1078+ tar_file_path = os .path .join (tmp_dir , "tarfile" )
1079+ with tarfile .open (tar_file_path , mode = "w:gz" ) as tar :
1080+ tar .add (project_dir , arcname = os .path .basename (project_dir ))
1081+
1082+ # Upload the tar file
1083+ print (
1084+ "Pushing changes to the platform with the commit message: \n "
1085+ f"\t - Message: { commit ['message' ]} \n "
1086+ f"\t - Date: { commit ['date' ]} "
1087+ )
1088+ payload = {"commit" : {"message" : commit ["message" ]}}
1089+ self .api .upload (
1090+ endpoint = f"projects/{ project_id } /versions" ,
1091+ file_path = tar_file_path ,
1092+ object_name = "tarfile" ,
1093+ body = payload ,
1094+ )
1095+
1096+ self ._post_push_cleanup (project_dir = project_dir )
1097+ print ("Pushed!" )
1098+
1099+ def _ready_for_push (self , project_dir : str ) -> bool :
1100+ """Checks if the project's staging area is ready to be pushed to the platform.
1101+
1102+ Parameters
1103+ ----------
1104+ project_dir : str
1105+ Directory path to the project's staging area.
1106+
1107+ Returns
1108+ -------
1109+ bool
1110+ Indicates whether the project's staging area is ready to be pushed to the platform.
1111+ """
10701112 if not os .listdir (project_dir ):
10711113 print (
10721114 "The staging area is clean and there is nothing committed to push. "
10731115 "Please add model and/or datasets first, and then commit before pushing."
10741116 )
1075- return
1117+ return False
10761118
10771119 if not os .path .exists (f"{ project_dir } /commit.yaml" ):
10781120 print (
10791121 "There are resources staged, but you haven't committed them yet. "
10801122 "Please commit before pushing"
10811123 )
1082- return
1083-
1084- with open (f"{ project_dir } /commit.yaml" , "r" , encoding = "UTF-8" ) as commit_file :
1085- commit = yaml .safe_load (commit_file )
1124+ return False
10861125
10871126 # Validate bundle resources
10881127 commit_bundle_validator = commit_validators .CommitBundleValidator (
@@ -1098,32 +1137,58 @@ def push(self, project_id: int):
10981137 "Make sure to fix all of the issues listed above before pushing." ,
10991138 ) from None
11001139
1101- print (
1102- "Pushing changes to the platform with the commit message: \n "
1103- f"\t - Message: { commit ['message' ]} \n "
1104- f"\t - Date: { commit ['date' ]} "
1105- )
1106-
1107- # Tar the project's staging area
1108- with tempfile .TemporaryDirectory () as tmp_dir :
1109- tar_file_path = os .path .join (tmp_dir , "staging" )
1110- with tarfile .open (tar_file_path , mode = "w:gz" ) as tar :
1111- tar .add (project_dir , arcname = os .path .basename (project_dir ))
1112-
1113- # Upload the tar file
1114- payload = {"commit" : {"message" : commit ["message" ]}}
1115- self .api .upload (
1116- endpoint = f"projects/{ project_id } /versions" ,
1117- file_path = tar_file_path ,
1118- object_name = "tarfile" ,
1119- body = payload ,
1120- )
1140+ return True
11211141
1122- # Clean up the staging area
1142+ def _post_push_cleanup (self , project_dir : str ) -> None :
1143+ """Cleans up and re-creates the project's staging area after a push."""
11231144 shutil .rmtree (project_dir )
11241145 os .makedirs (project_dir , exist_ok = True )
11251146
1126- print ("Pushed!" )
1147+ def export (self , destination_dir : str , project_id : int ):
1148+ """Exports the commited resources as a tarfile to the location specified
1149+ by ``destination_dir``.
1150+
1151+ This is useful if you want to drag and drop the tarfile into the platform's
1152+ UI to upload it instead of using the :obj:`push` method.
1153+
1154+ Parameters
1155+ ----------
1156+ destination_dir : str
1157+ Directory path to where the project's staging area should be exported.
1158+
1159+ Notes
1160+ -----
1161+ - To use this method, you must first have committed your changes with the :obj:`commit`
1162+ method.
1163+
1164+ Examples
1165+ --------
1166+
1167+ Let's say you have a project with a model and a dataset staged and committed. You can
1168+ confirm these resources are indeed in the staging area using the :obj:`status` method:
1169+
1170+ >>> project.status()
1171+
1172+ You should see the staged resources as well as the commit message associated with them.
1173+
1174+ Now, you can export the resources to a speficied location with:
1175+
1176+ >>> project.export(destination_dir="/path/to/destination")
1177+ """
1178+ project_dir = f"{ OPENLAYER_DIR } /{ project_id } /staging"
1179+
1180+ if self ._ready_for_push (project_dir = project_dir ):
1181+ # Tar the project's staging area
1182+ with tempfile .TemporaryDirectory () as tmp_dir :
1183+ tar_file_path = os .path .join (tmp_dir , "tarfile" )
1184+ with tarfile .open (tar_file_path , mode = "w:gz" ) as tar :
1185+ tar .add (project_dir , arcname = os .path .basename (project_dir ))
1186+
1187+ print (f"Exporting staging area to { destination_dir } ." )
1188+ shutil .copy (tar_file_path , os .path .expanduser (destination_dir ))
1189+
1190+ self ._post_push_cleanup (project_dir = project_dir )
1191+ print ("Exported tarfile!" )
11271192
11281193 def status (self , project_id : int ):
11291194 """Shows the state of the staging area.
0 commit comments