-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathbase.py
More file actions
147 lines (116 loc) · 3.46 KB
/
Copy pathbase.py
File metadata and controls
147 lines (116 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"""
Abstract base class for storage backends.
"""
from abc import ABC, abstractmethod
from typing import Any, AsyncIterator, Dict, List, Optional, Union
from pathlib import Path
class StorageBackend(ABC):
"""Abstract base class for storage backends."""
def __init__(self, config: Dict[str, Any]):
"""
Initialize storage backend.
Args:
config: Backend configuration dictionary
"""
self.config = config
self.name = config.get("name", "unknown")
@abstractmethod
async def exists(self, path: str) -> bool:
"""
Check if a file exists.
Args:
path: File path relative to backend root
Returns:
True if file exists, False otherwise
"""
pass
@abstractmethod
async def read(self, path: str) -> AsyncIterator[bytes]:
"""
Read file contents as an async iterator of chunks.
Args:
path: File path relative to backend root
Yields:
File content chunks as bytes
"""
pass
@abstractmethod
async def write(self, path: str, data: Union[bytes, AsyncIterator[bytes]]) -> int:
"""
Write data to a file.
Args:
path: File path relative to backend root
data: File content as bytes or async iterator of chunks
Returns:
Number of bytes written
"""
pass
@abstractmethod
async def delete(self, path: str) -> bool:
"""
Delete a file.
Args:
path: File path relative to backend root
Returns:
True if deleted, False if not found
"""
pass
@abstractmethod
async def list(self, path: str = "", recursive: bool = False) -> List[str]:
"""
List files in a directory.
Args:
path: Directory path relative to backend root
recursive: Whether to list recursively
Returns:
List of file paths
"""
pass
@abstractmethod
async def ensure_dir(self, path: str) -> None:
"""
Ensure a directory exists, creating it if necessary.
Args:
path: Directory path relative to backend root
"""
pass
async def get_file_info(self, path: str) -> Optional[Dict[str, Any]]:
"""
Get file metadata.
Args:
path: File path relative to backend root
Returns:
Dictionary with file info or None if not found
"""
if not await self.exists(path):
return None
return {
"path": path,
"exists": True,
}
async def get_size(self, path: str) -> int:
"""
Get file size in bytes.
Args:
path: File path relative to backend root
Returns:
File size in bytes
"""
info = await self.get_file_info(path)
return info.get("size", 0) if info else 0
async def get_status(self) -> Dict[str, Any]:
"""
Get backend status.
Returns:
Dictionary with backend status information
"""
return {
"name": self.name,
"type": self.__class__.__name__,
"available": True,
}
async def cleanup(self) -> None:
"""Clean up backend resources."""
pass
def __repr__(self) -> str:
return f"<{self.__class__.__name__} name={self.name}>"