Coverage for mindsdb / api / http / namespaces / jobs.py: 90%

52 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-21 00:36 +0000

1from http import HTTPStatus 

2 

3from flask import request, current_app as ca 

4from flask_restx import Resource 

5 

6from mindsdb.api.http.namespaces.configs.projects import ns_conf 

7from mindsdb.api.http.utils import http_error 

8from mindsdb.metrics.metrics import api_endpoint_metrics 

9 

10from mindsdb.interfaces.jobs.jobs_controller import parse_job_date 

11 

12 

13@ns_conf.route("/<project_name>/jobs") 

14class JobsResource(Resource): 

15 @ns_conf.doc("list_jobs") 

16 @api_endpoint_metrics("GET", "/jobs") 

17 def get(self, project_name): 

18 """List all jobs in a project""" 

19 return ca.jobs_controller.get_list(project_name) 

20 

21 @ns_conf.doc("create_job") 

22 @api_endpoint_metrics("POST", "/jobs") 

23 def post(self, project_name): 

24 """Create a job in a project""" 

25 

26 # Check for required parameters. 

27 if "job" not in request.json: 27 ↛ 28line 27 didn't jump to line 28 because the condition on line 27 was never true

28 return http_error(HTTPStatus.BAD_REQUEST, "Missing parameter", 'Must provide "job" parameter in POST body') 

29 

30 job = request.json["job"] 

31 

32 name = job.pop("name") 

33 if job["start_at"] is not None: 33 ↛ 35line 33 didn't jump to line 35 because the condition on line 33 was always true

34 job["start_at"] = parse_job_date(job["start_at"]) 

35 if job["end_at"] is not None: 35 ↛ 38line 35 didn't jump to line 38 because the condition on line 35 was always true

36 job["end_at"] = parse_job_date(job["end_at"]) 

37 

38 create_job_name = ca.jobs_controller.add(name, project_name, **job) 

39 

40 return ca.jobs_controller.get(create_job_name, project_name) 

41 

42 

43@ns_conf.route("/<project_name>/jobs/<job_name>") 

44@ns_conf.param("project_name", "Name of the project") 

45@ns_conf.param("job_name", "Name of the job") 

46class JobResource(Resource): 

47 @ns_conf.doc("get_job") 

48 @api_endpoint_metrics("GET", "/jobs/job") 

49 def get(self, project_name, job_name): 

50 """Gets a job by name""" 

51 job_info = ca.jobs_controller.get(job_name, project_name) 

52 if job_info is not None: 

53 return job_info 

54 

55 return http_error(HTTPStatus.NOT_FOUND, "Job not found", f"Job with name {job_name} does not exist") 

56 

57 @ns_conf.doc("delete_job") 

58 @api_endpoint_metrics("DELETE", "/jobs/job") 

59 def delete(self, project_name, job_name): 

60 """Deletes a job by name""" 

61 ca.jobs_controller.delete(job_name, project_name) 

62 

63 return "", HTTPStatus.NO_CONTENT 

64 

65 

66@ns_conf.route("/<project_name>/jobs/<job_name>/history") 

67@ns_conf.param("project_name", "Name of the project") 

68@ns_conf.param("job_name", "Name of the job") 

69class JobsHistory(Resource): 

70 @ns_conf.doc("job_history") 

71 @api_endpoint_metrics("GET", "/jobs/job/history") 

72 def get(self, project_name, job_name): 

73 """Get history of job calls""" 

74 if ca.jobs_controller.get(job_name, project_name) is None: 74 ↛ 75line 74 didn't jump to line 75 because the condition on line 74 was never true

75 return http_error(HTTPStatus.NOT_FOUND, "Job not found", f"Job with name {job_name} does not exist") 

76 

77 return ca.jobs_controller.get_history(job_name, project_name)