From 1bae62ad266a2840e8e52a1282c6ee1227afacd4 Mon Sep 17 00:00:00 2001 From: henryruhs Date: Mon, 24 Aug 2026 09:11:22 +0200 Subject: [PATCH] first piece for /jobs endpoint part7 --- facefusion/apis/core.py | 58 +++++++++++++++---------------- facefusion/apis/endpoints/jobs.py | 4 +-- facefusion/args_helper.py | 10 +++++- facefusion/core.py | 10 +++--- tests/test_api_jobs.py | 14 ++++++++ 5 files changed, 59 insertions(+), 37 deletions(-) diff --git a/facefusion/apis/core.py b/facefusion/apis/core.py index bee0e3ba..b0b8d64c 100644 --- a/facefusion/apis/core.py +++ b/facefusion/apis/core.py @@ -33,35 +33,35 @@ def pre_check() -> bool: def create_api() -> Starlette: session_guard = Middleware(create_session_guard) routes =\ - [ - Route('/session', create_session, methods = [ 'POST' ]), - Route('/session', get_session, methods = [ 'GET' ], middleware = [ session_guard ]), - Route('/session', refresh_session, methods = [ 'PUT' ]), - Route('/session', destroy_session, methods = [ 'DELETE' ], middleware = [ session_guard ]), - Route('/state', get_state, methods = [ 'GET' ], middleware = [ session_guard ]), - Route('/state', set_state, methods = [ 'PUT' ], middleware = [ session_guard ]), - Route('/assets', get_assets, methods = [ 'GET' ], middleware = [ session_guard ]), - Route('/assets', upload_asset, methods = [ 'POST' ], middleware = [ session_guard ]), - Route('/assets/{asset_id}', get_asset, methods = [ 'GET' ], middleware = [ session_guard ]), - Route('/assets', delete_assets, methods = [ 'DELETE' ], middleware = [ session_guard ]), - Route('/capabilities', get_capabilities, methods = [ 'GET' ]), - Route('/metrics', get_metrics, methods = [ 'GET' ], middleware = [ session_guard ]), - Route('/stream', post_stream, methods = [ 'POST' ], middleware = [ session_guard ]), - Route('/stream', delete_stream, methods = [ 'DELETE' ], name = 'delete_stream', middleware = [ session_guard ]), - Route('/jobs', get_jobs, methods = [ 'GET' ], middleware = [ session_guard ]), - Route('/jobs', create_job, methods = [ 'POST' ], middleware = [ session_guard ]), - Route('/jobs', update_jobs, methods = [ 'PATCH' ], middleware = [ session_guard ]), - Route('/jobs', delete_jobs, methods = [ 'DELETE' ], middleware = [ session_guard ]), - Route('/jobs/{job_id}', get_job, methods = [ 'GET' ], middleware = [ session_guard ]), - Route('/jobs/{job_id}', create_step, methods = [ 'POST' ], middleware = [ session_guard ]), - Route('/jobs/{job_id}', update_job, methods = [ 'PATCH' ], middleware = [ session_guard ]), - Route('/jobs/{job_id}', delete_job, methods = [ 'DELETE' ], middleware = [ session_guard ]), - Route('/jobs/{job_id}/{step_index:int}', create_step, methods = [ 'POST' ], middleware = [ session_guard ]), - Route('/jobs/{job_id}/{step_index:int}', delete_step, methods = [ 'DELETE' ], middleware = [ session_guard ]), - WebSocketRoute('/metrics', websocket_metrics, middleware = [ session_guard ]), - WebSocketRoute('/ping', websocket_ping, middleware = [ session_guard ]), - WebSocketRoute('/stream', websocket_stream, middleware = [ session_guard ]) - ] + [ + Route('/session', create_session, methods = [ 'POST' ]), + Route('/session', get_session, methods = [ 'GET' ], middleware = [ session_guard ]), + Route('/session', refresh_session, methods = [ 'PUT' ]), + Route('/session', destroy_session, methods = [ 'DELETE' ], middleware = [ session_guard ]), + Route('/state', get_state, methods = [ 'GET' ], middleware = [ session_guard ]), + Route('/state', set_state, methods = [ 'PUT' ], middleware = [ session_guard ]), + Route('/assets', get_assets, methods = [ 'GET' ], middleware = [ session_guard ]), + Route('/assets', upload_asset, methods = [ 'POST' ], middleware = [ session_guard ]), + Route('/assets/{asset_id}', get_asset, methods = [ 'GET' ], middleware = [ session_guard ]), + Route('/assets', delete_assets, methods = [ 'DELETE' ], middleware = [ session_guard ]), + Route('/capabilities', get_capabilities, methods = [ 'GET' ]), + Route('/metrics', get_metrics, methods = [ 'GET' ], middleware = [ session_guard ]), + Route('/stream', post_stream, methods = [ 'POST' ], middleware = [ session_guard ]), + Route('/stream', delete_stream, methods = [ 'DELETE' ], name = 'delete_stream', middleware = [ session_guard ]), + Route('/jobs', get_jobs, methods = [ 'GET' ], middleware = [ session_guard ]), + Route('/jobs', create_job, methods = [ 'POST' ], middleware = [ session_guard ]), + Route('/jobs', update_jobs, methods = [ 'PATCH' ], middleware = [ session_guard ]), + Route('/jobs', delete_jobs, methods = [ 'DELETE' ], middleware = [ session_guard ]), + Route('/jobs/{job_id}', get_job, methods = [ 'GET' ], middleware = [ session_guard ]), + Route('/jobs/{job_id}', create_step, methods = [ 'POST' ], middleware = [ session_guard ]), + Route('/jobs/{job_id}', update_job, methods = [ 'PATCH' ], middleware = [ session_guard ]), + Route('/jobs/{job_id}', delete_job, methods = [ 'DELETE' ], middleware = [ session_guard ]), + Route('/jobs/{job_id}/{step_index:int}', create_step, methods = [ 'POST' ], middleware = [ session_guard ]), + Route('/jobs/{job_id}/{step_index:int}', delete_step, methods = [ 'DELETE' ], middleware = [ session_guard ]), + WebSocketRoute('/metrics', websocket_metrics, middleware = [ session_guard ]), + WebSocketRoute('/ping', websocket_ping, middleware = [ session_guard ]), + WebSocketRoute('/stream', websocket_stream, middleware = [ session_guard ]) + ] api = Starlette(routes = routes) api.add_middleware(CORSMiddleware, allow_origins = [ '*' ], allow_methods = [ '*' ], allow_headers = [ '*' ]) diff --git a/facefusion/apis/endpoints/jobs.py b/facefusion/apis/endpoints/jobs.py index 24cff175..d4bd59df 100644 --- a/facefusion/apis/endpoints/jobs.py +++ b/facefusion/apis/endpoints/jobs.py @@ -7,7 +7,7 @@ from starlette.status import HTTP_200_OK, HTTP_201_CREATED, HTTP_202_ACCEPTED, H import facefusion.choices import facefusion.core -from facefusion import state_manager, translator +from facefusion import args_helper, state_manager, translator from facefusion.jobs import job_helper, job_manager, job_runner @@ -189,7 +189,7 @@ async def create_step(request : Request) -> JSONResponse: job_id = request.path_params.get('job_id') step_index = request.path_params.get('step_index') action = request.query_params.get('action') - step_args = await request.json() + step_args = args_helper.filter_api_step_args(await request.json()) if action == 'add': if job_manager.add_step(job_id, step_args): diff --git a/facefusion/args_helper.py b/facefusion/args_helper.py index 171e5a92..59332581 100644 --- a/facefusion/args_helper.py +++ b/facefusion/args_helper.py @@ -123,7 +123,15 @@ def extract_step_args(state : Union[State, ProcessorState]) -> Args: return step_args -def filter_step_args(args : Args) -> Args: +def filter_api_step_args(args : Args) -> Args: + step_args =\ + { + key: args.get(key) for key in args if key in get_api_arguments() and key not in get_sys_arguments() + } + return step_args + + +def filter_cli_step_args(args : Args) -> Args: step_args =\ { key: args.get(key) for key in args if key in get_cli_arguments() and key not in get_sys_arguments() diff --git a/facefusion/core.py b/facefusion/core.py index 4c27c00b..3c78163c 100755 --- a/facefusion/core.py +++ b/facefusion/core.py @@ -182,7 +182,7 @@ def route_job_manager(args : Args) -> ErrorCode: return 1 if state_manager.get_item('command') == 'job-add-step': - step_args = args_helper.filter_step_args(args) + step_args = args_helper.filter_cli_step_args(args) if job_manager.add_step(state_manager.get_item('job_id'), step_args): logger.info(translator.get('job_step_added').format(job_id = state_manager.get_item('job_id')), __name__) @@ -191,7 +191,7 @@ def route_job_manager(args : Args) -> ErrorCode: return 1 if state_manager.get_item('command') == 'job-remix-step': - step_args = args_helper.filter_step_args(args) + step_args = args_helper.filter_cli_step_args(args) if job_manager.remix_step(state_manager.get_item('job_id'), state_manager.get_item('step_index'), step_args): logger.info(translator.get('job_remix_step_added').format(job_id = state_manager.get_item('job_id'), step_index = state_manager.get_item('step_index')), __name__) @@ -200,7 +200,7 @@ def route_job_manager(args : Args) -> ErrorCode: return 1 if state_manager.get_item('command') == 'job-insert-step': - step_args = args_helper.filter_step_args(args) + step_args = args_helper.filter_cli_step_args(args) if job_manager.insert_step(state_manager.get_item('job_id'), state_manager.get_item('step_index'), step_args): logger.info(translator.get('job_step_inserted').format(job_id = state_manager.get_item('job_id'), step_index = state_manager.get_item('step_index')), __name__) @@ -254,7 +254,7 @@ def route_job_runner() -> ErrorCode: def process_headless(args : Args) -> ErrorCode: job_id = job_helper.suggest_job_id('headless') - step_args = args_helper.filter_step_args(args) + step_args = args_helper.filter_cli_step_args(args) if job_manager.create_job(job_id) and job_manager.add_step(job_id, step_args) and job_manager.submit_job(job_id) and job_runner.run_job(job_id, process_step): return 0 @@ -263,7 +263,7 @@ def process_headless(args : Args) -> ErrorCode: def process_batch(args : Args) -> ErrorCode: job_id = job_helper.suggest_job_id('batch') - step_args = args_helper.filter_step_args(args) + step_args = args_helper.filter_cli_step_args(args) source_paths = resolve_file_pattern(step_args.get('source_pattern')) target_paths = resolve_file_pattern(step_args.get('target_pattern')) diff --git a/tests/test_api_jobs.py b/tests/test_api_jobs.py index c6a6d66c..64f892b7 100644 --- a/tests/test_api_jobs.py +++ b/tests/test_api_jobs.py @@ -7,9 +7,15 @@ from starlette.testclient import TestClient from facefusion import metadata, session_manager from facefusion.apis.core import create_api from facefusion.jobs.job_manager import clear_jobs, count_step_total, create_job, find_job_ids, init_jobs +from facefusion.program import create_program from .assert_helper import get_test_jobs_directory +@pytest.fixture(scope = 'module', autouse = True) +def before_all() -> None: + create_program() + + @pytest.fixture(scope = 'function', autouse = True) def before_each() -> None: session_manager.SESSIONS.clear() @@ -447,6 +453,14 @@ def test_create_step(test_client : TestClient) -> None: assert count_step_total('job-test-create-step') == 1 assert create_step_response.status_code == 201 + get_job_response = test_client.get('/jobs/job-test-create-step', headers = + { + 'Authorization': 'Bearer ' + access_token + }) + get_job_body = get_job_response.json() + + assert get_job_body.get('steps')[0].get('args') == { 'processors': [ 'face_swapper' ] } + create_step_response = test_client.post('/jobs/job-test-create-step/0?action=insert', headers = { 'Authorization': 'Bearer ' + access_token