From 541bcc99b674f14a9bf06c386297fefb98ee9d1f Mon Sep 17 00:00:00 2001 From: "Sheriff .n Ibrahim" Date: Mon, 9 Mar 2026 10:32:44 +0100 Subject: [PATCH 1/2] =?UTF-8?q?Week=204:=20Code=20gen=20and=20unit-test=20?= =?UTF-8?q?AI=20(Python=E2=86=94TS=20converter=20+=20LLM=20unit=20tests)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IbrahimSheriff/README.md | 40 ++ .../IbrahimSheriff/python_to_typescript.ipynb | 419 ++++++++++++++++++ 2 files changed, 459 insertions(+) create mode 100644 week4/community-contributions/IbrahimSheriff/README.md create mode 100644 week4/community-contributions/IbrahimSheriff/python_to_typescript.ipynb diff --git a/week4/community-contributions/IbrahimSheriff/README.md b/week4/community-contributions/IbrahimSheriff/README.md new file mode 100644 index 0000000000..2577583cb5 --- /dev/null +++ b/week4/community-contributions/IbrahimSheriff/README.md @@ -0,0 +1,40 @@ +# Python to TypeScript Code Generator + +## What it is + +A Python-to-TypeScript code generator that uses a frontier LLM via **OpenRouter** to produce idiomatic, typed TypeScript from Python with equivalent behavior. The interface is a **Gradio app** launched from the notebook. + +## Setup + +1. **API key:** Put your OpenRouter API key in a `.env` file in the repo root: + + ``` + OPENROUTER_API_KEY=sk-or-v1-... + ``` + + Get a key at [openrouter.ai](https://openrouter.ai). + +2. **Dependencies:** From the repo root run: + ```bash + uv sync + ``` + Or install: `python-dotenv`, `openai`, `gradio`. + +## How to run + +1. Open and run **`week4/IbrahimSheriff/python_to_typescript.ipynb`**. +2. Run all cells to load the client and start the Gradio app. +3. The notebook will print a local URL (e.g. `http://127.0.0.1:7860`). Open it in your browser. +4. Paste or edit Python code, choose a model, click **Convert** to get TypeScript. Use **Run Python** and **Run TypeScript** to compare outputs. + +## Optional: Run TypeScript in the app + +The **Run TypeScript** button runs the generated code with `npx ts-node`. You need: + +- **Node.js** installed. +- **ts-node** available, e.g.: + - `npm i -g ts-node`, or + - `npx ts-node main.ts` (uses npx to run ts-node). + +If ts-node is not installed, the app will show a message such as: +`ts-node not found. Install with: npm i -g ts-node (or use npx ts-node)`. diff --git a/week4/community-contributions/IbrahimSheriff/python_to_typescript.ipynb b/week4/community-contributions/IbrahimSheriff/python_to_typescript.ipynb new file mode 100644 index 0000000000..58f3dffceb --- /dev/null +++ b/week4/community-contributions/IbrahimSheriff/python_to_typescript.ipynb @@ -0,0 +1,419 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "intro", + "metadata": {}, + "source": [ + "# Python to TypeScript Code Generator\n", + "\n", + "Use a frontier LLM via **OpenRouter only** to generate idiomatic, typed TypeScript code from Python that produces equivalent behavior.\n", + "\n", + "**Setup:** Set `OPENROUTER_API_KEY` in your `.env` file. Get a key at [openrouter.ai](https://openrouter.ai).\n", + "\n", + "**Run TypeScript:** The \"Run TypeScript\" button requires Node.js and `ts-node` (or `tsx`) installed, e.g. `npm i -g ts-node` or use `npx ts-node main.ts`." + ] + }, + { + "cell_type": "markdown", + "id": "cfb14d27", + "metadata": {}, + "source": [ + "## Imports\n", + "\n", + "Dependencies: `dotenv` for API key, `openai` for the OpenRouter client, `gradio` for the UI." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "imports", + "metadata": {}, + "outputs": [], + "source": [ + "# imports\n", + "import os\n", + "import io\n", + "import sys\n", + "import subprocess\n", + "from dotenv import load_dotenv\n", + "from openai import OpenAI\n", + "import gradio as gr\n", + "\n", + "OPENROUTER_BASE_URL = \"https://openrouter.ai/api/v1\"" + ] + }, + { + "cell_type": "markdown", + "id": "9d996b5e", + "metadata": {}, + "source": [ + "## API key\n", + "\n", + "Load `OPENROUTER_API_KEY` from `.env`. Get a key at [openrouter.ai](https://openrouter.ai)." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "load_env", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "OpenRouter API Key exists and begins sk-or-v1\n" + ] + } + ], + "source": [ + "load_dotenv(override=True)\n", + "openrouter_api_key = os.getenv('OPENROUTER_API_KEY')\n", + "\n", + "if openrouter_api_key:\n", + " print(f\"OpenRouter API Key exists and begins {openrouter_api_key[:8]}\")\n", + "else:\n", + " print(\"OpenRouter API Key not set - please add OPENROUTER_API_KEY to your .env file\")" + ] + }, + { + "cell_type": "markdown", + "id": "9c96290b", + "metadata": {}, + "source": [ + "## OpenRouter client and models\n", + "\n", + "Single client for OpenRouter; model dropdown uses OpenRouter model IDs (e.g. GPT-4o, Claude, Gemini)." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "client", + "metadata": {}, + "outputs": [], + "source": [ + "# Connect to OpenRouter - single client for all models\n", + "client = OpenAI(\n", + " api_key=openrouter_api_key,\n", + " base_url=OPENROUTER_BASE_URL,\n", + ")\n", + "\n", + "# Model dropdown: OpenRouter model IDs\n", + "MODELS = [\n", + " \"openai/gpt-4o\",\n", + " \"anthropic/claude-3-5-sonnet\",\n", + " \"google/gemini-2.0-flash-001\",\n", + " \"openai/gpt-4o-mini\",\n", + " \"anthropic/claude-3-haiku\",\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "50246369", + "metadata": {}, + "source": [ + "## Prompts for TypeScript\n", + "\n", + "System prompt asks for idiomatic TypeScript with types; user prompt wraps the Python code. `messages_for(python)` builds the chat message list." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "prompts", + "metadata": {}, + "outputs": [], + "source": [ + "system_prompt = \"\"\"\n", + "Your task is to convert Python code into idiomatic TypeScript.\n", + "Use proper types, interfaces, and type annotations. The TypeScript code must produce the same runtime behavior and output as the Python code.\n", + "Respond only with TypeScript code. Do not wrap the code in markdown code fences or provide explanations.\n", + "\"\"\"\n", + "\n", + "def user_prompt_for(python):\n", + " return f\"\"\"\n", + "Port this Python code to equivalent TypeScript. Use proper types and idiomatic TypeScript. The code will be run with ts-node.\n", + "Respond only with TypeScript code.\n", + "\n", + "Python code to port:\n", + "\n", + "```python\n", + "{python}\n", + "```\n", + "\"\"\"\n", + "\n", + "def messages_for(python):\n", + " return [\n", + " {\"role\": \"system\", \"content\": system_prompt},\n", + " {\"role\": \"user\", \"content\": user_prompt_for(python)}\n", + " ]" + ] + }, + { + "cell_type": "markdown", + "id": "4d701368", + "metadata": {}, + "source": [ + "## Write output\n", + "\n", + "Writes the generated TypeScript to a file (default `main.ts`, UTF-8)." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "write_output", + "metadata": {}, + "outputs": [], + "source": [ + "def write_output(ts_code, path=\"main.ts\"):\n", + " with open(path, \"w\", encoding=\"utf-8\") as f:\n", + " f.write(ts_code)" + ] + }, + { + "cell_type": "markdown", + "id": "49911b40", + "metadata": {}, + "source": [ + "## Port (convert)\n", + "\n", + "Calls the LLM with `messages_for(python)`, strips markdown code fences from the reply, writes to file, and returns the TypeScript for display." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "port", + "metadata": {}, + "outputs": [], + "source": [ + "def port(model, python):\n", + " kwargs = {\"model\": model, \"messages\": messages_for(python)}\n", + " if 'gpt' in model:\n", + " kwargs[\"reasoning_effort\"] = \"high\"\n", + " response = client.chat.completions.create(**kwargs)\n", + " reply = response.choices[0].message.content or \"\"\n", + " # Strip markdown code fences\n", + " reply = reply.strip()\n", + " for prefix in ('```typescript', '```ts', '```'):\n", + " if reply.startswith(prefix):\n", + " reply = reply[len(prefix):].lstrip('\\n')\n", + " break\n", + " if reply.endswith('```'):\n", + " reply = reply[:-3].rstrip()\n", + " write_output(reply)\n", + " return reply" + ] + }, + { + "cell_type": "markdown", + "id": "380223e4", + "metadata": {}, + "source": [ + "## Run Python\n", + "\n", + "Executes the Python code in a sandbox, captures stdout, and returns it (or an error message)." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "run_python", + "metadata": {}, + "outputs": [], + "source": [ + "def run_python(code):\n", + " globals_dict = {\"__builtins__\": __builtins__}\n", + " buffer = io.StringIO()\n", + " old_stdout = sys.stdout\n", + " sys.stdout = buffer\n", + " try:\n", + " exec(code, globals_dict)\n", + " output = buffer.getvalue()\n", + " except Exception as e:\n", + " output = f\"Error: {e}\"\n", + " finally:\n", + " sys.stdout = old_stdout\n", + " return output" + ] + }, + { + "cell_type": "markdown", + "id": "3dffba39", + "metadata": {}, + "source": [ + "## Run TypeScript\n", + "\n", + "Writes the TypeScript to a temp file, runs it with `npx tsx` (or `ts-node`), and returns stdout (or stderr on failure). Requires Node.js and tsx/ts-node." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "run_typescript", + "metadata": {}, + "outputs": [], + "source": [ + "def run_typescript(ts_code):\n", + " if not ts_code or not ts_code.strip():\n", + " return \"No TypeScript code to run. Convert Python first.\"\n", + " cwd = os.getcwd()\n", + " run_file = os.path.join(cwd, \"_gradio_ts_run.ts\")\n", + " try:\n", + " with open(run_file, \"w\", encoding=\"utf-8\") as f:\n", + " f.write(ts_code)\n", + " # Prefer tsx (captures stdout reliably); fall back to ts-node\n", + " for cmd in [[\"npx\", \"--yes\", \"tsx\", run_file], [\"npx\", \"--yes\", \"ts-node\", run_file]]:\n", + " try:\n", + " result = subprocess.run(\n", + " cmd,\n", + " cwd=cwd,\n", + " capture_output=True,\n", + " text=True,\n", + " encoding=\"utf-8\",\n", + " timeout=30,\n", + " env={**os.environ, \"FORCE_COLOR\": \"0\"},\n", + " )\n", + " break\n", + " except FileNotFoundError:\n", + " continue\n", + " else:\n", + " return \"Neither tsx nor ts-node found. Install with: npx tsx or npm i -g ts-node\"\n", + " if result.returncode != 0:\n", + " return result.stderr or result.stdout or \"Non-zero exit\"\n", + " out = (result.stdout or \"\").strip()\n", + " err = (result.stderr or \"\").strip()\n", + " if out:\n", + " return out\n", + " if err:\n", + " return err\n", + " return \"(Program ran successfully with no output.)\"\n", + " except subprocess.TimeoutExpired:\n", + " return \"Execution timed out.\"\n", + " except Exception as e:\n", + " return f\"Error: {e}\"\n", + " finally:\n", + " if os.path.exists(run_file):\n", + " try:\n", + " os.unlink(run_file)\n", + " except OSError:\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "id": "31f2008d", + "metadata": {}, + "source": [ + "## Default example\n", + "\n", + "Short Python snippet shown in the first code box so you can click Convert immediately." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "default_example", + "metadata": {}, + "outputs": [], + "source": [ + "DEFAULT_PYTHON = '''print(\"Hello from Python\")\n", + "x = [1, 2, 3]\n", + "print(sum(x))'''" + ] + }, + { + "cell_type": "markdown", + "id": "fe6b1375", + "metadata": {}, + "source": [ + "## Gradio UI\n", + "\n", + "Two code areas (Python input, TypeScript output), model dropdown, Convert button, and Run Python / Run TypeScript with result text areas. Launch in browser." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "gradio_ui", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* Running on local URL: http://127.0.0.1:7863\n", + "* To create a public link, set `share=True` in `launch()`.\n" + ] + }, + { + "data": { + "text/html": [ + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "with gr.Blocks() as ui:\n", + " gr.Markdown(\"## Python to TypeScript - By Sheriff Ibrahm\")\n", + " with gr.Row():\n", + " python = gr.Textbox(label=\"Python code:\", lines=16, value=DEFAULT_PYTHON)\n", + " ts = gr.Textbox(label=\"TypeScript code:\", lines=16)\n", + " with gr.Row():\n", + " model = gr.Dropdown(MODELS, label=\"Model\", value=MODELS[0])\n", + " convert_btn = gr.Button(\"Convert\")\n", + " convert_btn.click(port, inputs=[model, python], outputs=[ts])\n", + "\n", + " with gr.Row():\n", + " py_result = gr.Textbox(label=\"Python output\", lines=4)\n", + " ts_result = gr.Textbox(label=\"TypeScript output\", lines=4)\n", + " with gr.Row():\n", + " run_py_btn = gr.Button(\"Run Python\")\n", + " run_ts_btn = gr.Button(\"Run TypeScript\")\n", + " run_py_btn.click(run_python, inputs=[python], outputs=[py_result])\n", + " run_ts_btn.click(run_typescript, inputs=[ts], outputs=[ts_result])\n", + "\n", + "ui.launch(inbrowser=True)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 984c76df9c5dc4221a45dbf1a6717ee5c436e123 Mon Sep 17 00:00:00 2001 From: "Sheriff .n Ibrahim" Date: Mon, 9 Mar 2026 10:34:18 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Week=204:=20Code=20gen=20and=20unit-test=20?= =?UTF-8?q?AI=20(Python=E2=86=94TS=20converter=20+=20LLM=20unit=20tests)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IbrahimSheriff/README.md | 29 +++-- .../IbrahimSheriff/python_to_typescript.ipynb | 119 ++++++++++++++++-- 2 files changed, 124 insertions(+), 24 deletions(-) diff --git a/week4/community-contributions/IbrahimSheriff/README.md b/week4/community-contributions/IbrahimSheriff/README.md index 2577583cb5..9f5edcaad0 100644 --- a/week4/community-contributions/IbrahimSheriff/README.md +++ b/week4/community-contributions/IbrahimSheriff/README.md @@ -1,8 +1,14 @@ -# Python to TypeScript Code Generator +# Week 4: Code gen and unit-test AI ## What it is -A Python-to-TypeScript code generator that uses a frontier LLM via **OpenRouter** to produce idiomatic, typed TypeScript from Python with equivalent behavior. The interface is a **Gradio app** launched from the notebook. +A **Gradio app** (launched from the notebook) that uses a frontier LLM via **OpenRouter** to: + +- **Convert Python → TypeScript** — Generate idiomatic, typed TypeScript from Python with equivalent behavior. +- **Run code** — Run the Python or TypeScript in the app and compare outputs. +- **Generate unit tests** — Choose **Python** (pytest) or **TypeScript** (Jest) and generate tests for the code in the corresponding box. + +Notebook: **`week4/python_to_typescript.ipynb`**. ## Setup @@ -22,19 +28,20 @@ A Python-to-TypeScript code generator that uses a frontier LLM via **OpenRouter* ## How to run -1. Open and run **`week4/IbrahimSheriff/python_to_typescript.ipynb`**. +1. Open and run **`week4/python_to_typescript.ipynb`**. 2. Run all cells to load the client and start the Gradio app. -3. The notebook will print a local URL (e.g. `http://127.0.0.1:7860`). Open it in your browser. -4. Paste or edit Python code, choose a model, click **Convert** to get TypeScript. Use **Run Python** and **Run TypeScript** to compare outputs. +3. Use the local URL (e.g. `http://127.0.0.1:7860`) in your browser. +4. **Convert:** Paste Python, pick a model, click **Convert** to get TypeScript. +5. **Run:** Use **Run Python** and **Run TypeScript** to see outputs. +6. **Unit tests:** Choose **Python** or **TypeScript** in the dropdown and click **Generate unit tests** to get pytest or Jest tests. ## Optional: Run TypeScript in the app -The **Run TypeScript** button runs the generated code with `npx ts-node`. You need: +The **Run TypeScript** button uses `npx tsx` (or `npx ts-node`). You need: - **Node.js** installed. -- **ts-node** available, e.g.: - - `npm i -g ts-node`, or - - `npx ts-node main.ts` (uses npx to run ts-node). +- **tsx** or **ts-node**, e.g.: + - `npx tsx` (recommended, no global install), + - or `npm i -g ts-node`. -If ts-node is not installed, the app will show a message such as: -`ts-node not found. Install with: npm i -g ts-node (or use npx ts-node)`. +If neither is available, the app will show an install message. diff --git a/week4/community-contributions/IbrahimSheriff/python_to_typescript.ipynb b/week4/community-contributions/IbrahimSheriff/python_to_typescript.ipynb index 58f3dffceb..016b8e52fe 100644 --- a/week4/community-contributions/IbrahimSheriff/python_to_typescript.ipynb +++ b/week4/community-contributions/IbrahimSheriff/python_to_typescript.ipynb @@ -26,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 32, "id": "imports", "metadata": {}, "outputs": [], @@ -55,7 +55,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 33, "id": "load_env", "metadata": {}, "outputs": [ @@ -89,7 +89,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 34, "id": "client", "metadata": {}, "outputs": [], @@ -122,7 +122,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 35, "id": "prompts", "metadata": {}, "outputs": [], @@ -164,7 +164,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 36, "id": "write_output", "metadata": {}, "outputs": [], @@ -186,7 +186,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 37, "id": "port", "metadata": {}, "outputs": [], @@ -221,7 +221,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 38, "id": "run_python", "metadata": {}, "outputs": [], @@ -253,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 39, "id": "run_typescript", "metadata": {}, "outputs": [], @@ -304,6 +304,91 @@ " pass" ] }, + { + "cell_type": "markdown", + "id": "69cfa03e", + "metadata": {}, + "source": [ + "## Generate unit tests\n", + "\n", + "Uses the LLM to generate unit tests. Choose **Python** (pytest) to test the Python code, or **TypeScript** (Jest) to test the TypeScript code. Output is shown in a separate text area." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "f63db500", + "metadata": {}, + "outputs": [], + "source": [ + "UNIT_TEST_SYSTEM_PROMPT_PYTHON = \"\"\"\n", + "Your task is to write unit tests for the given Python code.\n", + "Use pytest style: test functions named test_*, assert statements, and pytest features (e.g. parametrize, fixtures) when helpful.\n", + "Cover the main behavior and edge cases. Respond only with Python test code. Do not wrap in markdown code fences or add explanations.\n", + "\"\"\"\n", + "\n", + "UNIT_TEST_SYSTEM_PROMPT_TS = \"\"\"\n", + "Your task is to write unit tests for the given TypeScript code.\n", + "Use Jest: describe/it, expect(), and Jest matchers. Use proper types. Cover the main behavior and edge cases.\n", + "Respond only with TypeScript test code. Do not wrap in markdown code fences or add explanations.\n", + "\"\"\"\n", + "\n", + "def user_prompt_for_tests_python(python_code):\n", + " return f\"\"\"Write unit tests for this Python code. Use pytest. Respond only with the test code.\n", + "\n", + "Python code to test:\n", + "\n", + "```python\n", + "{python_code}\n", + "```\n", + "\"\"\"\n", + "\n", + "def user_prompt_for_tests_ts(ts_code):\n", + " return f\"\"\"Write unit tests for this TypeScript code. Use Jest. Respond only with the test code.\n", + "\n", + "TypeScript code to test:\n", + "\n", + "```typescript\n", + "{ts_code}\n", + "```\n", + "\"\"\"\n", + "\n", + "def messages_for_tests_python(python_code):\n", + " return [\n", + " {\"role\": \"system\", \"content\": UNIT_TEST_SYSTEM_PROMPT_PYTHON},\n", + " {\"role\": \"user\", \"content\": user_prompt_for_tests_python(python_code)}\n", + " ]\n", + "\n", + "def messages_for_tests_ts(ts_code):\n", + " return [\n", + " {\"role\": \"system\", \"content\": UNIT_TEST_SYSTEM_PROMPT_TS},\n", + " {\"role\": \"user\", \"content\": user_prompt_for_tests_ts(ts_code)}\n", + " ]\n", + "\n", + "def generate_unit_tests(model, test_type, python_code, ts_code):\n", + " code = python_code if test_type == \"Python\" else ts_code\n", + " if not code or not code.strip():\n", + " msg = \"Paste Python code above\" if test_type == \"Python\" else \"Convert to TypeScript first or paste TypeScript code\"\n", + " return f\"{msg}, then click Generate unit tests.\"\n", + " messages = messages_for_tests_python(python_code) if test_type == \"Python\" else messages_for_tests_ts(ts_code)\n", + " kwargs = {\"model\": model, \"messages\": messages}\n", + " if \"gpt\" in model:\n", + " kwargs[\"reasoning_effort\"] = \"high\"\n", + " response = client.chat.completions.create(**kwargs)\n", + " reply = (response.choices[0].message.content or \"\").strip()\n", + " if test_type == \"Python\":\n", + " prefixes = (\"```python\", \"```py\", \"```\")\n", + " else:\n", + " prefixes = (\"```typescript\", \"```ts\", \"```\")\n", + " for prefix in prefixes:\n", + " if reply.startswith(prefix):\n", + " reply = reply[len(prefix):].lstrip(\"\\n\")\n", + " break\n", + " if reply.endswith(\"```\"):\n", + " reply = reply[:-3].rstrip()\n", + " return reply" + ] + }, { "cell_type": "markdown", "id": "31f2008d", @@ -316,7 +401,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 41, "id": "default_example", "metadata": {}, "outputs": [], @@ -338,7 +423,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 42, "id": "gradio_ui", "metadata": {}, "outputs": [ @@ -346,14 +431,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "* Running on local URL: http://127.0.0.1:7863\n", + "* Running on local URL: http://127.0.0.1:7864\n", "* To create a public link, set `share=True` in `launch()`.\n" ] }, { "data": { "text/html": [ - "
" + "
" ], "text/plain": [ "" @@ -366,7 +451,7 @@ "data": { "text/plain": [] }, - "execution_count": null, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -391,6 +476,14 @@ " run_py_btn.click(run_python, inputs=[python], outputs=[py_result])\n", " run_ts_btn.click(run_typescript, inputs=[ts], outputs=[ts_result])\n", "\n", + " gr.Markdown(\"### Generate unit tests\")\n", + " TEST_TYPES = [\"Python\", \"TypeScript\"]\n", + " with gr.Row():\n", + " test_type = gr.Dropdown(TEST_TYPES, label=\"Test language\", value=\"Python\")\n", + " unit_tests = gr.Textbox(label=\"Unit tests\", lines=16)\n", + " gen_tests_btn = gr.Button(\"Generate unit tests\")\n", + " gen_tests_btn.click(generate_unit_tests, inputs=[model, test_type, python, ts], outputs=[unit_tests])\n", + "\n", "ui.launch(inbrowser=True)" ] }