Skip to content

Commit 38e4e02

Browse files
lsp: verify and provide api key
1 parent e17d0f7 commit 38e4e02

File tree

4 files changed

+55
-5
lines changed

4 files changed

+55
-5
lines changed

codeflash/api/cfapi.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ def get_user_id() -> Optional[str]:
9999
if min_version and version.parse(min_version) > version.parse(__version__):
100100
msg = "Your Codeflash CLI version is outdated. Please update to the latest version using `pip install --upgrade codeflash`."
101101
console.print(f"[bold red]{msg}[/bold red]")
102+
if console.quiet: # lsp
103+
logger.debug(msg)
104+
return None
102105
sys.exit(1)
103106
return userid
104107

codeflash/code_utils/env_utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ def check_formatter_installed(formatter_cmds: list[str], exit_on_failure: bool =
3434

3535
@lru_cache(maxsize=1)
3636
def get_codeflash_api_key() -> str:
37-
api_key = os.environ.get("CODEFLASH_API_KEY") or read_api_key_from_shell_config()
37+
if console.quiet: # lsp
38+
# prefer shell config over env var in lsp mode
39+
api_key = read_api_key_from_shell_config() or os.environ.get("CODEFLASH_API_KEY")
40+
else:
41+
api_key = os.environ.get("CODEFLASH_API_KEY") or read_api_key_from_shell_config()
42+
3843
api_secret_docs_message = "For more information, refer to the documentation at [https://docs.codeflash.ai/getting-started/codeflash-github-actions#add-your-api-key-to-your-repository-secrets]." # noqa
3944
if not api_key:
4045
msg = (

codeflash/lsp/beta.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
from pygls import uris
1010

11+
from codeflash.api.cfapi import get_user_id
12+
from codeflash.code_utils.shell_utils import save_api_key_to_rc
1113
from codeflash.either import is_successful
1214
from codeflash.lsp.server import CodeflashLanguageServer, CodeflashLanguageServerProtocol
1315

@@ -28,6 +30,11 @@ class FunctionOptimizationParams:
2830
functionName: str # noqa: N815
2931

3032

33+
@dataclass
34+
class ProvideApiKeyParams:
35+
api_key: str
36+
37+
3138
server = CodeflashLanguageServer("codeflash-language-server", "v1.0", protocol_cls=CodeflashLanguageServerProtocol)
3239

3340

@@ -118,6 +125,40 @@ def discover_function_tests(server: CodeflashLanguageServer, params: FunctionOpt
118125
return {"functionName": params.functionName, "status": "success", "discovered_tests": num_discovered_tests}
119126

120127

128+
@server.feature("apiKeyExistsAndValid")
129+
def check_api_key(_server: CodeflashLanguageServer, _params: any) -> dict[str, str]:
130+
try:
131+
user_id = get_user_id()
132+
if user_id is None:
133+
return {"status": "error", "message": "api key not found or invalid"}
134+
135+
from codeflash.optimization.optimizer import Optimizer
136+
137+
server.optimizer = Optimizer(server.args)
138+
return {"status": "success", "user_id": user_id} # noqa
139+
except Exception:
140+
return {"status": "error", "message": "something went wrong while validating the api key"}
141+
142+
143+
@server.feature("provideApiKey")
144+
def provide_api_key(server: CodeflashLanguageServer, params: ProvideApiKeyParams) -> dict[str, str]:
145+
try:
146+
api_key = params.api_key
147+
result = save_api_key_to_rc(api_key)
148+
if not is_successful(result):
149+
return {"status": "error", "message": result.failure()}
150+
user_id = get_user_id()
151+
if user_id is None:
152+
return {"status": "error", "message": "api key is not valid"}
153+
154+
from codeflash.optimization.optimizer import Optimizer
155+
156+
server.optimizer = Optimizer(server.args)
157+
return {"status": "success", "message": "Api key saved successfully", "user_id": user_id} # noqa: TRY300
158+
except Exception:
159+
return {"status": "error", "message": "something went wrong while saving the api key"}
160+
161+
121162
@server.feature("prepareOptimization")
122163
def prepare_optimization(server: CodeflashLanguageServer, params: FunctionOptimizationParams) -> dict[str, str]:
123164
current_function = server.optimizer.current_function_being_optimized

codeflash/lsp/server.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def lsp_initialize(self, params: InitializeParams) -> InitializeResult:
2525
workspace_path = uris.to_fs_path(workspace_uri)
2626
pyproject_toml_path = self._find_pyproject_toml(workspace_path)
2727
if pyproject_toml_path:
28-
server.initialize_optimizer(pyproject_toml_path)
28+
server.prepare_optimizer_arguments(pyproject_toml_path)
2929
server.show_message(f"Found pyproject.toml at: {pyproject_toml_path}")
3030
else:
3131
server.show_message("No pyproject.toml found in workspace.")
@@ -45,16 +45,17 @@ class CodeflashLanguageServer(LanguageServer):
4545
def __init__(self, *args: Any, **kwargs: Any) -> None: # noqa: ANN401
4646
super().__init__(*args, **kwargs)
4747
self.optimizer = None
48+
self.args = None
4849

49-
def initialize_optimizer(self, config_file: Path) -> None:
50+
def prepare_optimizer_arguments(self, config_file: Path) -> None:
5051
from codeflash.cli_cmds.cli import parse_args, process_pyproject_config
51-
from codeflash.optimization.optimizer import Optimizer
5252

5353
args = parse_args()
5454
args.config_file = config_file
5555
args.no_pr = True # LSP server should not create PRs
5656
args = process_pyproject_config(args)
57-
self.optimizer = Optimizer(args)
57+
self.args = args
58+
# self.optimizer = Optimizer(args) # avoid creating the optimizer during initialization, bacause it may cause and erro if the api key is invalid
5859

5960
def show_message_log(self, message: str, message_type: str) -> None:
6061
"""Send a log message to the client's output channel.

0 commit comments

Comments
 (0)