Peterase commited on
Commit
f48c629
·
1 Parent(s): 3bb4dfd

fix: use HuggingFace Hub API for file uploads

Browse files
Files changed (1) hide show
  1. app/services/hf_storage_adapter.py +36 -27
app/services/hf_storage_adapter.py CHANGED
@@ -15,9 +15,11 @@ class HFStorageAdapter(StoragePort):
15
 
16
  def __init__(self):
17
  self.bucket_path = settings.HF_BUCKET_PATH
 
 
18
  self.local_cache = Path("/tmp/ragora_cache")
19
  self.local_cache.mkdir(exist_ok=True)
20
- logger.info(f"Using HF bucket: {self.bucket_path}")
21
 
22
  async def upload(self, key: str, data: bytes, content_type: str) -> str:
23
  """Upload file to HF bucket."""
@@ -29,20 +31,18 @@ class HFStorageAdapter(StoragePort):
29
  with open(local_path, 'wb') as f:
30
  f.write(data)
31
 
32
- # Upload to HF bucket using hf CLI
33
- import subprocess
34
- hf_path = f"{self.bucket_path}/{key}"
35
 
36
- result = subprocess.run(
37
- ["hf", "upload", hf_path, str(local_path)],
38
- capture_output=True,
39
- text=True
 
 
40
  )
41
 
42
- if result.returncode != 0:
43
- logger.error(f"HF upload failed: {result.stderr}")
44
- raise Exception(f"Upload failed: {result.stderr}")
45
-
46
  logger.info(f"Uploaded file: {key}")
47
  return key
48
  except Exception as e:
@@ -56,19 +56,20 @@ class HFStorageAdapter(StoragePort):
56
  local_path = self.local_cache / key
57
 
58
  if not local_path.exists():
59
- # Download from HF bucket
60
- import subprocess
61
- hf_path = f"{self.bucket_path}/{key}"
 
62
 
63
- result = subprocess.run(
64
- ["hf", "download", hf_path, "--local-dir", str(self.local_cache)],
65
- capture_output=True,
66
- text=True
 
 
67
  )
68
 
69
- if result.returncode != 0:
70
- logger.error(f"HF download failed: {result.stderr}")
71
- raise Exception(f"Download failed: {result.stderr}")
72
 
73
  with open(local_path, 'rb') as f:
74
  data = f.read()
@@ -81,20 +82,28 @@ class HFStorageAdapter(StoragePort):
81
  async def delete(self, key: str) -> None:
82
  """Delete file from HF bucket."""
83
  try:
 
 
 
 
 
 
 
 
 
 
84
  # Delete from local cache
85
  local_path = self.local_cache / key
86
  if local_path.exists():
87
  local_path.unlink()
88
 
89
- # Note: HF CLI doesn't have direct delete, so we'll just remove from cache
90
- # Files in HF buckets can be managed via web interface
91
- logger.info(f"Deleted file from cache: {key}")
92
  except Exception as e:
93
  logger.error(f"Error deleting file: {e}")
94
  raise
95
 
96
  async def get_presigned_url(self, key: str, expires: int = 3600) -> str:
97
  """Get presigned URL for downloading."""
98
- # For HF buckets, return the direct HF URL
99
- hf_url = f"https://huggingface.co/datasets/{self.bucket_path.replace('hf://buckets/', '')}/resolve/main/{key}"
100
  return hf_url
 
15
 
16
  def __init__(self):
17
  self.bucket_path = settings.HF_BUCKET_PATH
18
+ # Extract repo_id from bucket path: hf://buckets/Peterase/Ragora-doc-store -> Peterase/Ragora-doc-store
19
+ self.repo_id = self.bucket_path.replace("hf://buckets/", "")
20
  self.local_cache = Path("/tmp/ragora_cache")
21
  self.local_cache.mkdir(exist_ok=True)
22
+ logger.info(f"Using HF bucket: {self.bucket_path} (repo: {self.repo_id})")
23
 
24
  async def upload(self, key: str, data: bytes, content_type: str) -> str:
25
  """Upload file to HF bucket."""
 
31
  with open(local_path, 'wb') as f:
32
  f.write(data)
33
 
34
+ # Upload to HF bucket using huggingface_hub API
35
+ from huggingface_hub import HfApi
36
+ api = HfApi()
37
 
38
+ # Upload file to the bucket
39
+ api.upload_file(
40
+ path_or_fileobj=str(local_path),
41
+ path_in_repo=key,
42
+ repo_id=self.repo_id,
43
+ repo_type="dataset"
44
  )
45
 
 
 
 
 
46
  logger.info(f"Uploaded file: {key}")
47
  return key
48
  except Exception as e:
 
56
  local_path = self.local_cache / key
57
 
58
  if not local_path.exists():
59
+ # Download from HF bucket using huggingface_hub API
60
+ from huggingface_hub import hf_hub_download
61
+
62
+ local_path.parent.mkdir(parents=True, exist_ok=True)
63
 
64
+ downloaded_path = hf_hub_download(
65
+ repo_id=self.repo_id,
66
+ filename=key,
67
+ repo_type="dataset",
68
+ local_dir=str(self.local_cache),
69
+ local_dir_use_symlinks=False
70
  )
71
 
72
+ logger.info(f"Downloaded file: {key}")
 
 
73
 
74
  with open(local_path, 'rb') as f:
75
  data = f.read()
 
82
  async def delete(self, key: str) -> None:
83
  """Delete file from HF bucket."""
84
  try:
85
+ # Delete from HF bucket using huggingface_hub API
86
+ from huggingface_hub import HfApi
87
+ api = HfApi()
88
+
89
+ api.delete_file(
90
+ path_in_repo=key,
91
+ repo_id=self.repo_id,
92
+ repo_type="dataset"
93
+ )
94
+
95
  # Delete from local cache
96
  local_path = self.local_cache / key
97
  if local_path.exists():
98
  local_path.unlink()
99
 
100
+ logger.info(f"Deleted file: {key}")
 
 
101
  except Exception as e:
102
  logger.error(f"Error deleting file: {e}")
103
  raise
104
 
105
  async def get_presigned_url(self, key: str, expires: int = 3600) -> str:
106
  """Get presigned URL for downloading."""
107
+ # For HF datasets, return the direct HF URL
108
+ hf_url = f"https://huggingface.co/datasets/{self.repo_id}/resolve/main/{key}"
109
  return hf_url