|
| 1 | +import os |
| 2 | +from functools import wraps |
| 3 | +from typing import List |
| 4 | + |
| 5 | +import requests |
| 6 | + |
| 7 | +from .types import Location, SymbolNode |
| 8 | + |
| 9 | +BASE_SERVER_URL = os.environ.get("DEVCHAT_IDE_SERVICE_URL", "http://localhost:3000") |
| 10 | + |
| 11 | + |
| 12 | +def rpc_method(f): |
| 13 | + """ |
| 14 | + Decorator for Service methods |
| 15 | + """ |
| 16 | + |
| 17 | + @wraps(f) |
| 18 | + def wrapper(self, *args, **kwargs): |
| 19 | + if os.environ.get("DEVCHAT_IDE_SERVICE_URL", "") == "": |
| 20 | + # maybe in a test, user don't want to mock services functions |
| 21 | + return |
| 22 | + |
| 23 | + try: |
| 24 | + function_name = f.__name__ |
| 25 | + url = f"{BASE_SERVER_URL}/{function_name}" |
| 26 | + |
| 27 | + data = dict(zip(f.__code__.co_varnames[1:], args)) # Exclude "self" |
| 28 | + data.update(kwargs) |
| 29 | + headers = {"Content-Type": "application/json"} |
| 30 | + |
| 31 | + response = requests.post(url, json=data, headers=headers) |
| 32 | + |
| 33 | + if response.status_code != 200: |
| 34 | + raise Exception(f"Server error: {response.status_code}") |
| 35 | + |
| 36 | + response_data = response.json() |
| 37 | + if "error" in response_data: |
| 38 | + raise Exception(f"Server returned an error: {response_data['error']}") |
| 39 | + |
| 40 | + # Store the result in the _result attribute of the instance |
| 41 | + self._result = response_data.get("result", None) |
| 42 | + return f(self, *args, **kwargs) |
| 43 | + |
| 44 | + except ConnectionError as err: |
| 45 | + # TODO |
| 46 | + raise err |
| 47 | + |
| 48 | + return wrapper |
| 49 | + |
| 50 | + |
| 51 | +class IDEService: |
| 52 | + """ |
| 53 | + Client for IDE service |
| 54 | +
|
| 55 | + Usage: |
| 56 | + client = IDEService() |
| 57 | + res = client.ide_language() |
| 58 | + res = client.ide_logging("info", "some message") |
| 59 | + """ |
| 60 | + |
| 61 | + def __init__(self): |
| 62 | + self._result = None |
| 63 | + |
| 64 | + @rpc_method |
| 65 | + def get_lsp_brige_port(self) -> str: |
| 66 | + return self._result |
| 67 | + |
| 68 | + @rpc_method |
| 69 | + def install_python_env(self, command_name: str, requirements_file: str) -> str: |
| 70 | + return self._result |
| 71 | + |
| 72 | + @rpc_method |
| 73 | + def update_slash_commands(self) -> bool: |
| 74 | + return self._result |
| 75 | + |
| 76 | + @rpc_method |
| 77 | + def ide_language(self) -> str: |
| 78 | + return self._result |
| 79 | + |
| 80 | + @rpc_method |
| 81 | + def ide_logging(self, level: str, message: str) -> bool: |
| 82 | + """ |
| 83 | + level: "info" | "warn" | "error" | "debug" |
| 84 | + """ |
| 85 | + return self._result |
| 86 | + |
| 87 | + @rpc_method |
| 88 | + def get_document_symbols(self, abspath: str) -> List[SymbolNode]: |
| 89 | + return [SymbolNode.parse_obj(node) for node in self._result] |
| 90 | + |
| 91 | + @rpc_method |
| 92 | + def find_type_def_locations(self, abspath: str, line: int, character: int) -> List[Location]: |
| 93 | + return [Location.parse_obj(loc) for loc in self._result] |
0 commit comments