Skip to content

Commit

Permalink
Implement document upload functionality for MinIO only
Browse files Browse the repository at this point in the history
  • Loading branch information
Q-Niranjan committed Oct 30, 2024
1 parent 18e5d07 commit 2ab1362
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 116 deletions.
4 changes: 0 additions & 4 deletions src/openg2p_portal_api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ class Settings(AuthSettings, Settings):

openapi_version: str = __version__
db_dbname: Optional[str] = "openg2pdb"
odoo_url: str
odoo_db: str
odoo_username: str
odoo_password: str

auth_api_get_programs: ApiAuthSettings = ApiAuthSettings(enabled=True)
auth_api_get_program_by_id: ApiAuthSettings = ApiAuthSettings(enabled=True)
Expand Down
54 changes: 16 additions & 38 deletions src/openg2p_portal_api/services/document_file_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
compute_human_file_size,
create_or_update_tag,
extract_filename,
fullpath,
get_company_and_backend_id_by_programid,
get_file_id_by_slug,
get_s3_backend_config,
Expand Down Expand Up @@ -53,7 +52,7 @@ async def get_document_by_id(self, document_id: int):

async def upload_document(self, file, programid: int, file_tag: str):
"""
Uploads a document to Amazon S3 or local filesystem and saves its metadata in the database.
Uploads a document to MinIO or the local filesystem and saves its metadata in the database.
"""
async with self.async_session_maker() as session:
# Retrieve company and backend IDs
Expand All @@ -62,12 +61,17 @@ async def upload_document(self, file, programid: int, file_tag: str):
backend_id,
) = await get_company_and_backend_id_by_programid(self, programid)

# Fetching the backend on the basis of backend_id
# Retrieve backend configuration using the backend_id
backend = await get_s3_backend_config(self, backend_id)
# Determine backend type and upload document
# Determine backend type
backend_type = backend.server_env_defaults.get("x_backend_type_env_default")

if backend_type == "amazon_s3" or backend_type == "filesystem":
if backend_type == "filesystem":
return {
"message": "Uploading files via the filesystem is currently not supported."
}

if backend_type == "amazon_s3":
name = file.filename
data = await file.read()
if data is None:
Expand Down Expand Up @@ -101,21 +105,16 @@ async def upload_document(self, file, programid: int, file_tag: str):
slugified_filename = slugify(name)
file_id = await get_file_id_by_slug(self)
final_filename = f"{slugified_filename}-{file_id}"

# Update the database with the new slugified filename relative path
await update_slug_relative_path(self, file_id, final_filename)

# Upload file to backend storage
if backend_type == "amazon_s3":
return await self.S3_StorageSystem(file, final_filename, backend)
elif backend_type == "filesystem":
full_path = fullpath(final_filename)
return await self.file_StorageSystem(full_path, data)
# Upload the file to the backend storage
return await self.s3_storage_system(file, final_filename, backend)

else:
raise BadRequestError(
message="Backend configuration not belong amazon_s3 or fileStorageSystem "
) from None
return {"message": "Backend type should be either amazon_s3 or filesystem."}

async def S3_StorageSystem(self, file: object, file_name: str, backend: object):
async def s3_storage_system(self, file: object, file_name: str, backend: object):
"""
Upload a file to an S3-compatible storage system (e.g., MinIO) using the provided backend configuration.
"""
Expand Down Expand Up @@ -155,25 +154,4 @@ async def S3_StorageSystem(self, file: object, file_name: str, backend: object):
handle_exception(e, "Client error occurred")
except Exception as e:
handle_exception(e, f"Unexpected error while uploading file {file_name}")
return {"Message": "File Upload on s3 Successfully "}

async def file_StorageSystem(self, full_path: str, data: bytes):
"""
Add a file at the specified relative path in the local filesystem.
"""
try:
# Ensure directory exists
dirname = os.path.dirname(full_path)
if not os.path.isdir(dirname):
os.makedirs(dirname)

# Write file data
with open(full_path, "wb") as my_file:
my_file.write(data)
except OSError as e:
handle_exception(e, "Error creating directory or writing file")
except TypeError as e:
handle_exception(e, "Invalid data type")
except Exception as e:
handle_exception(e, "Unexpected error while writing file")
return {"Message": "File Upload Successfully in fileStorage "}
return {"message": "File uploaded successfully."}
41 changes: 1 addition & 40 deletions src/openg2p_portal_api/utils/file_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,8 @@
from openg2p_portal_api.models.orm.document_store_orm import DocumentStoreORM
from openg2p_portal_api.models.orm.document_tag_orm import DocumentTagORM
from openg2p_portal_api.models.orm.program_orm import ProgramORM
from openg2p_portal_api.utils.odoo_server_utils import get_odoo_connection

# Methods: Below are used for managing file storage in the local environment.
# - fullpath
# - is_safe_path
# - basedir


def fullpath(relative_path: str) -> str:
"""
Build the full path for the file and ensure it's safe.
"""
base_dir = basedir()
print(base_dir)
full_path = os.path.join(base_dir, relative_path)
if not is_safe_path(base_dir, full_path):
raise BadRequestError(message=f"Access to {full_path} is forbidden.") from None
return full_path


def is_safe_path(basedir: str, path: str) -> bool:
"""Check if the path is within the base directory."""
return os.path.realpath(path).startswith(basedir)


def basedir() -> str:
"""
Get base directory for file storage.
"""

try:
models, db, uid, password = get_odoo_connection()
filestore_path = models.execute_kw(
db, uid, password, "ir.attachment", "get_filestore_path", []
)
return os.path.join(filestore_path, "storage")
except Exception as e:
handle_exception(e, "Error retrieving base directory")


# Methods below are used for uploading documents to Odoo and S3:
# The methods below enable concurrent document uploads to Odoo and MinIO (S3-compatible).
# - get_s3_backend_config
# - create_or_update_tag
# - get_company_and_backend_id_by_programid
Expand Down
34 changes: 0 additions & 34 deletions src/openg2p_portal_api/utils/odoo_server_utils.py

This file was deleted.

0 comments on commit 2ab1362

Please sign in to comment.