Skip to content

Commit 377e33c

Browse files
(feat:file_abstract) process files method
1 parent e567d88 commit 377e33c

File tree

3 files changed

+77
-6
lines changed

3 files changed

+77
-6
lines changed

application/storage/base.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Base storage class for file system abstraction."""
22
from abc import ABC, abstractmethod
3-
from typing import BinaryIO, List
3+
from typing import BinaryIO, List, Optional, Callable
44

55

66
class BaseStorage(ABC):
@@ -33,6 +33,24 @@ def get_file(self, path: str) -> BinaryIO:
3333
"""
3434
pass
3535

36+
@abstractmethod
37+
def process_file(self, path: str, processor_func: Callable, **kwargs):
38+
"""
39+
Process a file using the provided processor function.
40+
41+
This method handles the details of retrieving the file and providing
42+
it to the processor function in an appropriate way based on the storage type.
43+
44+
Args:
45+
path: Path to the file
46+
processor_func: Function that processes the file
47+
**kwargs: Additional arguments to pass to the processor function
48+
49+
Returns:
50+
The result of the processor function
51+
"""
52+
pass
53+
3654
@abstractmethod
3755
def delete_file(self, path: str) -> bool:
3856
"""

application/storage/local.py

+22-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
"""Local file system implementation."""
22
import os
33
import shutil
4-
from typing import BinaryIO, List
4+
from typing import BinaryIO, List, Callable
55

6-
from application.core.settings import settings
76
from application.storage.base import BaseStorage
87

98

@@ -83,3 +82,24 @@ def list_files(self, directory: str) -> List[str]:
8382
result.append(rel_path)
8483

8584
return result
85+
86+
def process_file(self, path: str, processor_func: Callable, **kwargs):
87+
"""
88+
Process a file using the provided processor function.
89+
90+
For local storage, we can directly pass the full path to the processor.
91+
92+
Args:
93+
path: Path to the file
94+
processor_func: Function that processes the file
95+
**kwargs: Additional arguments to pass to the processor function
96+
97+
Returns:
98+
The result of the processor function
99+
"""
100+
full_path = self._get_full_path(path)
101+
102+
if not os.path.exists(full_path):
103+
raise FileNotFoundError(f"File not found: {full_path}")
104+
105+
return processor_func(file_path=full_path, **kwargs)

application/storage/s3.py

+36-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""S3 storage implementation."""
22
import io
3-
from typing import BinaryIO, List
3+
from typing import BinaryIO, List, Callable
44

55
import boto3
66
from botocore.exceptions import ClientError
@@ -24,7 +24,6 @@ def __init__(self, bucket_name: str, aws_access_key_id=None,
2424
"""
2525
self.bucket_name = bucket_name
2626

27-
# Initialize S3 client
2827
self.s3 = boto3.client(
2928
's3',
3029
aws_access_key_id=aws_access_key_id,
@@ -78,4 +77,38 @@ def list_files(self, directory: str) -> List[str]:
7877
for obj in page['Contents']:
7978
result.append(obj['Key'])
8079

81-
return result
80+
return result
81+
82+
def process_file(self, path: str, processor_func: Callable, **kwargs):
83+
"""
84+
Process a file using the provided processor function.
85+
86+
For S3 storage, we need to download the file to a temporary location first.
87+
88+
Args:
89+
path: Path to the file
90+
processor_func: Function that processes the file
91+
**kwargs: Additional arguments to pass to the processor function
92+
93+
Returns:
94+
The result of the processor function
95+
"""
96+
import tempfile
97+
import os
98+
99+
if not self.file_exists(path):
100+
raise FileNotFoundError(f"File not found: {path}")
101+
102+
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
103+
self.s3.download_fileobj(self.bucket_name, path, temp_file)
104+
temp_path = temp_file.name
105+
106+
try:
107+
result = processor_func(file_path=temp_path, **kwargs)
108+
return result
109+
finally:
110+
try:
111+
os.unlink(temp_path)
112+
except Exception as e:
113+
import logging
114+
logging.warning(f"Failed to delete temporary file: {e}")

0 commit comments

Comments
 (0)