fake_bucket.py (2281B)
1 """A tiny in-memory stand-in for the Hugging Face bucket, shared by the offline tests. 2 3 `install(storage, main)` patches the storage layer so the real FastAPI app can be exercised with no 4 network. Directories have no `size` attribute, like the real tree items. 5 """ 6 7 import datetime 8 9 # path -> size in bytes. Includes awkward cases on purpose: HTML-special characters, spaces, a deep 10 # path (long breadcrumb), root-level files, an excluded .gitattributes and hidden internal prefixes. 11 FILES = { 12 "README.md": 1200, 13 ".gitattributes": 66, 14 "top-level.txt": 7, 15 "bsc/README.md": 3000, 16 "bsc/semester_1/notes.txt": 12, 17 "bsc/semester_1/deep/a.bin": 5, 18 "bsc/semester_1/deep/er/est/x.txt": 1048576, 19 "bsc/semester_1/Zeta.pdf": 2500000, 20 "bsc/semester_1/alpha.pdf": 999, 21 "a&b/it's here/<x> \"q\".txt": 42, 22 "a&b/plain.txt": 1023, 23 "uploads/9f3a1c2b-photo one.png": 2048, 24 "bsc/ünï 😀/a.txt": 9, 25 "bsc/semester_1/deep/er/est/more/x.txt": 3, 26 "solo/only.txt": 1152, 27 "solo2/a.txt": 1, 28 "_logs/hidden.log": 1, 29 "_batches/b1.json": 1, 30 } 31 32 33 class Dir: 34 def __init__(self, path): 35 self.path = path 36 37 38 class File: 39 def __init__(self, path, size): 40 self.path, self.size = path, size 41 self.uploaded_at = datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc) 42 43 44 def _children(path): 45 path = path.strip("/") 46 prefix = path + "/" if path else "" 47 out = {} 48 for fp, size in FILES.items(): 49 if not fp.startswith(prefix): 50 continue 51 rest = fp[len(prefix):] 52 if "/" in rest: 53 d = prefix + rest.split("/")[0] 54 out[d] = Dir(d) 55 else: 56 out[fp] = File(fp, size) 57 return list(out.values()) 58 59 60 def fetch_tree(path): 61 return _children(path) 62 63 64 def fetch_tree_recursive(path=""): 65 path = path.strip("/") 66 prefix = path + "/" if path else "" 67 return [File(fp, s) for fp, s in FILES.items() if fp.startswith(prefix)] 68 69 70 async def get_file_info(path): 71 return {"exists": path in FILES, "size": FILES.get(path), "content_type": None} 72 73 74 def install(storage, main): 75 storage._fetch_tree = fetch_tree 76 storage._fetch_tree_recursive = fetch_tree_recursive 77 storage.get_file_info = get_file_info 78 storage._cache.clear()