first piece for /jobs endpoint part2

This commit is contained in:
henryruhs
2026-08-24 00:17:51 +02:00
parent 2e54b6d0dd
commit 6b81f6728b
4 changed files with 111 additions and 3 deletions
+3 -1
View File
@@ -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
from facefusion.apis.endpoints.jobs import create_job, get_job, get_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
@@ -48,6 +48,8 @@ def create_api() -> Starlette:
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/{job_id}', get_job, methods = [ 'GET' ], middleware = [ session_guard ]),
Route('/jobs', create_job, methods = [ 'POST' ], middleware = [ session_guard ]),
WebSocketRoute('/metrics', websocket_metrics, middleware = [ session_guard ]),
WebSocketRoute('/ping', websocket_ping, middleware = [ session_guard ]),
+38 -1
View File
@@ -1,11 +1,48 @@
from starlette.requests import Request
from starlette.responses import JSONResponse
from starlette.status import HTTP_201_CREATED, HTTP_400_BAD_REQUEST
from starlette.status import HTTP_200_OK, HTTP_201_CREATED, HTTP_400_BAD_REQUEST, HTTP_404_NOT_FOUND
import facefusion.choices
from facefusion import translator
from facefusion.jobs import job_helper, job_manager
async def get_jobs(request : Request) -> JSONResponse:
job_status = request.query_params.get('status')
if job_status in facefusion.choices.job_statuses:
job_set = job_manager.find_jobs(job_status)
job_summaries = {}
for job_id, job in job_set.items():
job_summaries[job_id] =\
{
'version': job.get('version'),
'date_created': job.get('date_created'),
'date_updated': job.get('date_updated')
}
return JSONResponse(job_summaries, status_code = HTTP_200_OK)
return JSONResponse(
{
'message': translator.get('invalid_job_status', 'facefusion.apis')
}, status_code = HTTP_400_BAD_REQUEST)
async def get_job(request : Request) -> JSONResponse:
job_id = request.path_params.get('job_id')
job = job_manager.read_job_file(job_id)
if job:
return JSONResponse(job, status_code = HTTP_200_OK)
return JSONResponse(
{
'message': translator.get('job_not_found', 'facefusion.apis')
}, status_code = HTTP_404_NOT_FOUND)
async def create_job(request : Request) -> JSONResponse:
job_id = job_helper.suggest_job_id()
+2
View File
@@ -11,6 +11,8 @@ LOCALES : Locales =\
'source_asset_not_found': 'source asset not found',
'target_asset_not_found': 'target asset not found',
'invalid_state_key': 'invalid state key',
'invalid_job_status': 'invalid job status',
'job_not_found': 'job not found',
'job_not_created': 'job not created'
}
}
+68 -1
View File
@@ -6,7 +6,7 @@ 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, find_job_ids, init_jobs
from facefusion.jobs.job_manager import clear_jobs, create_job, find_job_ids, init_jobs
from .assert_helper import get_test_jobs_directory
@@ -23,6 +23,73 @@ def test_client() -> Iterator[TestClient]:
yield test_client
def test_get_jobs(test_client : TestClient) -> None:
get_jobs_response = test_client.get('/jobs?status=drafted')
assert get_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')
get_jobs_response = test_client.get('/jobs?status=invalid', headers =
{
'Authorization': 'Bearer ' + access_token
})
get_jobs_body = get_jobs_response.json()
assert get_jobs_body.get('message') == 'invalid job status'
assert get_jobs_response.status_code == 400
create_job('job-test-get-jobs')
get_jobs_response = test_client.get('/jobs?status=drafted', headers =
{
'Authorization': 'Bearer ' + access_token
})
get_jobs_body = get_jobs_response.json()
assert 'job-test-get-jobs' in get_jobs_body
assert get_jobs_body.get('job-test-get-jobs').get('step_total') == 0
assert get_jobs_response.status_code == 200
def test_get_job(test_client : TestClient) -> None:
get_job_response = test_client.get('/jobs/job-test-get-job')
assert get_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')
get_job_response = test_client.get('/jobs/job-test-unknown', headers =
{
'Authorization': 'Bearer ' + access_token
})
get_job_body = get_job_response.json()
assert get_job_body.get('message') == 'job not found'
assert get_job_response.status_code == 404
create_job('job-test-get-job')
get_job_response = test_client.get('/jobs/job-test-get-job', headers =
{
'Authorization': 'Bearer ' + access_token
})
get_job_body = get_job_response.json()
assert get_job_body.get('version') == '1'
assert get_job_response.status_code == 200
def test_create_job(test_client : TestClient) -> None:
create_job_response = test_client.post('/jobs')