diff --git a/README.md b/README.md index 4d5fb94..935c612 100644 --- a/README.md +++ b/README.md @@ -109,9 +109,9 @@ curl -X POST http://localhost:8080/api/add_job \ - **UI**: View job status, progress, logs, and worker availability in real-time. - **API Endpoints**: - `GET /api/jobs`: List all jobs - - `GET /api/job/`: Get job details - - `POST /api/job//cancel`: Cancel a job - - `POST /api/job//delete`: Delete a job + - `GET /api/jobs/`: Get job details + - `POST /api/jobs//cancel`: Cancel a job + - `POST /api/jobs//delete`: Delete a job - `GET /api/status`: Get server and queue status - `GET /api/engines`: List engine information diff --git a/docs/API.md b/docs/API.md index d57be1a..526eed8 100644 --- a/docs/API.md +++ b/docs/API.md @@ -48,7 +48,7 @@ Known callers: - `RenderServerProxy.get_all_jobs()` - `src/ui/main_window.py` -### `GET /api/jobs_long_poll` +### `GET /api/jobs/long_poll` Long-polls the job list until the supplied cache token changes or 30 seconds elapse. @@ -68,7 +68,7 @@ Known callers: - `RenderServerProxy.get_all_jobs()` through the background cache updater. -### `GET /api/jobs/` +### `GET /api/jobs/status/` Returns jobs matching a render status. @@ -86,7 +86,7 @@ Responses: Review note: this route is not currently wrapped by `RenderServerProxy` and no in-repo callers were found. -### `GET /api/job/` +### `GET /api/jobs/` Returns one job as JSON. @@ -98,7 +98,7 @@ Known callers: - `src/distributed_job_manager.py` - `tests/job_creation_tests.py` -### `GET /api/job//logs` +### `GET /api/jobs//logs` Returns the job log file as `text/plain`. @@ -106,7 +106,7 @@ Known callers: - `src/ui/main_window.py` opens this URL directly. -### `GET /api/job//file_list` +### `GET /api/jobs//files` Returns a list of output filenames for the job. @@ -115,7 +115,7 @@ Known callers: - `RenderServerProxy.get_job_files_list()` - `src/utilities/server_helper.py` -### `GET /api/job//download` +### `GET /api/jobs//download` Downloads one output file. @@ -136,7 +136,7 @@ Known callers: - `RenderServerProxy.download_job_file()` - `src/utilities/server_helper.py` -### `GET /api/job//download_all` +### `GET /api/jobs//download_all` Creates a temporary zip of the job output directory and downloads it. @@ -146,7 +146,7 @@ Known callers: - `src/ui/main_window.py` - `src/utilities/server_helper.py` -### `GET /api/job//thumbnail` +### `GET /api/jobs//thumbnail` Returns a generated preview image or video for a job. @@ -207,7 +207,7 @@ Known callers: - `src/distributed_job_manager.py` - `tests/job_creation_tests.py` -### `POST /api/job//cancel` +### `POST /api/jobs//cancel` Cancels a job. @@ -224,7 +224,7 @@ Known callers: - `src/ui/main_window.py` - `src/distributed_job_manager.py` -### `POST /api/job//delete` +### `POST /api/jobs//delete` Deletes a job, stops it first, deletes previews, and removes owned upload/output directories when safe. @@ -240,7 +240,7 @@ Known callers: - `RenderServerProxy.delete_job()` - `src/ui/main_window.py` -### `POST /api/job//send_subjob_update_notification` +### `POST /api/jobs//subjob_update` Notifies a parent job that a child/subjob changed state. @@ -498,7 +498,7 @@ Likely redundant or overlapping routes: used internally by `/api/full_status`. Routes with no in-repo callers found: -- `GET /api/jobs/` +- `GET /api/jobs/status/` - `GET /api/presets` - `GET /api/disk_benchmark` - `GET /api/engines//args` diff --git a/docs/api.html b/docs/api.html index b4a65b1..22fb700 100644 --- a/docs/api.html +++ b/docs/api.html @@ -288,7 +288,7 @@
-
GET/api/jobs_long_poll
+
GET/api/jobs/long_poll

Long-polls the job list until the supplied cache token changes or 30 seconds elapse.

@@ -298,30 +298,30 @@
-
GET/api/jobs/<status_val>
+
GET/api/jobs/status/<status_val>

Returns jobs matching a render status converted by string_to_status().

No RenderServerProxy wrapper or in-repo caller was found.
-
GET/api/job/<job_id>
+
GET/api/jobs/<job_id>

Returns one job as JSON.

Known callers include RenderServerProxy.get_job_info(), add_job.py, src/ui/main_window.py, src/distributed_job_manager.py, and tests/job_creation_tests.py.

-
GET/api/job/<job_id>/logs
+
GET/api/jobs/<job_id>/logs

Returns the job log file as text/plain. The main window opens this URL directly.

-
GET/api/job/<job_id>/file_list
+
GET/api/jobs/<job_id>/files

Returns a list of output filenames for the job.

Known callers: RenderServerProxy.get_job_files_list() and src/utilities/server_helper.py.

-
GET/api/job/<job_id>/download
+
GET/api/jobs/<job_id>/download

Downloads one output file.

Query ParameterRequiredDescription
@@ -331,13 +331,13 @@
-
GET/api/job/<job_id>/download_all
+
GET/api/jobs/<job_id>/download_all

Creates a temporary zip of the job output directory and downloads it.

Known callers: RenderServerProxy.download_all_job_files(), src/ui/main_window.py, and src/utilities/server_helper.py.

-
GET/api/job/<job_id>/thumbnail
+
GET/api/jobs/<job_id>/thumbnail

Returns a generated preview image or video for a job.

Query ParameterRequiredDescription
@@ -369,7 +369,7 @@
-
POST/api/job/<job_id>/cancel
+
POST/api/jobs/<job_id>/cancel

Cancels a job. Requires a truthy confirm query parameter.

Query ParameterRequiredDescription
@@ -379,7 +379,7 @@
-
POST/api/job/<job_id>/delete
+
POST/api/jobs/<job_id>/delete

Deletes a job, stops it first, deletes previews, and removes owned upload/output directories when safe.

Query ParameterRequiredDescription
@@ -388,7 +388,7 @@
-
POST/api/job/<job_id>/send_subjob_update_notification
+
POST/api/jobs/<job_id>/subjob_update

Notifies a parent job that a child/subjob changed state. The request body is the JSON representation of the subjob.

@@ -571,7 +571,7 @@

Routes With No In-Repo Callers Found

    -
  • GET /api/jobs/<status_val>
  • +
  • GET /api/jobs/status/<status_val>
  • GET /api/presets
  • GET /api/disk_benchmark
  • GET /api/engines/<engine_name>/args
  • diff --git a/src/api/api_server.py b/src/api/api_server.py index 7124327..6aaf249 100755 --- a/src/api/api_server.py +++ b/src/api/api_server.py @@ -84,7 +84,7 @@ def jobs_json() -> Dict[str, Any]: return {'jobs': all_jobs, 'token': job_cache_token} -@server.get('/api/jobs_long_poll') +@server.get('/api/jobs/long_poll') def long_polling_jobs(): hash_token = request.args.get('token', None) start_time = time.time() @@ -98,7 +98,7 @@ def long_polling_jobs(): time.sleep(1) -@server.get('/api/jobs/') +@server.get('/api/jobs/status/') def filtered_jobs_json(status_val): state = string_to_status(status_val) jobs = [x.json() for x in RenderQueue.jobs_with_status(state)] @@ -112,7 +112,7 @@ def filtered_jobs_json(status_val): # Job Details / File Handling # -------------------------------------------- -@server.get('/api/job/') +@server.get('/api/jobs/') def get_job_details(job_id): """Retrieves the details of a requested job in JSON format @@ -125,7 +125,7 @@ def get_job_details(job_id): return RenderQueue.job_with_id(job_id).json() -@server.get('/api/job//logs') +@server.get('/api/jobs//logs') def get_job_logs(job_id): """Retrieves the log file for a specific render job. @@ -144,12 +144,12 @@ def get_job_logs(job_id): return Response(log_data, mimetype='text/plain') -@server.get('/api/job//file_list') -def get_file_list(job_id): - return [Path(p).name for p in RenderQueue.job_with_id(job_id).file_list()] +@server.get('/api/jobs//files') +def get_job_files(job_id): + return [Path(p).name for p in RenderQueue.job_with_id(job_id).file_list()] -@server.route('/api/job//download') +@server.route('/api/jobs//download') def download_requested_file(job_id): requested_filename = request.args.get("filename") if not requested_filename: @@ -165,7 +165,7 @@ def download_requested_file(job_id): return f"File '{requested_filename}' not found", 404 -@server.route('/api/job//download_all') +@server.route('/api/jobs//download_all') def download_all_files(job_id): zip_filename = None @@ -307,7 +307,7 @@ def add_job_handler(): return 'unknown error', 500 -@server.post('/api/job//cancel') +@server.post('/api/jobs//cancel') def cancel_job(job_id): if not request.args.get('confirm', False): return 'Confirmation required to cancel job', 400 @@ -321,7 +321,7 @@ def cancel_job(job_id): return "Unknown error", 500 -@server.post('/api/job//delete') +@server.post('/api/jobs//delete') def delete_job(job_id): try: if not request.args.get("confirm", False): @@ -543,14 +543,14 @@ def delete_engine_download(): def heartbeat(): return datetime.now().isoformat(), 200 -@server.post('/api/job//send_subjob_update_notification') +@server.post('/api/jobs//subjob_update') def subjob_update_notification(job_id): subjob_details = request.json DistributedJobManager.handle_subjob_update_notification(RenderQueue.job_with_id(job_id), subjob_data=subjob_details) return Response(status=200) -@server.route('/api/job//thumbnail') +@server.route('/api/jobs//thumbnail') def job_thumbnail(job_id): try: diff --git a/src/api/server_proxy.py b/src/api/server_proxy.py index 76bde84..50c3edd 100644 --- a/src/api/server_proxy.py +++ b/src/api/server_proxy.py @@ -139,7 +139,7 @@ class RenderServerProxy: if self.__offline_flags: # if we're offline, don't bother with the long poll ignore_token = True - url = f'jobs_long_poll?token={self.__jobs_cache_token}' if (self.__jobs_cache_token and + url = f'jobs/long_poll?token={self.__jobs_cache_token}' if (self.__jobs_cache_token and not ignore_token) else 'jobs' status_result = self.request_data(url, timeout=timeout) if status_result is not None: @@ -181,10 +181,10 @@ class RenderServerProxy: # -------------------------------------------- def get_job_info(self, job_id, timeout=5): - return self.request_data(f'job/{job_id}', timeout=timeout) + return self.request_data(f'jobs/{job_id}', timeout=timeout) def get_job_files_list(self, job_id): - return self.request_data(f"job/{job_id}/file_list") + return self.request_data(f'jobs/{job_id}/files') # -------------------------------------------- # Job Lifecycle: @@ -230,10 +230,10 @@ class RenderServerProxy: return response def cancel_job(self, job_id, confirm=False): - return self._post(f'job/{job_id}/cancel', params={'confirm': confirm}) + return self._post(f'jobs/{job_id}/cancel', params={'confirm': confirm}) def delete_job(self, job_id, confirm=False): - return self._post(f'job/{job_id}/delete', params={'confirm': confirm}) + return self._post(f'jobs/{job_id}/delete', params={'confirm': confirm}) def send_subjob_update_notification(self, parent_id, subjob): """ @@ -246,7 +246,7 @@ class RenderServerProxy: Returns: Response: The response from the server. """ - return requests.post(f'http://{self.hostname}:{self.port}/api/job/{parent_id}/send_subjob_update_notification', + return requests.post(f'http://{self.hostname}:{self.port}/api/jobs/{parent_id}/subjob_update', json=subjob.json()) # -------------------------------------------- @@ -312,11 +312,11 @@ class RenderServerProxy: # -------------------------------------------- def download_all_job_files(self, job_id, save_path): - url = f"http://{self.hostname}:{self.port}/api/job/{job_id}/download_all" + url = f'http://{self.hostname}:{self.port}/api/jobs/{job_id}/download_all' return self.__download_file_from_url(url, output_filepath=save_path) def download_job_file(self, job_id, job_filename, save_path): - url = f"http://{self.hostname}:{self.port}/api/job/{job_id}/download?filename={job_filename}" + url = f'http://{self.hostname}:{self.port}/api/jobs/{job_id}/download?filename={job_filename}' return self.__download_file_from_url(url, output_filepath=save_path) @staticmethod diff --git a/src/ui/main_window.py b/src/ui/main_window.py index daa3871..ca5803b 100644 --- a/src/ui/main_window.py +++ b/src/ui/main_window.py @@ -334,7 +334,7 @@ class MainWindow(QMainWindow): default_image_path = "error.png" before_fetch_hostname = self.current_server_proxy.hostname - response = self.current_server_proxy.request(f'job/{job_id}/thumbnail?size=big') + response = self.current_server_proxy.request(f'jobs/{job_id}/thumbnail?size=big') if response.ok: try: with io.BytesIO(response.content) as image_data_stream: @@ -547,7 +547,8 @@ class MainWindow(QMainWindow): """ selected_job_ids = self.selected_job_ids() if selected_job_ids: - url = f'http://{self.current_server_proxy.hostname}:{self.current_server_proxy.port}/api/job/{selected_job_ids[0]}/logs' + url = (f'http://{self.current_server_proxy.hostname}:{self.current_server_proxy.port}' + f'/api/jobs/{selected_job_ids[0]}/logs') self.log_viewer_window = LogViewer(url) self.log_viewer_window.show() @@ -616,8 +617,8 @@ class MainWindow(QMainWindow): return import webbrowser - download_url = (f"http://{self.current_server_proxy.hostname}:{self.current_server_proxy.port}" - f"/api/job/{job_ids[0]}/download_all") + download_url = (f'http://{self.current_server_proxy.hostname}:{self.current_server_proxy.port}' + f'/api/jobs/{job_ids[0]}/download_all') webbrowser.open(download_url) def open_files(self, event):
Query ParameterRequiredDescription