|
24 | 24 | logger = log.getLogger(__name__) |
25 | 25 |
|
26 | 26 |
|
| 27 | +def _resolve_handler_readme_path(handler_folder: str) -> Path: |
| 28 | + handler_folder_name = Path(handler_folder).name |
| 29 | + if handler_folder_name != handler_folder or ".." in handler_folder: |
| 30 | + raise ValueError(f"Handler folder '{handler_folder}' is invalid.") |
| 31 | + |
| 32 | + mindsdb_path = Path(importlib.util.find_spec("mindsdb").origin).parent |
| 33 | + base_handlers_path = mindsdb_path.joinpath("integrations/handlers").resolve() |
| 34 | + readme_path = base_handlers_path.joinpath(handler_folder_name).joinpath("README.md").resolve() |
| 35 | + |
| 36 | + if base_handlers_path not in readme_path.parents: |
| 37 | + raise ValueError(f"Handler folder '{handler_folder}' is invalid.") |
| 38 | + |
| 39 | + return readme_path |
| 40 | + |
| 41 | + |
27 | 42 | @ns_conf.route("/") |
28 | 43 | class HandlersList(Resource): |
29 | 44 | @ns_conf.doc("handlers_list") |
@@ -82,6 +97,52 @@ def get(self, handler_name): |
82 | 97 | return row |
83 | 98 |
|
84 | 99 |
|
| 100 | +@ns_conf.route("/<handler_name>/readme") |
| 101 | +class HandlerReadme(Resource): |
| 102 | + @ns_conf.param("handler_name", "Handler name") |
| 103 | + @api_endpoint_metrics("GET", "/handlers/handler/readme") |
| 104 | + def get(self, handler_name): |
| 105 | + try: |
| 106 | + handler_meta = ca.integration_controller.get_handler_meta(handler_name) |
| 107 | + except Exception: |
| 108 | + return http_error( |
| 109 | + HTTPStatus.NOT_FOUND, |
| 110 | + "Readme not found", |
| 111 | + f"Handler '{handler_name}' not found", |
| 112 | + ) |
| 113 | + |
| 114 | + def make_response(*, error_message=None, readme=None): |
| 115 | + return {"name": handler_name, "readme": readme, "error_message": error_message} |
| 116 | + |
| 117 | + if handler_meta is None: |
| 118 | + error_message = f"Handler '{handler_name}' not found" |
| 119 | + logger.warning(error_message) |
| 120 | + return make_response(error_message=error_message) |
| 121 | + |
| 122 | + handler_folder = handler_meta.get("import", {}).get("folder") |
| 123 | + if handler_folder is None: |
| 124 | + error_message = f"Handler '{handler_name}' does not define a folder" |
| 125 | + logger.warning(error_message) |
| 126 | + return make_response(error_message=error_message) |
| 127 | + |
| 128 | + try: |
| 129 | + readme_path = _resolve_handler_readme_path(handler_folder) |
| 130 | + except ValueError as exc: |
| 131 | + error_message = str(exc) |
| 132 | + logger.warning(error_message) |
| 133 | + return make_response(error_message=error_message) |
| 134 | + |
| 135 | + try: |
| 136 | + with open(readme_path, "r", encoding="utf-8") as readme_file: |
| 137 | + readme_content = readme_file.read() |
| 138 | + except FileNotFoundError: |
| 139 | + error_message = f"README.md for handler '{handler_name}' not found" |
| 140 | + logger.warning(error_message) |
| 141 | + return make_response(error_message=error_message) |
| 142 | + |
| 143 | + return make_response(readme=readme_content) |
| 144 | + |
| 145 | + |
85 | 146 | @ns_conf.route("/<handler_name>/install") |
86 | 147 | class InstallDependencies(Resource): |
87 | 148 | @ns_conf.param("handler_name", "Handler name") |
|
0 commit comments