diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..1a6fd809 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,36 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/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": {}, + + // 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": "pip3 install --user -r requirements.txt", + + // Configure tool-specific properties. + "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/.well-known/ai-plugin.json b/.well-known/ai-plugin.json index 04e8d871..6006299b 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": "localhost:5003/openapi.yaml" }, - "logo_url": "http://localhost:5003/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 a408731a..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,20 +45,35 @@ 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="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..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: http://localhost:5003 + - url: localhost:5003/ paths: /todos/{username}: get: