Coverage for streamwise/job_manager.py: 72%
36 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 04:47 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 04:47 +0000
1"""
2Submit jobs to services in the cluster.
3"""
5import sys
6import logging
8from aiohttp import ClientTimeout
9from asyncio import TimeoutError
11from http import HTTPStatus
13from quart import request
14from quart import jsonify
15from quart import Response
17import http_session_manager
19sys.path.append("..")
20from quart_utils import QuartReturn
23# HTTP clients
24JSON_HEADER = {
25 "Content-Type": "application/json"
26}
27GENERATION_TIMEOUT = ClientTimeout(
28 total=60.0,
29 connect=5.0)
32async def submit_job(
33 service_name: str,
34 container_ip: str,
35 container_port: int
36) -> QuartReturn:
37 """API interface to submit a job to the specified service."""
38 if not service_name or not container_ip or not container_port:
39 return jsonify({"error": "Service name, container IP and port are required"}), HTTPStatus.BAD_REQUEST
40 try:
41 payload_json = await request.get_json()
42 if not payload_json:
43 return jsonify({"error": "No job data provided"}), HTTPStatus.BAD_REQUEST
45 url = f"{http_session_manager.SERVICE_SCHEME}://{container_ip}:{container_port}/{service_name}"
46 session = await http_session_manager.get_global_session()
47 async with session.post(url, json=payload_json, headers=JSON_HEADER, timeout=GENERATION_TIMEOUT) as response:
48 content_type = response.headers.get("Content-Type", "application/octet-stream")
49 data = await response.read()
50 headers = {}
51 content_disposition = response.headers.get("Content-Disposition")
52 if content_disposition:
53 headers["Content-Disposition"] = content_disposition
54 return Response(
55 response=data,
56 status=response.status,
57 headers=headers,
58 content_type=content_type)
59 except TimeoutError:
60 logging.error(f"Timeout submitting job to {service_name} at {container_ip}:{container_port}.")
61 return jsonify({"error": "Request timed out"}), HTTPStatus.GATEWAY_TIMEOUT
62 except Exception as ex:
63 logging.error(f"Error submitting job to {service_name} at {container_ip}:{container_port}: {ex}")
64 return jsonify({"error": str(ex)}), HTTPStatus.INTERNAL_SERVER_ERROR