|
4 | 4 | import logging |
5 | 5 | import typing as t |
6 | 6 | from pathlib import Path |
| 7 | +import urllib.parse |
7 | 8 |
|
8 | 9 | from lsprotocol import types |
9 | 10 | from pygls.server import LanguageServer |
|
14 | 15 | from sqlmesh.lsp.api import ( |
15 | 16 | API_FEATURE, |
16 | 17 | ApiRequest, |
| 18 | + ApiResponseGetColumnLineage, |
17 | 19 | ApiResponseGetLineage, |
18 | 20 | ApiResponseGetModels, |
19 | 21 | ) |
|
24 | 26 | get_references, |
25 | 27 | ) |
26 | 28 | from sqlmesh.lsp.uri import URI |
27 | | -from web.server.api.endpoints.lineage import model_lineage |
| 29 | +from web.server.api.endpoints.lineage import column_lineage, model_lineage |
28 | 30 | from web.server.api.endpoints.models import get_models |
29 | 31 |
|
30 | 32 |
|
@@ -92,18 +94,37 @@ def all_models(ls: LanguageServer, params: AllModelsRequest) -> AllModelsRespons |
92 | 94 | @self.server.feature(API_FEATURE) |
93 | 95 | def api( |
94 | 96 | ls: LanguageServer, request: ApiRequest |
95 | | - ) -> t.Union[ApiResponseGetModels, ApiResponseGetLineage]: |
| 97 | + ) -> t.Union[ApiResponseGetModels, ApiResponseGetLineage, ApiResponseGetColumnLineage]: |
96 | 98 | ls.log_trace(f"API request: {request}") |
97 | 99 | if self.lsp_context is None: |
98 | 100 | raise RuntimeError("No context found") |
99 | | - if request.url == "/api/models": |
100 | | - response = ApiResponseGetModels(data=get_models(self.lsp_context.context)) |
101 | | - return response |
102 | | - if request.url.startswith("/api/lineage"): |
103 | | - name = request.url.split("/")[-1] |
104 | | - lineage = model_lineage(name, self.lsp_context.context) |
105 | | - non_set_lineage = {k: v for k, v in lineage.items() if v is not None} |
106 | | - return ApiResponseGetLineage(data=non_set_lineage) |
| 101 | + |
| 102 | + parsed_url = urllib.parse.urlparse(request.url) |
| 103 | + path_parts = parsed_url.path.strip("/").split("/") |
| 104 | + |
| 105 | + if request.method == "GET": |
| 106 | + if path_parts == ["api", "models"]: |
| 107 | + # /api/models |
| 108 | + return ApiResponseGetModels(data=get_models(self.lsp_context.context)) |
| 109 | + |
| 110 | + if path_parts[:2] == ["api", "lineage"]: |
| 111 | + if len(path_parts) == 3: |
| 112 | + # /api/lineage/{model} |
| 113 | + model_name = urllib.parse.unquote(path_parts[2]) |
| 114 | + lineage = model_lineage(model_name, self.lsp_context.context) |
| 115 | + non_set_lineage = {k: v for k, v in lineage.items() if v is not None} |
| 116 | + return ApiResponseGetLineage(data=non_set_lineage) |
| 117 | + |
| 118 | + if len(path_parts) == 4: |
| 119 | + # /api/lineage/{model}/{column} |
| 120 | + model_name = urllib.parse.unquote(path_parts[2]) |
| 121 | + column = urllib.parse.unquote(path_parts[3]) |
| 122 | + logging.info(f"Column lineage request: {model_name} {column}") |
| 123 | + column_lineage_response = column_lineage( |
| 124 | + model_name, column, False, self.lsp_context.context |
| 125 | + ) |
| 126 | + return ApiResponseGetColumnLineage(data=column_lineage_response) |
| 127 | + |
107 | 128 | raise NotImplementedError(f"API request not implemented: {request.url}") |
108 | 129 |
|
109 | 130 | @self.server.feature(types.TEXT_DOCUMENT_DID_OPEN) |
|
0 commit comments