Package: autoplugin
AutoPluginAutoPlugin is a Python package that makes it easy to convert Python functions intoChatGPT plugins. With just a couple lines of code, you can:Automatically create an OpenAPI spec with custom endpoints for your registered Python functions, telling ChatGPT how to use it. Pull endpoint descriptions from the function docstring or generate them automatically with the OpenAI API.Generate theai-plugin.jsonfile to register your plugin with ChatGPT.Launch a local server that can be used by ChatGPT for development.InstallationTo install AutoPlugin, simply run the following command:pipinstallautopluginTo install with the ability to generate endpoint descriptions for the OpenAPI specification automatically from source code, install withpipinstall'autoplugin[gen]'Basic UsageTo get started with AutoPlugin, follow these steps:Import the necessary functions from AutoPlugin:fromautopluginimportregister,generate,launch,get_appCreate an app instance, backed by FastAPI:app=get_app()Use the register decorator to register your functions as API endpoints.
AutoPlugin will automatically generate descriptions if needed.@register(app,methods=["GET"])asyncdefget_order(name:str)->str:order=awaitget_order_from_db(name)returnf"Order for{name}:{order}"# Generated description: "Retrieves an order from the database for a given name."Generate the necessary files (openapi.yamlandai-plugin.json) for your ChatGPT plugin.
Optionally, specifyout_dirto change where they're saved to,
or setoverwrite_openapi_spec=Falseoroverwrite_plugin_spec=Falseto avoid overwriting the respective files.# generated files saved to `.well-known/` directorygenerate(app,name="Example",description="Plugin to add numbers or greet users")Launch the server. Optionally, specifyhostandport:launch(app)# API hosted at localhost:8000Follow theinstructionsto run a custom plugin:On ChatGPT, make a new chat.Under "Models" select "Plugins"In the Plugins dropdown, select "Plugin store"Click "Develop your own plugin"Enter the URL you're running the server at ("localhost:8000" by default) and hit enter.Click "Install localhost plugin"ExampleHere's a complete example that demonstrates how to use AutoPlugin to create API endpoints for two functions,helloandadd.
It also generates theopenapi.yamlandai-plugin.jsonfiles, by default in the.well-knowndirectory. :fromautoplugin.autopluginimportregister,generate,launch,get_appapp=get_app()@register(app,methods=["GET","POST"])asyncdefhello(name:str,age:int=5)->str:returnf"Hello,{name}! Age{age}."@register(app,methods=["GET"])asyncdefadd(a:int,b:int)->int:""" Adds two numbers """returna+b# Generate the necessary filesgenerate(app,name="Example",description="Plugin to add numbers or greet users")# Launch the serverlaunch(app)This example creates a FastAPI server with two endpoints,/helloand/add, that can be accessed using GET or POST requests.
AutoPlugin will use the docstring for the OpenAPI description of/addand generate an automatic description for/helloby passing the source code of the function to OpenAI's API.DocsThe@registerDecoratorThe@registerdecorator is used as follows:@register(app:FastAPI,methods:List[str],# which HTTP methods to supportdescription:Optional[str],# if provided, used as isgenerate_description:Optional[bool])# whether to autogenerate a descriptiondefmy_func(...):...AutoPlugin generates function descriptions in the OpenAPI spec so that ChatGPT knows how to use your endpoints. There are a few arguments to customize the behavior of this generation.app: Your FastAPI application. AutoPlugin provides aget_appfunction that includes CORSMiddleware for testing convenience (allows all origins by default).methods: A list of HTTP methods to be supported (e.g. ”GET”, POST”)description: If provided, overrides everything else and is used directly as the endpoint description for the OpenAPI specgenerate_description: If set toTrue, AutoPlugin will generate one automatically from OpenAI's API (requires the LangChain package and setting theOPENAI_API_KEYenvironment variable).By default (if neitherdescriptionnorgenerate_descriptionare provided), the description is fetched from the docstring. If there's no docstring, AutoPlugin falls back to generating one automatically.ThegenerateFunctionThegeneratefunction has the following signature:defgenerate(app:FastAPI,version="v1",out_dir=".well-known",overwrite_plugin_spec=True,overwrite_openapi_spec=True,name="",description="",**kwargs)app: Your FastAPI application again.version="v1": What version number to pass to both the plugin and OpenAPI specs.out_dir=".well-known": The directory to save both files to.overwrite_plugin_spec=True: If set to False, does not overwriteai-plugin.jsonif it already exists.overwrite_openapi_spec=True: If set to False, does not overwriteopenapi.yamlif it already exists.name="": If specified, used for bothname_for_humanandname_for_model.description="": If specified, used for bothdescription_for_humananddescription_for_model. Keep in mind thebest practicesfor descriptions.**kwargs: All other keyword arguments are passed on toai-plugin.jsondirectly. See the full list of possible optionshere.ThelaunchFunctionThelaunchfunction has the following signature:deflaunch(app:FastAPI,host="127.0.0.1",port=8000):app: Still your FastAPI application.host="127.0.0.1": the host to launch the server onport=8000: the port to launch the server onTestingAutoPlugin also provides atesting_serverutility (courtesy offlorimondmanca) for testing your endpoints. Here's an example of how you can use it to test the/helloand/addendpoints from the example above:fromautoplugin.testingimporttesting_serverfromos.pathimportjoinimportrequestsdeftest_api():host="127.0.0.1"port=8000server,base_url=testing_server(host=host,port=port,app_file="path/to/example.py",app_var="app")withserver.run_in_thread():# Server is started. Do your tests here.response=requests.post(join(base_url,"hello"),json={"name":"John Doe","age":31})assertresponse.json()=={"result":"Hello, John Doe! Age 31."}response=requests.get(join(base_url,"hello"),params={"name":"Jane Smith"})assertresponse.json()=={"result":"Hello, Jane Smith! Age 5."}response=requests.get(join(base_url,"add"),params={"a":6,"b":8})assertresponse.json()=={"result":14}# Server will be stopped.test_api()