From ee68caba4e9eb102e34e3179a2251b8004f4f5c5 Mon Sep 17 00:00:00 2001 From: Henry Ruhs Date: Sat, 12 Sep 2026 17:01:41 +0200 Subject: [PATCH] convert asset store (#1243) --- facefusion/apis/asset_store.py | 59 +++++++++++++--------------- facefusion/apis/endpoints/assets.py | 21 ++++------ facefusion/apis/endpoints/jobs.py | 7 ++-- facefusion/apis/endpoints/session.py | 3 +- facefusion/apis/endpoints/state.py | 8 ++-- facefusion/apis/jobs_helper.py | 5 +-- facefusion/types.py | 1 - 7 files changed, 46 insertions(+), 58 deletions(-) diff --git a/facefusion/apis/asset_store.py b/facefusion/apis/asset_store.py index 204fc0d1..49ccaa13 100644 --- a/facefusion/apis/asset_store.py +++ b/facefusion/apis/asset_store.py @@ -2,15 +2,22 @@ import uuid from datetime import datetime, timedelta from typing import Optional, cast +from facefusion import store_creator from facefusion.apis.asset_helper import detect_media_type_by_path, extract_image_metadata from facefusion.ffprobe import extract_audio_metadata, extract_video_metadata from facefusion.filesystem import get_file_format, get_file_name, get_file_size -from facefusion.types import AssetId, AssetSet, AssetStore, AssetType, AudioAsset, AudioFormat, ImageAsset, ImageFormat, SessionId, VideoAsset, VideoFormat +from facefusion.session_manager import resolve_owner_id +from facefusion.types import AssetId, AssetSet, AssetType, AudioAsset, AudioFormat, ImageAsset, ImageFormat, Store, VideoAsset, VideoFormat -ASSET_STORE : AssetStore = {} +ASSET_STORE : Store = store_creator.create_store({}) -def create_asset(session_id : SessionId, asset_type : AssetType, asset_path : str) -> Optional[AudioAsset | ImageAsset | VideoAsset]: +def init() -> None: + owner_id = resolve_owner_id() + store_creator.init_content(ASSET_STORE, owner_id) + + +def create_asset(asset_type : AssetType, asset_path : str) -> Optional[AudioAsset | ImageAsset | VideoAsset]: asset_id = str(uuid.uuid4()) asset_name = get_file_name(asset_path) asset_format = get_file_format(asset_path) @@ -18,12 +25,10 @@ def create_asset(session_id : SessionId, asset_type : AssetType, asset_path : st media_type = detect_media_type_by_path(asset_path) created_at = datetime.now() expires_at = created_at + timedelta(hours = 2) - - if session_id not in ASSET_STORE: - ASSET_STORE[session_id] = {} + asset_set = get_assets() if media_type == 'audio': - ASSET_STORE[session_id][asset_id] = cast(AudioAsset, + asset_set[asset_id] = cast(AudioAsset, { 'id': asset_id, 'created_at': created_at, @@ -38,7 +43,7 @@ def create_asset(session_id : SessionId, asset_type : AssetType, asset_path : st }) if media_type == 'image': - ASSET_STORE[session_id][asset_id] = cast(ImageAsset, + asset_set[asset_id] = cast(ImageAsset, { 'id': asset_id, 'created_at': created_at, @@ -53,7 +58,7 @@ def create_asset(session_id : SessionId, asset_type : AssetType, asset_path : st }) if media_type == 'video': - ASSET_STORE[session_id][asset_id] = cast(VideoAsset, + asset_set[asset_id] = cast(VideoAsset, { 'id': asset_id, 'created_at': created_at, @@ -67,34 +72,26 @@ def create_asset(session_id : SessionId, asset_type : AssetType, asset_path : st 'metadata': extract_video_metadata(asset_path) }) - return ASSET_STORE[session_id].get(asset_id) + return asset_set.get(asset_id) -def get_assets(session_id : SessionId) -> Optional[AssetSet]: - return ASSET_STORE.get(session_id) +def get_assets() -> AssetSet: + owner_id = resolve_owner_id() + + return store_creator.get_content(ASSET_STORE, owner_id) -def get_asset(session_id : SessionId, asset_id : AssetId) -> Optional[AudioAsset | ImageAsset | VideoAsset]: - if session_id in ASSET_STORE: - return ASSET_STORE.get(session_id).get(asset_id) - return None +def get_asset(asset_id : AssetId) -> Optional[AudioAsset | ImageAsset | VideoAsset]: + return get_assets().get(asset_id) -def delete_asset(session_id : SessionId, asset_id : AssetId) -> None: - if session_id in ASSET_STORE: - if asset_id in ASSET_STORE.get(session_id): - del ASSET_STORE[session_id][asset_id] +def delete_asset(asset_id : AssetId) -> None: + asset_set = get_assets() - if ASSET_STORE.get(session_id) == {}: - del ASSET_STORE[session_id] - return None + if asset_id in asset_set: + del asset_set[asset_id] -def delete_assets(session_id : SessionId) -> None: - if session_id in ASSET_STORE: - del ASSET_STORE[session_id] - return None - - -def clear() -> None: - ASSET_STORE.clear() +def delete_assets() -> None: + owner_id = resolve_owner_id() + store_creator.init_content(ASSET_STORE, owner_id) diff --git a/facefusion/apis/endpoints/assets.py b/facefusion/apis/endpoints/assets.py index b229af67..639417bd 100644 --- a/facefusion/apis/endpoints/assets.py +++ b/facefusion/apis/endpoints/assets.py @@ -5,7 +5,7 @@ from starlette.requests import Request from starlette.responses import FileResponse, JSONResponse, Response from starlette.status import HTTP_200_OK, HTTP_201_CREATED, HTTP_400_BAD_REQUEST, HTTP_404_NOT_FOUND, HTTP_415_UNSUPPORTED_MEDIA_TYPE -from facefusion import session_context, translator +from facefusion import translator from facefusion.apis import asset_store from facefusion.apis.asset_helper import capture_asset_faces, capture_asset_frames, save_asset_files, validate_asset_files from facefusion.filesystem import remove_file @@ -13,8 +13,7 @@ from facefusion.vision import is_vision_frames, to_strip_buffer async def get_assets(request : Request) -> Response: - session_id = session_context.get_session_id() - asset_set = asset_store.get_assets(session_id) + asset_set = asset_store.get_assets() assets = [] if asset_set: @@ -39,9 +38,8 @@ async def get_assets(request : Request) -> Response: async def get_asset(request : Request) -> Response: - session_id = session_context.get_session_id() asset_id = request.path_params.get('asset_id') - asset = asset_store.get_asset(session_id, asset_id) + asset = asset_store.get_asset(asset_id) if asset: if asset.get('media') in [ 'image', 'video' ] and request.query_params.get('action') == 'capture': @@ -86,7 +84,6 @@ async def get_asset(request : Request) -> Response: async def upload_assets(request : Request) -> Response: - session_id = session_context.get_session_id() asset_type = request.query_params.get('type') if asset_type in [ 'source', 'target' ]: @@ -100,7 +97,7 @@ async def upload_assets(request : Request) -> Response: asset_ids : List[str] = [] for asset_path in asset_paths: - asset = asset_store.create_asset(session_id, asset_type, asset_path) + asset = asset_store.create_asset(asset_type, asset_path) if asset: asset_id = asset.get('id') @@ -120,8 +117,7 @@ async def upload_assets(request : Request) -> Response: async def delete_assets(request : Request) -> Response: - session_id = session_context.get_session_id() - asset_set = asset_store.get_assets(session_id) + asset_set = asset_store.get_assets() asset_ids : List[str] = [] if asset_set: @@ -130,18 +126,17 @@ async def delete_assets(request : Request) -> Response: asset_ids.append(asset.get('id')) for asset_id in asset_ids: - asset_store.delete_asset(session_id, asset_id) + asset_store.delete_asset(asset_id) return Response(status_code = HTTP_200_OK) async def delete_asset(request : Request) -> Response: - session_id = session_context.get_session_id() asset_id = request.path_params.get('asset_id') - asset = asset_store.get_asset(session_id, asset_id) + asset = asset_store.get_asset(asset_id) if asset and remove_file(asset.get('path')): - asset_store.delete_asset(session_id, asset_id) + asset_store.delete_asset(asset_id) return Response(status_code = HTTP_200_OK) return Response(status_code = HTTP_404_NOT_FOUND) diff --git a/facefusion/apis/endpoints/jobs.py b/facefusion/apis/endpoints/jobs.py index adb59cc2..45a0df82 100644 --- a/facefusion/apis/endpoints/jobs.py +++ b/facefusion/apis/endpoints/jobs.py @@ -8,7 +8,7 @@ from starlette.status import HTTP_200_OK, HTTP_201_CREATED, HTTP_202_ACCEPTED, H import facefusion.choices import facefusion.core -from facefusion import args_helper, session_context, state_manager, translator +from facefusion import args_helper, state_manager, translator from facefusion.apis import jobs_helper from facefusion.filesystem import create_directory, get_file_extension, is_directory from facefusion.jobs import job_helper, job_manager, job_runner @@ -117,7 +117,6 @@ async def update_jobs(request : Request) -> JSONResponse: async def update_job(request : Request) -> JSONResponse: job_id = request.path_params.get('job_id') action = request.query_params.get('action') - session_id = session_context.get_session_id() if action == 'submit': if job_manager.submit_job(job_id): @@ -135,7 +134,7 @@ async def update_job(request : Request) -> JSONResponse: if job_id in job_manager.find_job_ids('queued'): run_job_tasks = BackgroundTasks() run_job_tasks.add_task(partial(job_runner.run_job, job_id, facefusion.core.process_step)) - run_job_tasks.add_task(partial(jobs_helper.capture_output_asset, job_id, session_id)) + run_job_tasks.add_task(partial(jobs_helper.capture_output_asset, job_id)) return JSONResponse( { @@ -151,7 +150,7 @@ async def update_job(request : Request) -> JSONResponse: if job_id in job_manager.find_job_ids('failed'): retry_job_tasks = BackgroundTasks() retry_job_tasks.add_task(partial(job_runner.retry_job, job_id, facefusion.core.process_step)) - retry_job_tasks.add_task(partial(jobs_helper.capture_output_asset, job_id, session_id)) + retry_job_tasks.add_task(partial(jobs_helper.capture_output_asset, job_id)) return JSONResponse( { diff --git a/facefusion/apis/endpoints/session.py b/facefusion/apis/endpoints/session.py index eed09610..7d3382c1 100644 --- a/facefusion/apis/endpoints/session.py +++ b/facefusion/apis/endpoints/session.py @@ -21,6 +21,7 @@ async def create_session(request : Request) -> JSONResponse: session_manager.set_session(session_id, session) state_manager.init() + asset_store.init() content_store.init() face_store.init() inference_manager.init() @@ -85,7 +86,7 @@ async def destroy_session(request : Request) -> JSONResponse: destroy_stream() - asset_store.delete_assets(session_id) + asset_store.delete_assets() session_manager.clear_session(session_id) state_manager.clear() diff --git a/facefusion/apis/endpoints/state.py b/facefusion/apis/endpoints/state.py index 3cf985c9..b5618bea 100644 --- a/facefusion/apis/endpoints/state.py +++ b/facefusion/apis/endpoints/state.py @@ -2,7 +2,7 @@ from starlette.requests import Request from starlette.responses import JSONResponse, Response from starlette.status import HTTP_200_OK, HTTP_400_BAD_REQUEST, HTTP_404_NOT_FOUND, HTTP_422_UNPROCESSABLE_CONTENT -from facefusion import args_helper, capability_store, session_context, state_manager, translator +from facefusion import args_helper, capability_store, state_manager, translator from facefusion.apis import asset_store @@ -49,13 +49,12 @@ async def set_state(request : Request) -> Response: async def select_source(request : Request) -> JSONResponse: body = await request.json() asset_ids = body.get('asset_ids') - session_id = session_context.get_session_id() if isinstance(asset_ids, list): source_paths = [] for asset_id in asset_ids: - asset = asset_store.get_asset(session_id, asset_id) + asset = asset_store.get_asset(asset_id) if asset: source_paths.append(asset.get('path')) @@ -74,10 +73,9 @@ async def select_source(request : Request) -> JSONResponse: async def select_target(request : Request) -> JSONResponse: body = await request.json() asset_id = body.get('asset_id') - session_id = session_context.get_session_id() if isinstance(asset_id, str): - asset = asset_store.get_asset(session_id, asset_id) + asset = asset_store.get_asset(asset_id) if asset: state_manager.set_item('target_path', asset.get('path')) diff --git a/facefusion/apis/jobs_helper.py b/facefusion/apis/jobs_helper.py index 06c90420..5420a11a 100644 --- a/facefusion/apis/jobs_helper.py +++ b/facefusion/apis/jobs_helper.py @@ -1,14 +1,13 @@ from facefusion.apis import asset_store from facefusion.filesystem import is_file from facefusion.jobs import job_manager -from facefusion.types import SessionId -def capture_output_asset(job_id : str, session_id : SessionId) -> None: +def capture_output_asset(job_id : str) -> None: job = job_manager.read_job_file(job_id) if job and job.get('steps'): output_path = job.get('steps')[-1].get('args').get('output_path') if output_path and is_file(output_path): - asset_store.create_asset(session_id, 'output', output_path) + asset_store.create_asset('output', output_path) diff --git a/facefusion/types.py b/facefusion/types.py index 64a6edf8..a49d8b55 100755 --- a/facefusion/types.py +++ b/facefusion/types.py @@ -323,7 +323,6 @@ VideoAsset = TypedDict('VideoAsset', AssetMetadata : TypeAlias = AudioMetadata | ImageMetadata | VideoMetadata AssetSet : TypeAlias = Dict[AssetId, AudioAsset | ImageAsset | VideoAsset] -AssetStore : TypeAlias = Dict[SessionId, AssetSet] AssetAction = Literal['capture'] AssetSubject = Literal['frame', 'face']