# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_oai.ipynb.

# %% auto 0
__all__ = ['list_models', 'create_openai_plugin_scaffolding']

# %% ../nbs/00_oai.ipynb 3
from datetime import datetime
import inspect, os, json, subprocess
import pandas as pd
from fastcore.script import call_parse
from fastcore.meta import delegates
from urllib.parse import urljoin

# %% ../nbs/00_oai.ipynb 4
def _to_dt(dt:int):
    return datetime.fromtimestamp(dt).strftime('%Y-%m-%d')

@call_parse
def list_models(owned:str=None, # Filter by who models are owned by
                limit:int=None # Limit results to the most n created models.
               ):
    "List OpenAI models you have access to."
    from openai import OpenAI
    client = OpenAI()
    models = list(client.models.list())
    models.sort(key=lambda m: -m.created)
    models = [{'Name': m.id, 'Created Dt': _to_dt(m.created)} for m in models if not owned or owned in m.owned_by]
    if limit: models = models[:limit]
    df = pd.DataFrame(models)
    return df.to_markdown(index=False)

# %% ../nbs/00_oai.ipynb 6
def _query_git_config(key: str):
    try:
        result = subprocess.check_output(['git', 'config', '--get', key])
        str_res = result.decode().strip()
        if key == 'remote.origin.url': return str_res.split('/')[-1][:-4]
        return str_res
    except subprocess.CalledProcessError:
        return None

# %% ../nbs/00_oai.ipynb 8
def _join_url(base, path):
    if not base.endswith('/'):
        base += '/'
    return urljoin(base, path)

# %% ../nbs/00_oai.ipynb 9
@call_parse
def create_openai_plugin_scaffolding(name:str=None, # the name of your app for the LLM, ex: `todo`.  By default, this is inferred from the name of your git repo.
                                     description:str=None, # the description of your application that will be read by the LLM.
                                     url='http://localhost:8000', # The url of your function endpoint. 
                                     email=None, # The email associated with your app.  By default this is inferred by git.
                                    ):
    "Generate minimal scaffolding for an OpenAI Plugin."
    # Prompt for the application description
    if not description: description = input("Enter the application description: ")
    if not url: 
        _url = input("Change the url for the app (default: http://localhost:8000): ")
        if url: url=_url

    # Try to infer name_for_model and contact_email from Git config
    if name: 
        name_for_model=name
    else:
        name_for_model = _query_git_config('remote.origin.url')
        if name_for_model: print(f"Inferred name of app for model and human as `{name_for_model.split('/')[-1]}`.  Modify .well-known/ai-plugin.json and main.py to change this.")
        else: name_for_model = input("Provide the name of your function for the model. (ex `todo`):")
        
    if not email:
        email = _query_git_config('user.email')
        if not email: email = input("Enter the contact email: ")
    
    # Write the ai-plugin.json file
    ai_plugin_info = {
        "schema_version": "v1",
        "name_for_human": name_for_model,  # Assuming the Git repo name is suitable for human-readable name
        "name_for_model": name_for_model,
        "description_for_human": description,
        "description_for_model": description,
        "auth": {
            "type": "none"
        },
        "api": {
            "type": "openapi",
            "url": f"{_join_url(url, 'openapi.yaml')}"
        },
        "logo_url": f"{_join_url(url, 'logo.png')}",
        "contact_email": email,
        "legal_info_url": "http://example.com/legal"
    }

    os.makedirs('.well-known', exist_ok=True)
    with open('.well-known/ai-plugin.json', 'w') as f:
        json.dump(ai_plugin_info, f, indent=4)

    # Write the main.py file
    with open('main.py', 'w') as f:
        f.write(
            'from fastapi import FastAPI, Response, Request\n'
            'from fastapi.responses import FileResponse\n'
            'import yaml\n\n'
            f'app = FastAPI(description="{description}", title="{name_for_model}")\n\n'  # Set description for FastAPI
            '@app.get("/some-route")\n'
            'async def example_route():\n'
            '    return {"message": "Hello World"}\n\n'
            '@app.get("/.well-known/ai-plugin.json", response_class=FileResponse)\n'
            'async def ai_plugin():\n'
            '    return FileResponse("my_plugin/.well-known/ai-plugin.json")\n\n'
            '@app.get("/logo.png", response_class=FileResponse)\n'
            'async def plugin_logo():\n'
            '    return FileResponse("my_plugin/static/logo.png")\n\n'
            '@app.get("/openapi.yaml")\n'
            'async def openapi(request: Request):\n'
            '    openapi_schema = app.openapi()\n'
            '    openapi_schema["servers"] = [{"url": f"https://{request.headers[\'Host\']}"}]\n'
            '    for p in ["/.well-known/ai-plugin.json", "/logo.png", "/openapi.yaml"]:\n'
            '        openapi_schema["paths"].pop(p)\n'
            '    return Response(content=yaml.dump(openapi_schema), media_type="text/yaml")\n\n'
        )

    print('Plugin scaffolding created in current directory.')
