Coverage for mindsdb / api / http / namespaces / views.py: 88%
97 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
1from http import HTTPStatus
3from flask import request
4from flask_restx import Resource
6from mindsdb.api.http.utils import http_error
7from mindsdb.api.http.namespaces.configs.projects import ns_conf
8from mindsdb.api.executor.controllers.session_controller import SessionController
9from mindsdb.metrics.metrics import api_endpoint_metrics
10from mindsdb.utilities.exception import EntityNotExistsError
13@ns_conf.route("/<project_name>/views")
14class ViewsList(Resource):
15 @ns_conf.doc("list_views")
16 @api_endpoint_metrics("GET", "/views")
17 def get(self, project_name):
18 """List all views"""
19 session = SessionController()
20 try:
21 project = session.database_controller.get_project(project_name)
22 except EntityNotExistsError:
23 return http_error(HTTPStatus.NOT_FOUND, "Project not found", f"Project name {project_name} does not exist")
25 all_views = project.get_views()
26 all_view_objs = []
27 # Only want to return relevant fields to the user.
28 for view in all_views:
29 all_view_objs.append({"id": view["metadata"]["id"], "name": view["name"], "query": view["query"]})
30 return all_view_objs
32 @ns_conf.doc("create_view")
33 @api_endpoint_metrics("POST", "/views")
34 def post(self, project_name):
35 """Create a new view"""
36 if "view" not in request.json:
37 return http_error(HTTPStatus.BAD_REQUEST, "Wrong argument", 'Must provide "view" parameter in POST body')
38 session = SessionController()
39 view_obj = request.json["view"]
40 if "name" not in view_obj:
41 return http_error(HTTPStatus.BAD_REQUEST, "Wrong argument", 'Missing "name" field for view')
42 if "query" not in view_obj:
43 return http_error(HTTPStatus.BAD_REQUEST, "Wrong argument", 'Missing "query" field for view')
44 name = view_obj["name"]
45 query = view_obj["query"]
47 try:
48 project = session.database_controller.get_project(project_name)
49 except EntityNotExistsError:
50 return http_error(HTTPStatus.NOT_FOUND, "Project not found", f"Project name {project_name} does not exist")
52 if project.get_view(name) is not None:
53 return http_error(HTTPStatus.CONFLICT, "Name conflict", f"View with name {name} already exists.")
55 project.create_view(name, query, session)
56 created_view = project.get_view(name)
57 # Only want to return relevant fields to the user.
58 return {
59 "id": created_view["metadata"]["id"],
60 "name": created_view["name"],
61 "query": created_view["query"],
62 }, HTTPStatus.CREATED
65@ns_conf.route("/<project_name>/views/<view_name>")
66@ns_conf.param("project_name", "Name of the project")
67@ns_conf.param("view_name", "Name of the view")
68class ViewResource(Resource):
69 @ns_conf.doc("get_view")
70 @api_endpoint_metrics("GET", "/views/view")
71 def get(self, project_name, view_name):
72 """Get a view by name"""
73 session = SessionController()
74 try:
75 project = session.database_controller.get_project(project_name)
76 except EntityNotExistsError:
77 return http_error(HTTPStatus.NOT_FOUND, "Project not found", f"Project name {project_name} does not exist")
79 view = project.get_view(view_name)
80 if view is None:
81 return http_error(HTTPStatus.NOT_FOUND, "View not found", f"View with name {view_name} does not exist")
83 # Only want to return relevant fields to the user.
84 return {"id": view["metadata"]["id"], "name": view["name"], "query": view["query"]}
86 @ns_conf.doc("update_view")
87 @api_endpoint_metrics("PUT", "/views/view")
88 def put(self, project_name, view_name):
89 """Updates or creates a view"""
90 if "view" not in request.json:
91 return http_error(HTTPStatus.BAD_REQUEST, "Wrong argument", 'Must provide "view" parameter in PUT body')
92 request_view = request.json["view"]
93 session = SessionController()
94 try:
95 project = session.database_controller.get_project(project_name)
96 except EntityNotExistsError:
97 return http_error(HTTPStatus.NOT_FOUND, "Project not found", f"Project name {project_name} does not exist")
99 existing_view = project.get_view(view_name)
100 if existing_view is None:
101 # Create
102 if "query" not in request_view: 102 ↛ 103line 102 didn't jump to line 103 because the condition on line 102 was never true
103 return http_error(HTTPStatus.BAD_REQUEST, "Wrong argument", 'Missing "query" field for new view')
104 project.create_view(view_name, request_view["query"], session)
105 created_view = project.get_view(view_name)
106 # Only want to return relevant fields to the user.
107 return {
108 "id": created_view["metadata"]["id"],
109 "name": created_view["name"],
110 "query": created_view["query"],
111 }, HTTPStatus.CREATED
113 new_query = existing_view["query"]
114 if "query" in request_view: 114 ↛ 118line 114 didn't jump to line 118 because the condition on line 114 was always true
115 new_query = request_view["query"]
116 project.update_view(view_name, new_query)
118 existing_view = project.get_view(view_name)
119 # Only want to return relevant fields to the user.
120 return {"id": existing_view["metadata"]["id"], "name": existing_view["name"], "query": existing_view["query"]}
122 @ns_conf.doc("delete_view")
123 @api_endpoint_metrics("DELETE", "/views/view")
124 def delete(self, project_name, view_name):
125 """Deletes a view by name"""
126 session = SessionController()
127 try:
128 project = session.database_controller.get_project(project_name)
129 except EntityNotExistsError:
130 return http_error(HTTPStatus.NOT_FOUND, "Project not found", f"Project name {project_name} does not exist")
132 if project.get_view(view_name) is None:
133 return http_error(HTTPStatus.NOT_FOUND, "View not found", f"View with name {view_name} does not exist")
135 project.delete_view(view_name)
136 return "", HTTPStatus.NO_CONTENT