From eb60333f19d3cad8e700416442f71f9678a53c92 Mon Sep 17 00:00:00 2001 From: henryruhs Date: Mon, 24 Aug 2026 02:34:20 +0200 Subject: [PATCH] first piece for /jobs endpoint part4 --- facefusion/apis/core.py | 4 +- facefusion/apis/endpoints/jobs.py | 32 +++++++++++++- facefusion/apis/locales.py | 6 ++- tests/test_api_jobs.py | 72 ++++++++++++++++++++++++++++++- 4 files changed, 108 insertions(+), 6 deletions(-) diff --git a/facefusion/apis/core.py b/facefusion/apis/core.py index 6c74e504..352378f0 100644 --- a/facefusion/apis/core.py +++ b/facefusion/apis/core.py @@ -8,7 +8,7 @@ from starlette.routing import Route, WebSocketRoute from facefusion.apis.endpoints.assets import delete_assets, get_asset, get_assets, upload_asset from facefusion.apis.endpoints.capabilities import get_capabilities -from facefusion.apis.endpoints.jobs import create_job, delete_job, delete_jobs, get_job, get_jobs +from facefusion.apis.endpoints.jobs import create_job, delete_job, delete_jobs, get_job, get_jobs, submit_job, submit_jobs from facefusion.apis.endpoints.metrics import get_metrics, websocket_metrics from facefusion.apis.endpoints.ping import websocket_ping from facefusion.apis.endpoints.session import create_session, destroy_session, get_session, refresh_session @@ -50,8 +50,10 @@ def create_api() -> Starlette: 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/submit', submit_jobs, methods = [ 'PUT' ], 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}/submit', submit_job, methods = [ 'PUT' ], middleware = [ session_guard ]), Route('/jobs/{job_id}', delete_job, methods = [ 'DELETE' ], middleware = [ session_guard ]), WebSocketRoute('/metrics', websocket_metrics, middleware = [ session_guard ]), WebSocketRoute('/ping', websocket_ping, middleware = [ session_guard ]), diff --git a/facefusion/apis/endpoints/jobs.py b/facefusion/apis/endpoints/jobs.py index b724bca8..2941fbc6 100644 --- a/facefusion/apis/endpoints/jobs.py +++ b/facefusion/apis/endpoints/jobs.py @@ -58,6 +58,34 @@ async def create_job(request : Request) -> JSONResponse: }, status_code = HTTP_400_BAD_REQUEST) +async def submit_jobs(request : Request) -> JSONResponse: + if job_manager.submit_jobs(state_manager.get_item('halt_on_error')): + return JSONResponse( + { + 'message': translator.get('ok', 'facefusion.apis') + }, status_code = HTTP_200_OK) + + return JSONResponse( + { + 'message': translator.get('job_all_not_submitted', 'facefusion.apis') + }, status_code = HTTP_400_BAD_REQUEST) + + +async def submit_job(request : Request) -> JSONResponse: + job_id = request.path_params.get('job_id') + + if job_manager.submit_job(job_id): + return JSONResponse( + { + 'message': translator.get('ok', 'facefusion.apis') + }, status_code = HTTP_200_OK) + + return JSONResponse( + { + 'message': translator.get('job_not_submitted', 'facefusion.apis') + }, status_code = HTTP_400_BAD_REQUEST) + + async def delete_jobs(request : Request) -> JSONResponse: if job_manager.delete_jobs(state_manager.get_item('halt_on_error')): return JSONResponse( @@ -67,7 +95,7 @@ async def delete_jobs(request : Request) -> JSONResponse: return JSONResponse( { - 'message': translator.get('job_not_found', 'facefusion.apis') + 'message': translator.get('job_all_not_deleted', 'facefusion.apis') }, status_code = HTTP_404_NOT_FOUND) @@ -82,5 +110,5 @@ async def delete_job(request : Request) -> JSONResponse: return JSONResponse( { - 'message': translator.get('job_not_found', 'facefusion.apis') + 'message': translator.get('job_not_deleted', 'facefusion.apis') }, status_code = HTTP_404_NOT_FOUND) diff --git a/facefusion/apis/locales.py b/facefusion/apis/locales.py index 8d74da30..d4ff2496 100644 --- a/facefusion/apis/locales.py +++ b/facefusion/apis/locales.py @@ -13,6 +13,10 @@ LOCALES : Locales =\ 'invalid_state_key': 'invalid state key', 'invalid_job_status': 'invalid job status', 'job_not_found': 'job not found', - 'job_not_created': 'job not created' + 'job_not_created': 'job not created', + 'job_not_submitted': 'job not submitted', + 'job_not_deleted': 'job not deleted', + 'job_all_not_submitted': 'jobs not submitted', + 'job_all_not_deleted': 'jobs not deleted' } } diff --git a/tests/test_api_jobs.py b/tests/test_api_jobs.py index e3d4d05a..25b5b0ff 100644 --- a/tests/test_api_jobs.py +++ b/tests/test_api_jobs.py @@ -128,6 +128,74 @@ def test_create_job(test_client : TestClient) -> None: assert create_job_response.status_code == 400 +def test_submit_jobs(test_client : TestClient) -> None: + submit_jobs_response = test_client.put('/jobs/submit') + + assert submit_jobs_response.status_code == 401 + + create_session_response = test_client.post('/session', json = + { + 'client_version': metadata.get('version') + }) + create_session_body = create_session_response.json() + access_token = create_session_body.get('access_token') + + create_job('job-test-submit-jobs') + + submit_jobs_response = test_client.put('/jobs/submit', headers = + { + 'Authorization': 'Bearer ' + access_token + }) + submit_jobs_body = submit_jobs_response.json() + + assert submit_jobs_body.get('message') == 'jobs not submitted' + assert submit_jobs_response.status_code == 400 + + with patch('facefusion.jobs.job_manager.submit_jobs', return_value = True): + submit_jobs_response = test_client.put('/jobs/submit', headers = + { + 'Authorization': 'Bearer ' + access_token + }) + submit_jobs_body = submit_jobs_response.json() + + assert submit_jobs_body.get('message') == 'ok' + assert submit_jobs_response.status_code == 200 + + +def test_submit_job(test_client : TestClient) -> None: + submit_job_response = test_client.put('/jobs/job-test-submit-job/submit') + + assert submit_job_response.status_code == 401 + + create_session_response = test_client.post('/session', json = + { + 'client_version': metadata.get('version') + }) + create_session_body = create_session_response.json() + access_token = create_session_body.get('access_token') + + create_job('job-test-submit-job') + + submit_job_response = test_client.put('/jobs/job-test-submit-job/submit', headers = + { + 'Authorization': 'Bearer ' + access_token + }) + submit_job_body = submit_job_response.json() + + assert submit_job_body.get('message') == 'job not submitted' + assert submit_job_response.status_code == 400 + + with patch('facefusion.jobs.job_manager.submit_job', return_value = True): + submit_job_response = test_client.put('/jobs/job-test-submit-job/submit', headers = + { + 'Authorization': 'Bearer ' + access_token + }) + submit_job_body = submit_job_response.json() + + assert submit_job_body.get('message') == 'ok' + assert submit_job_response.status_code == 200 + + def test_delete_jobs(test_client : TestClient) -> None: delete_jobs_response = test_client.delete('/jobs') @@ -146,7 +214,7 @@ def test_delete_jobs(test_client : TestClient) -> None: }) delete_jobs_body = delete_jobs_response.json() - assert delete_jobs_body.get('message') == 'job not found' + assert delete_jobs_body.get('message') == 'jobs not deleted' assert delete_jobs_response.status_code == 404 create_job('job-test-delete-jobs-1') @@ -179,7 +247,7 @@ def test_delete_job(test_client : TestClient) -> None: }) delete_job_body = delete_job_response.json() - assert delete_job_body.get('message') == 'job not found' + assert delete_job_body.get('message') == 'job not deleted' assert delete_job_response.status_code == 404 create_job('job-test-delete-job')