Skip to content

Commit

Permalink
🐛 fix things for Windows (#351)
Browse files Browse the repository at this point in the history
Signed-off-by: Pranav Gaikwad <pgaikwad@redhat.com>
  • Loading branch information
pranavgaikwad committed Sep 5, 2024
1 parent 8863dd9 commit 0006e28
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 11 deletions.
7 changes: 7 additions & 0 deletions playpen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The goals of this effort are:
As of writing this, here's the progress we made on the goals above:

- We have a JSON-RPC interface in front of the Client CLI. The JSON-RPC interface can be found in [./client/rpc.py](./client/rpc.py). It exposes `get_incident_solutions_for_file` function that generates a fix for one file. There are two example clients (Python and Javascript) we have written that talk with the interface over I/O streams.

- We have a `build.spec` file that builds the JSON-RPC client into a binary using PyInstaller.

### Building JSON-RPC interface into a binary
Expand All @@ -36,6 +37,12 @@ pyinstaller build.spec

Once successful, a binary will be generated at `./dist/cli`.

#### Building for different platforms

We are using PyInstaller to create binaries. To create a binary for a certain platform / arch, we are building on the same platform + arch. As per our understanding, it is possible to potentially cross-compile for different architectures but not the platform itself.

So far, we have successfully built and tested binaries for MacOS and Windows (built on respective machines).

### Testing JSON-RPC binary

Now that we have built our JSON-RPC interface into a binary, we will test it using a Python and a JS client that communicates. Both of these clients use a hardcoded path `./dist/cli` to run the JSON-RPC server. Make sure you have built the binary before moving forward.
Expand Down
2 changes: 1 addition & 1 deletion playpen/build.spec
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ script_path = 'client/rpc.py'

a = Analysis(
[script_path],
pathex=[os.path.dirname(script_path)],
pathex=[os.path.dirname(script_path), '../'],
binaries=[],
datas=data_dirs,
hiddenimports=["_ssl"],
Expand Down
25 changes: 15 additions & 10 deletions playpen/client/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

"""This module is intended to facilitate using Konveyor with LLMs."""


import json
import logging
import os
Expand Down Expand Up @@ -49,7 +50,6 @@ def run(self):

if method:
if rpc_id is not None:
# a call for method
if method not in self.method_callbacks:
raise ResponseError(
ErrorCodes.MethodNotFound,
Expand All @@ -70,6 +70,10 @@ def run(self):
self.handle_result(rpc_id, result, error)
except ResponseError as e:
self.send_response(rpc_id, None, e)
except Exception as e:
self.send_response(
rpc_id, None, ResponseError(ErrorCodes.InternalError, str(e))
)


class CustomRpcEndpoint(JsonRpcEndpoint):
Expand All @@ -81,16 +85,16 @@ def __add_header(self, json_string: str):
def send_request(self, message):
json_string = json.dumps(message, cls=MyEncoder)
jsonrpc_req = self.__add_header(json_string)
log.debug(f"Sending data over stdin {jsonrpc_req}")
log.debug(f"sending data over stdin {repr(jsonrpc_req)}")
with self.write_lock:
self.stdin.write(jsonrpc_req)
self.stdin.buffer.write(jsonrpc_req.encode())
self.stdin.flush()

def recv_response(self):
with self.read_lock:
message_size = None
while True:
line = self.stdout.readline()
line = self.stdout.buffer.readline().decode("utf-8")
if not line:
return None
if not line.endswith("\r\n") and not line.endswith("\n"):
Expand All @@ -116,8 +120,8 @@ def recv_response(self):
if not message_size:
raise ResponseError(ErrorCodes.ParseError, "Bad header: missing size")

jsonrpc_res = self.stdout.read(message_size)
log.debug(f"Read data from stdout {jsonrpc_res}")
jsonrpc_res = self.stdout.buffer.read(message_size).decode("utf-8")
log.debug(f"read data from stdout {repr(jsonrpc_res)}")
return json.loads(jsonrpc_res)


Expand Down Expand Up @@ -206,7 +210,7 @@ def _validate_path(self, path: str, dir: bool = False) -> bool:
class KaiClientRPCServer:
def get_incident_solutions_for_file(self, **kwargs) -> str:
rpc_params = RPCParams(**kwargs)
log.debug(f"got rpc params {rpc_params}")
log.debug(f"got rpc params {rpc_params._data}")
config = get_config(rpc_params.config_path)

setup_file_handler(
Expand Down Expand Up @@ -270,16 +274,17 @@ def get_incident_solutions_for_file(self, **kwargs) -> str:
return result.updated_file
except Exception as e:
trace.exception(-1, -1, e, traceback.format_exc())
log.debug(f"error processing file: {e}")
log.debug(f"failed to generate fix: {e}")
raise ResponseError(
ErrorCodes.InternalError, f"failed to generate fix - {str(e)}"
) from e
finally:
end = time.time()
trace.end(end)
log.info(
f"END - completed in '{end-start}s: - App: '{rpc_params.app_name}', File: '{rpc_params.input_file_path}' with {len(incidents)} incidents'"
)

raise ResponseError("failed to generate fix")


def run_rpc_server():
# filter warnings so stdout is not polluted
Expand Down
3 changes: 3 additions & 0 deletions playpen/rpc-client.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ def main():
)
print(response)
print("\nReceived response successfully!")
except Exception as e:
print(str(e))
print("\nFailed to generate fix")
finally:
rpc_server.stdin.close()
rpc_server.stdout.close()
Expand Down

0 comments on commit 0006e28

Please sign in to comment.