33import os
44import shutil
55import subprocess
6- < << << << HEAD
76import tempfile
87from pathlib import Path
9- == == == =
10- from pathlib import Path
11- from typing import Set
12- > >> >> >> origin / dev
138
149from huggingface_hub import HfApi
1510
1611
17- < << << << HEAD
1812def get_excluded_dirs () -> set [str ]:
19- == == == =
20- def get_excluded_dirs () -> Set [str ]:
21- > >> >> >> origin / dev
2213 """Get set of directory names to exclude from deployment."""
2314 return {
2415 "docs" ,
@@ -47,28 +38,17 @@ def get_excluded_dirs() -> Set[str]:
4738 "dist" ,
4839 ".eggs" ,
4940 "htmlcov" ,
50- < << << << HEAD
5141 "hf_space" , # Exclude the cloned HF Space directory itself
5242 }
5343
5444
5545def get_excluded_files () -> set [str ]:
56- == == == =
57- }
58-
59-
60- def get_excluded_files () -> Set [str ]:
61- > >> >> >> origin / dev
6246 """Get set of file names to exclude from deployment."""
6347 return {
6448 ".pre-commit-config.yaml" ,
6549 "mkdocs.yml" ,
6650 "uv.lock" ,
6751 "AGENTS.txt" ,
68- < << << << HEAD
69- == == == =
70- "CONTRIBUTING.md" ,
71- > >> >> >> origin / dev
7252 ".env" ,
7353 ".env.local" ,
7454 "*.local" ,
@@ -80,29 +60,17 @@ def get_excluded_files() -> Set[str]:
8060 }
8161
8262
83- << << << < HEAD
8463def should_exclude (path : Path , excluded_dirs : set [str ], excluded_files : set [str ]) -> bool :
85- == == == =
86- def should_exclude (path : Path , excluded_dirs : Set [str ], excluded_files : Set [str ]) -> bool :
87- > >> >> >> origin / dev
8864 """Check if a path should be excluded from deployment."""
8965 # Check if any parent directory is excluded
9066 for parent in path .parents :
9167 if parent .name in excluded_dirs :
9268 return True
93- < << << << HEAD
9469
9570 # Check if the path itself is a directory that should be excluded
9671 if path .is_dir () and path .name in excluded_dirs :
9772 return True
9873
99- == == == =
100-
101- # Check if the path itself is a directory that should be excluded
102- if path .is_dir () and path .name in excluded_dirs :
103- return True
104-
105- > >> >> >> origin / dev
10674 # Check if the file name matches excluded patterns
10775 if path .is_file ():
10876 # Check exact match
@@ -115,36 +83,22 @@ def should_exclude(path: Path, excluded_dirs: Set[str], excluded_files: Set[str]
11583 suffix = pattern .replace ("*" , "" )
11684 if path .name .endswith (suffix ):
11785 return True
118- < << << << HEAD
119-
120- == == == =
121-
122- >> >> >> > origin / dev
12386 return False
12487
12588
12689def deploy_to_hf_space () -> None :
12790 """Deploy repository to Hugging Face Space.
128- <<<<<<< HEAD
12991
13092 Supports both user and organization Spaces:
13193 - User Space: username/space-name
13294 - Organization Space: organization-name/space-name
13395
134- =======
135-
136- Supports both user and organization Spaces:
137- - User Space: username/space-name
138- - Organization Space: organization-name/space-name
139-
140- >>>>>>> origin/dev
14196 Works with both classic tokens and fine-grained tokens.
14297 """
14398 # Get configuration from environment variables
14499 hf_token = os .getenv ("HF_TOKEN" )
145100 hf_username = os .getenv ("HF_USERNAME" ) # Can be username or organization name
146101 space_name = os .getenv ("HF_SPACE_NAME" )
147- < << << << HEAD
148102
149103 # Check which variables are missing and provide helpful error message
150104 missing = []
@@ -164,33 +118,16 @@ def deploy_to_hf_space() -> None:
164118 f" - HF_SPACE_NAME in Settings > Secrets and variables > Actions > Variables"
165119 )
166120
167- == == == =
168-
169- if not all ([hf_token , hf_username , space_name ]):
170- raise ValueError (
171- "Missing required environment variables: HF_TOKEN, HF_USERNAME, HF_SPACE_NAME"
172- )
173-
174- > >> >> >> origin / dev
175121 # HF_USERNAME can be either a username or organization name
176122 # Format: {username|organization}/{space_name}
177123 repo_id = f"{ hf_username } /{ space_name } "
178124 local_dir = "hf_space"
179- < << << << HEAD
180125
181126 print (f"🚀 Deploying to Hugging Face Space: { repo_id } " )
182127
183128 # Initialize HF API
184129 api = HfApi (token = hf_token )
185130
186- == == == =
187-
188- print (f"🚀 Deploying to Hugging Face Space: { repo_id } " )
189-
190- # Initialize HF API
191- api = HfApi (token = hf_token )
192-
193- >> >> >> > origin / dev
194131 # Create Space if it doesn't exist
195132 try :
196133 api .repo_info (repo_id = repo_id , repo_type = "space" , token = hf_token )
@@ -208,7 +145,6 @@ def deploy_to_hf_space() -> None:
208145 exist_ok = True ,
209146 )
210147 print (f"✅ Created new Space: { repo_id } " )
211- << << << < HEAD
212148
213149 # Configure Git credential helper for authentication
214150 # This is needed for Git LFS to work properly with fine-grained tokens
@@ -248,25 +184,13 @@ def deploy_to_hf_space() -> None:
248184 shutil .rmtree (local_dir )
249185
250186 print ("📥 Cloning Space repository..." )
251- == == == =
252-
253- # Clone repository using git
254- space_url = f"https://{ hf_token } @huggingface.co/spaces/{ repo_id } "
255-
256- if Path (local_dir ).exists ():
257- print (f"🧹 Removing existing { local_dir } directory..." )
258- shutil .rmtree (local_dir )
259-
260- print (f"📥 Cloning Space repository..." )
261- >> >> >> > origin / dev
262187 try :
263188 result = subprocess .run (
264189 ["git" , "clone" , space_url , local_dir ],
265190 check = True ,
266191 capture_output = True ,
267192 text = True ,
268193 )
269- << << << < HEAD
270194 print ("✅ Cloned Space repository" )
271195
272196 # After clone, configure the remote to use credential helper
@@ -325,18 +249,6 @@ def deploy_to_hf_space() -> None:
325249 excluded_dirs = get_excluded_dirs ()
326250 excluded_files = get_excluded_files ()
327251
328- == == == =
329- print (f"✅ Cloned Space repository" )
330- except subprocess .CalledProcessError as e :
331- error_msg = e .stderr if e .stderr else e .stdout if e .stdout else "Unknown error"
332- print (f"❌ Failed to clone Space repository: { error_msg } " )
333- raise RuntimeError (f"Git clone failed: { error_msg } " ) from e
334-
335- # Get exclusion sets
336- excluded_dirs = get_excluded_dirs ()
337- excluded_files = get_excluded_files ()
338-
339- > >> >> >> origin / dev
340252 # Remove all existing files in HF Space (except .git)
341253 print ("🧹 Cleaning existing files..." )
342254 for item in Path (local_dir ).iterdir ():
@@ -346,26 +258,15 @@ def deploy_to_hf_space() -> None:
346258 shutil .rmtree (item )
347259 else :
348260 item .unlink ()
349- < << << << HEAD
350-
351- == == == =
352-
353- >> >> >> > origin / dev
354261 # Copy files from repository root
355262 print ("📦 Copying files..." )
356263 repo_root = Path ("." )
357264 files_copied = 0
358265 dirs_copied = 0
359- < << << << HEAD
360-
361- == == == =
362-
363- >> >> >> > origin / dev
364266 for item in repo_root .rglob ("*" ):
365267 # Skip if in .git directory
366268 if ".git" in item .parts :
367269 continue
368- < << << << HEAD
369270
370271 # Skip if in hf_space directory (the cloned Space directory)
371272 if "hf_space" in item .parts :
@@ -375,20 +276,12 @@ def deploy_to_hf_space() -> None:
375276 if should_exclude (item , excluded_dirs , excluded_files ):
376277 continue
377278
378- == == == =
379-
380- # Skip if should be excluded
381- if should_exclude (item , excluded_dirs , excluded_files ):
382- continue
383-
384- > >> >> >> origin / dev
385279 # Calculate relative path
386280 try :
387281 rel_path = item .relative_to (repo_root )
388282 except ValueError :
389283 # Item is outside repo root, skip
390284 continue
391- << << << < HEAD
392285
393286 # Skip if in excluded directory
394287 if any (part in excluded_dirs for part in rel_path .parts ):
@@ -400,27 +293,13 @@ def deploy_to_hf_space() -> None:
400293 # Create parent directories
401294 dest_path .parent .mkdir (parents = True , exist_ok = True )
402295
403- == == == =
404-
405- # Skip if in excluded directory
406- if any (part in excluded_dirs for part in rel_path .parts ):
407- continue
408-
409- # Destination path
410- dest_path = Path (local_dir ) / rel_path
411-
412- # Create parent directories
413- dest_path .parent .mkdir (parents = True , exist_ok = True )
414-
415- >> >> >> > origin / dev
416296 # Copy file or directory
417297 if item .is_file ():
418298 shutil .copy2 (item , dest_path )
419299 files_copied += 1
420300 elif item .is_dir ():
421301 # Directory will be created by parent mkdir, but we track it
422302 dirs_copied += 1
423- < << << << HEAD
424303
425304 print (f"✅ Copied { files_copied } files and { dirs_copied } directories" )
426305
@@ -431,18 +310,6 @@ def deploy_to_hf_space() -> None:
431310 original_cwd = os .getcwd ()
432311 os .chdir (local_dir )
433312
434- == == == =
435-
436- print (f"✅ Copied { files_copied } files and { dirs_copied } directories" )
437-
438- # Commit and push changes using git
439- print ("💾 Committing changes..." )
440-
441- # Change to the Space directory
442- original_cwd = os .getcwd ()
443- os .chdir (local_dir )
444-
445- >> >> >> > origin / dev
446313 try :
447314 # Configure git user (required for commit)
448315 subprocess .run (
@@ -455,18 +322,12 @@ def deploy_to_hf_space() -> None:
455322 check = True ,
456323 capture_output = True ,
457324 )
458- << << << < HEAD
459-
460- == == == =
461-
462- >> >> >> > origin / dev
463325 # Add all files
464326 subprocess .run (
465327 ["git" , "add" , "." ],
466328 check = True ,
467329 capture_output = True ,
468330 )
469- < << << << HEAD
470331
471332 # Check if there are changes to commit
472333 result = subprocess .run (
@@ -476,16 +337,6 @@ def deploy_to_hf_space() -> None:
476337 text = True ,
477338 )
478339
479- == == == =
480-
481- # Check if there are changes to commit
482- result = subprocess .run (
483- ["git" , "status" , "--porcelain" ],
484- capture_output = True ,
485- text = True ,
486- )
487-
488- >> >> >> > origin / dev
489340 if result .stdout .strip ():
490341 # There are changes, commit and push
491342 subprocess .run (
@@ -494,15 +345,12 @@ def deploy_to_hf_space() -> None:
494345 capture_output = True ,
495346 )
496347 print ("📤 Pushing to Hugging Face Space..." )
497- < << << << HEAD
498348 # Ensure remote URL uses credential helper (not token in URL)
499349 subprocess .run (
500350 ["git" , "remote" , "set-url" , "origin" , f"https://huggingface.co/spaces/{ repo_id } " ],
501351 check = True ,
502352 capture_output = True ,
503353 )
504- == == == =
505- >> >> >> > origin / dev
506354 subprocess .run (
507355 ["git" , "push" ],
508356 check = True ,
@@ -523,7 +371,6 @@ def deploy_to_hf_space() -> None:
523371 finally :
524372 # Return to original directory
525373 os .chdir (original_cwd )
526- < << << << HEAD
527374
528375 # Clean up credential store for security
529376 try :
@@ -533,15 +380,8 @@ def deploy_to_hf_space() -> None:
533380 # Ignore cleanup errors
534381 pass
535382
536- == == == =
537-
538- >> >> >> > origin / dev
539383 print (f"🎉 Successfully deployed to: https://huggingface.co/spaces/{ repo_id } " )
540384
541385
542386if __name__ == "__main__" :
543387 deploy_to_hf_space ()
544- < << << << HEAD
545- == == == =
546-
547- >> >> >> > origin / dev
0 commit comments