From 03634d57fa53180930c9315129772489e59e1243 Mon Sep 17 00:00:00 2001 From: Morten Rand-Hendriksen Date: Sat, 11 Nov 2023 05:53:47 +0000 Subject: [PATCH 1/5] add devcontainer --- .devcontainer/Dockerfile | 11 +++++++++++ .devcontainer/devcontainer.json | 33 +++++++++++++++++++++++++++++++++ .devcontainer/noop.txt | 3 +++ 3 files changed, 47 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/noop.txt diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..351a829d --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,11 @@ +FROM mcr.microsoft.com/devcontainers/anaconda:0-3 + +# Copy environment.yml (if found) to a temp location so we update the environment. Also +# copy "noop.txt" so the COPY instruction does not fail if no environment.yml exists. +COPY environment.yml* .devcontainer/noop.txt /tmp/conda-tmp/ +RUN if [ -f "/tmp/conda-tmp/environment.yml" ]; then umask 0002 && /opt/conda/bin/conda env update -n base -f /tmp/conda-tmp/environment.yml; fi \ + && rm -rf /tmp/conda-tmp + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..106472dd --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,33 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/anaconda +{ + "name": "Anaconda (Python 3)", + "build": { + "context": "..", + "dockerfile": "Dockerfile" + }, + "customizations": { + "vscode": { + "extensions": [ + "ms-azuretools.vscode-docker", + "ms-python.vscode-pylance", + "ms-python.python" + ] + } + }, + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [5003], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "pip install -r requirements.txt, python main.py" + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/.devcontainer/noop.txt b/.devcontainer/noop.txt new file mode 100644 index 00000000..dde8dc3c --- /dev/null +++ b/.devcontainer/noop.txt @@ -0,0 +1,3 @@ +This file copied into the container along with environment.yml* from the parent +folder. This file is included to prevents the Dockerfile COPY instruction from +failing if no environment.yml is found. \ No newline at end of file From 29a613ee6142676c87a4f56bea2b70f7749187c0 Mon Sep 17 00:00:00 2001 From: Morten Rand-Hendriksen Date: Sat, 11 Nov 2023 06:08:47 +0000 Subject: [PATCH 2/5] change container --- .devcontainer/Dockerfile | 11 ---------- .devcontainer/devcontainer.json | 37 ++++++++++++++++++--------------- .devcontainer/noop.txt | 3 --- 3 files changed, 20 insertions(+), 31 deletions(-) delete mode 100644 .devcontainer/Dockerfile delete mode 100644 .devcontainer/noop.txt diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 351a829d..00000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM mcr.microsoft.com/devcontainers/anaconda:0-3 - -# Copy environment.yml (if found) to a temp location so we update the environment. Also -# copy "noop.txt" so the COPY instruction does not fail if no environment.yml exists. -COPY environment.yml* .devcontainer/noop.txt /tmp/conda-tmp/ -RUN if [ -f "/tmp/conda-tmp/environment.yml" ]; then umask 0002 && /opt/conda/bin/conda env update -n base -f /tmp/conda-tmp/environment.yml; fi \ - && rm -rf /tmp/conda-tmp - -# [Optional] Uncomment this section to install additional OS packages. -# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ -# && apt-get -y install --no-install-recommends diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 106472dd..f12b85c0 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,20 +1,9 @@ // For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/anaconda +// README at: https://github.com/devcontainers/templates/tree/main/src/python { - "name": "Anaconda (Python 3)", - "build": { - "context": "..", - "dockerfile": "Dockerfile" - }, - "customizations": { - "vscode": { - "extensions": [ - "ms-azuretools.vscode-docker", - "ms-python.vscode-pylance", - "ms-python.python" - ] - } - }, + "name": "Python 3", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye", // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, @@ -22,11 +11,25 @@ // Use 'forwardPorts' to make a list of ports inside the container available locally. "forwardPorts": [5003], + "portsAttributes": { + "5003": { + "label": "GPT-plugin" + } + }, + // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "pip install -r requirements.txt, python main.py" + "postCreateCommand": "pip3 install --user -r requirements.txt && python main.py", // Configure tool-specific properties. - // "customizations": {}, + "customizations": { + "vscode": { + "extensions": [ + "ms-azuretools.vscode-docker", + "ms-python.vscode-pylance", + "ms-python.python" + ] + } + } // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. // "remoteUser": "root" diff --git a/.devcontainer/noop.txt b/.devcontainer/noop.txt deleted file mode 100644 index dde8dc3c..00000000 --- a/.devcontainer/noop.txt +++ /dev/null @@ -1,3 +0,0 @@ -This file copied into the container along with environment.yml* from the parent -folder. This file is included to prevents the Dockerfile COPY instruction from -failing if no environment.yml is found. \ No newline at end of file From 0bac20eb17a9ebd18ba51988ddd0fabf9131401a Mon Sep 17 00:00:00 2001 From: Morten Rand-Hendriksen Date: Sat, 11 Nov 2023 06:27:58 +0000 Subject: [PATCH 3/5] remove start --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f12b85c0..1a6fd809 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,7 @@ }, // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "pip3 install --user -r requirements.txt && python main.py", + "postCreateCommand": "pip3 install --user -r requirements.txt", // Configure tool-specific properties. "customizations": { From 907470b39fdc84a42ee6440310b23a5e46025092 Mon Sep 17 00:00:00 2001 From: Morten Rand-Hendriksen Date: Fri, 1 Dec 2023 23:02:04 +0000 Subject: [PATCH 4/5] temp URLs --- .well-known/ai-plugin.json | 4 ++-- main.py | 2 +- openapi.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.well-known/ai-plugin.json b/.well-known/ai-plugin.json index 04e8d871..6f96249b 100644 --- a/.well-known/ai-plugin.json +++ b/.well-known/ai-plugin.json @@ -9,9 +9,9 @@ }, "api": { "type": "openapi", - "url": "http://localhost:5003/openapi.yaml" + "url": "https://psychic-system-q74qxp6vgjf96qv-5003.app.github.dev/openapi.yaml" }, - "logo_url": "http://localhost:5003/logo.png", + "logo_url": "https://psychic-system-q74qxp6vgjf96qv-5003.app.github.dev/logo.png", "contact_email": "legal@example.com", "legal_info_url": "http://example.com/legal" } diff --git a/main.py b/main.py index a408731a..c78452a0 100644 --- a/main.py +++ b/main.py @@ -50,7 +50,7 @@ async def openapi_spec(): return quart.Response(text, mimetype="text/yaml") def main(): - app.run(debug=True, host="0.0.0.0", port=5003) + app.run(debug=True, host="localhost", port=5003) if __name__ == "__main__": main() diff --git a/openapi.yaml b/openapi.yaml index 3332d960..c09b9488 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -4,7 +4,7 @@ info: description: A plugin that allows the user to create and manage a TODO list using ChatGPT. If you do not know the user's username, ask them first before making queries to the plugin. Otherwise, use the username "global". version: 'v1' servers: - - url: http://localhost:5003 + - url: https://psychic-system-q74qxp6vgjf96qv-5003.app.github.dev/ paths: /todos/{username}: get: From a87a09af12b16ce0fc2ff640af9531980e9f3b98 Mon Sep 17 00:00:00 2001 From: Morten Rand-Hendriksen Date: Fri, 1 Dec 2023 23:59:57 +0000 Subject: [PATCH 5/5] Fully functional --- .well-known/ai-plugin.json | 4 ++-- README.md | 19 +++++++++++++++++++ main.py | 39 ++++++++++++++++++++++++++++++-------- openapi.yaml | 2 +- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/.well-known/ai-plugin.json b/.well-known/ai-plugin.json index 6f96249b..6006299b 100644 --- a/.well-known/ai-plugin.json +++ b/.well-known/ai-plugin.json @@ -9,9 +9,9 @@ }, "api": { "type": "openapi", - "url": "https://psychic-system-q74qxp6vgjf96qv-5003.app.github.dev/openapi.yaml" + "url": "localhost:5003/openapi.yaml" }, - "logo_url": "https://psychic-system-q74qxp6vgjf96qv-5003.app.github.dev/logo.png", + "logo_url": "localhost:5003/logo.png", "contact_email": "legal@example.com", "legal_info_url": "http://example.com/legal" } diff --git a/README.md b/README.md index 4ab0c1b0..1efd626b 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,25 @@ The plugin should now be installed and enabled! You can start with a question li ## Setup remotely +### GitHub Codespaces +1. Create a new Codespace from this repo by clicking Code -> Codespaces and the + button. +2. All required packages are automatically installed. +3. To run the plugin, enter the following command: + +```bash +python main.py +``` +Once the Codespaces server is running: + +1. Copy the URI to the local server (found under Ports) +2. Navigate to https://chat.openai.com. +3. In the Model drop down, select "Plugins" (note, if you don't see it there, you don't have access yet). +4. Select "Plugin store" +5. Select "Develop your own plugin" +6. Paste in the local server Codespaces url, then select "Find manifest file". + +The plugin should now be installed and enabled! You can start with a question like "What is on my todo list" and then try adding something to it as well! + ### Cloudflare workers ### Code Sandbox diff --git a/main.py b/main.py index c78452a0..c25512e9 100644 --- a/main.py +++ b/main.py @@ -1,11 +1,19 @@ import json - +import os import quart import quart_cors from quart import request app = quart_cors.cors(quart.Quart(__name__), allow_origin="https://chat.openai.com") +# Get GitHub Codespaces domain if any +def construct_codespaces_url(): + codespace_name = os.environ.get('CODESPACE_NAME') + if not codespace_name: + return None # Return None if there's no codespace name + port = 5003 # Example port number + return f"https://{codespace_name}-{port}.app.github.dev" + # Keep track of todo's. Does not persist if Python session is restarted. _TODOS = {} @@ -37,17 +45,32 @@ async def plugin_logo(): @app.get("/.well-known/ai-plugin.json") async def plugin_manifest(): - host = request.headers['Host'] - with open("./.well-known/ai-plugin.json") as f: - text = f.read() - return quart.Response(text, mimetype="text/json") + codespaces_url = construct_codespaces_url() + with open("./.well-known/ai-plugin.json", "r") as f: + data = json.load(f) + + # Update URL properties only if codespaces_url is not None + if codespaces_url: + data["api"]["url"] = data["api"]["url"].replace("localhost:5003", codespaces_url) + data["logo_url"] = data["logo_url"].replace("localhost:5003", codespaces_url) + + return quart.Response(json.dumps(data), mimetype="application/json") @app.get("/openapi.yaml") async def openapi_spec(): - host = request.headers['Host'] - with open("openapi.yaml") as f: + codespaces_url = construct_codespaces_url() + with open("openapi.yaml", "r") as f: text = f.read() - return quart.Response(text, mimetype="text/yaml") + + # Replace the URL only if codespaces_url is not None + if codespaces_url: + updated_text = text.replace("localhost:5003", codespaces_url) + else: + updated_text = text + + return quart.Response(updated_text, mimetype="text/yaml") + + def main(): app.run(debug=True, host="localhost", port=5003) diff --git a/openapi.yaml b/openapi.yaml index c09b9488..1347b41e 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -4,7 +4,7 @@ info: description: A plugin that allows the user to create and manage a TODO list using ChatGPT. If you do not know the user's username, ask them first before making queries to the plugin. Otherwise, use the username "global". version: 'v1' servers: - - url: https://psychic-system-q74qxp6vgjf96qv-5003.app.github.dev/ + - url: localhost:5003/ paths: /todos/{username}: get: