Skip to content

Commit

Permalink
feat: Add more openapi functions and refactor open_api_function (#578)
Browse files Browse the repository at this point in the history
  • Loading branch information
yiyiyi0817 committed Jun 10, 2024
1 parent 52938a7 commit 2f26b55
Show file tree
Hide file tree
Showing 20 changed files with 593 additions and 19 deletions.
7 changes: 7 additions & 0 deletions camel/functions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,17 @@
from .weather_functions import WEATHER_FUNCS
from .slack_functions import SLACK_FUNCS

from .open_api_function import (
apinames_filepaths_to_funs_schemas,
generate_apinames_filepaths,
)

__all__ = [
'OpenAIFunction',
'get_openai_function_schema',
'get_openai_tool_schema',
'apinames_filepaths_to_funs_schemas',
'generate_apinames_filepaths',
'MAP_FUNCS',
'MATH_FUNCS',
'OPENAPI_FUNCS',
Expand Down
68 changes: 51 additions & 17 deletions camel/functions/open_api_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,13 +332,22 @@ def openapi_function(**kwargs):
return functions


def combine_all_funcs_schemas() -> Tuple[List[Callable], List[Dict[str, Any]]]:
r"""Combines functions and schemas from multiple OpenAPI specifications.
def apinames_filepaths_to_funs_schemas(
apinames_filepaths: List[Tuple[str, str]],
) -> Tuple[List[Callable], List[Dict[str, Any]]]:
r"""Combines functions and schemas from multiple OpenAPI specifications,
using API names as keys.
Iterates over a list of OpenAPI specs, parses each, and generates functions
and schemas based on the defined operations and schemas respectively.
Assumes specification files are named 'openapi.yaml' located in
`open_api_specs/<api_name>/`.
This function iterates over tuples of API names and OpenAPI spec file
paths, parsing each spec to generate callable functions and schema
dictionaries, all organized by API name.
Args:
apinames_filepaths (List[Tuple[str, str]]): A list of tuples, where each
tuple consists of:
- The API name (str) as the first element.
- The file path (str) to the API's OpenAPI specification file as the
second element.
Returns:
Tuple[List[Callable], List[Dict[str, Any]]]:: one of callable
Expand All @@ -347,34 +356,59 @@ def combine_all_funcs_schemas() -> Tuple[List[Callable], List[Dict[str, Any]]]:
"""
combined_func_lst = []
combined_schemas_list = []

for api_name in OpenAPIName:
for api_name, file_path in apinames_filepaths:
# Parse the OpenAPI specification for each API
current_dir = os.path.dirname(__file__)
spec_file_path = os.path.join(
current_dir, 'open_api_specs', f'{api_name.value}', 'openapi.yaml'
file_path = os.path.join(
current_dir, 'open_api_specs', f'{api_name}', 'openapi.yaml'
)

openapi_spec = parse_openapi_file(spec_file_path)
openapi_spec = parse_openapi_file(file_path)

# Generate and merge function schemas
openapi_functions_schemas = openapi_spec_to_openai_schemas(
api_name.value, openapi_spec
api_name, openapi_spec
)
combined_schemas_list.extend(openapi_functions_schemas)

# Generate and merge function lists
openapi_functions_list = generate_openapi_funcs(
api_name.value, openapi_spec
)
openapi_functions_list = generate_openapi_funcs(api_name, openapi_spec)
combined_func_lst.extend(openapi_functions_list)

return combined_func_lst, combined_schemas_list


combined_funcs_lst, combined_schemas_list = combine_all_funcs_schemas()
def generate_apinames_filepaths() -> List[Tuple[str, str]]:
"""Generates a list of tuples containing API names and their corresponding
file paths.
This function iterates over the OpenAPIName enum, constructs the file path
for each API's OpenAPI specification file, and appends a tuple of the API
name and its file path to the list. The file paths are relative to the
'open_api_specs' directory located in the same directory as this script.
Returns:
List[Tuple[str, str]]: A list of tuples where each tuple contains two
elements. The first element of each tuple is a string representing
the name of an API, and the second element is a string that
specifies the file path to that API's OpenAPI specification file.
"""
apinames_filepaths = []
current_dir = os.path.dirname(__file__)
for api_name in OpenAPIName:
file_path = os.path.join(
current_dir, 'open_api_specs', f'{api_name.value}', 'openapi.yaml'
)
apinames_filepaths.append((api_name.value, file_path))
return apinames_filepaths


apinames_filepaths = generate_apinames_filepaths()
all_funcs_lst, all_schemas_lst = apinames_filepaths_to_funs_schemas(
apinames_filepaths
)

OPENAPI_FUNCS: List[OpenAIFunction] = [
OpenAIFunction(a_func, a_schema)
for a_func, a_schema in zip(combined_funcs_lst, combined_schemas_list)
for a_func, a_schema in zip(all_funcs_lst, all_schemas_lst)
]
13 changes: 13 additions & 0 deletions camel/functions/open_api_specs/biztoc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
# Licensed under the Apache License, Version 2.0 (the “License”);
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an “AS IS” BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
34 changes: 34 additions & 0 deletions camel/functions/open_api_specs/biztoc/ai-plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"id": "plugin-da9afb50-fc07-4d30-b606-51ed1b105bfc",
"domain": "biztoc.com",
"namespace": "biztoc",
"status": "approved",
"manifest": {
"schema_version": "v1",
"name_for_model": "biztoc",
"name_for_human": "BizToc",
"description_for_model": "Plugin for querying BizToc for business news.",
"description_for_human": "Search BizToc for business & finance news.",
"auth": {
"type": null
},
"api": {
"type": "openapi",
"url": "https://ai.biztoc.com/openapi.yaml"
},
"logo_url": "https://biztoc.com/favicon.png",
"contact_email": "mail@biztoc.com",
"legal_info_url": "https://biztoc.com/s/legal"
},
"oauth_client_id": null,
"user_settings": {
"is_installed": false,
"is_authenticated": true
},
"categories": [
{
"id": "newly_added",
"title": "New"
}
]
}
21 changes: 21 additions & 0 deletions camel/functions/open_api_specs/biztoc/openapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
openapi: 3.0.1
info:
title: BizToc
description: Search BizToc for business & finance news.
version: 'v1'
servers:
- url: https://ai.biztoc.com
paths:
/ai/news:
get:
operationId: getNews
summary: Retrieves the latest news whose content contains the query string.
parameters:
- in: query
name: query
schema:
type: string
description: Used to query news articles on their title and body. For example, ?query=apple will return news stories that have 'apple' in their title or body.
responses:
"200":
description: OK
13 changes: 13 additions & 0 deletions camel/functions/open_api_specs/create_qr_code/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
# Licensed under the Apache License, Version 2.0 (the “License”);
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an “AS IS” BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
44 changes: 44 additions & 0 deletions camel/functions/open_api_specs/create_qr_code/openapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
openapi: 3.0.1
info:
title: QR Code API
version: 1.0.0
description: Create a QR code for any text or url.
servers:
- url: https://create-qr-code.modelxy.com
paths:
/create-qr-code:
get:
operationId: getQRCode
summary: Create a QR code
parameters:
- in: query
name: data
schema:
type: string
description: The data to encode in the QR code.
- in: query
name: size
schema:
type: string
default: '100x100'
description: The size of the QR code.
- in: query
name: alt
schema:
type: string
description: The alt text for the QR code image.
- in: query
name: title
schema:
type: string
description: The title for the QR code image.
responses:
'200':
description: A JSON object containing the QR code image tag.
content:
application/json:
schema:
type: object
properties:
img_tag:
type: string
13 changes: 13 additions & 0 deletions camel/functions/open_api_specs/outschool/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
# Licensed under the Apache License, Version 2.0 (the “License”);
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an “AS IS” BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
34 changes: 34 additions & 0 deletions camel/functions/open_api_specs/outschool/ai-plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"id": "plugin-9335c256-4658-4376-bac8-a0baa5c1c889",
"domain": "chatgpt-plugin.outschool.com",
"namespace": "Outschool",
"status": "approved",
"manifest": {
"schema_version": "v1",
"name_for_model": "Outschool",
"name_for_human": "Outschool",
"description_for_model": "Search for top-quality online classes and teachers on Outschool.",
"description_for_human": "Search for top-quality online classes and teachers on Outschool.",
"auth": {
"type": "none"
},
"api": {
"type": "openapi",
"url": "https://chatgpt-plugin.outschool.com/openapi.json"
},
"logo_url": "https://chatgpt-plugin.outschool.com/logo.png",
"contact_email": "support@outschool.com",
"legal_info_url": "https://outschool.com/terms"
},
"oauth_client_id": null,
"user_settings": {
"is_installed": false,
"is_authenticated": true
},
"categories": [
{
"id": "newly_added",
"title": "New"
}
]
}
1 change: 1 addition & 0 deletions camel/functions/open_api_specs/outschool/openapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"openapi":"3.0.1","info":{"title":"Outschool Plugin","description":"Search for top-quality online classes and teachers on Outschool.","version":"v1"},"servers":[{"url":"https://chatgpt-plugin.outschool.com/api"}],"paths":{"/classes":{"get":{"operationId":"searchClasses","description":"Returns a list of online classes","parameters":[{"name":"timeZone","in":"query","required":true,"description":"IANA Time Zone identifier of the user. Either provided by user or derived from their location. Since Outschool parents and teachers can be from different time zones, this is required to search classes that are available in parent's timezone at reasonable hours. Only IANA format is accepted.","schema":{"type":"string"},"examples":{"losAngeles":{"value":"America/Los_Angeles"},"newYork":{"value":"America/New_York"},"london":{"value":"Europe/London"}}},{"name":"age","in":"query","required":true,"description":"Outschool has several classes serving different age groups. The age of the learner(s) helps to find classes that match the best. This is a comma separated list. If the age difference between the children is more than 5 years, it may be better to search for different ages separately to get better search results.","schema":{"type":"string","minimum":3,"maximum":18},"examples":{"12":{"value":"12"},"1213":{"value":"12,13"},"5617":{"value":"5,6,17"}}},{"name":"q","in":"query","required":false,"description":"Keywords to use to search in the class list. Classes matching the keyword closest will be returned.","schema":{"type":"string"}},{"name":"delivery","in":"query","required":false,"explode":true,"description":"Filters classes by delivery type. Description for different enum values:\n One-time: Classes that meets once\n Ongoing: Weekly classes that learners can enroll in any week\n Semester course: Multi-week/session classes, usually more than 4 weeks\n Short course: Multi-week/session classes, usually around 4 weeks\n Camp: Semester or short courses during summer and school breaks\n Group: Async chat groups on a specific topic where learners share ideas and experiences, like clubs","schema":{"type":"array","items":{"type":"string","enum":["One-time","Ongoing","Semester course","Short course","Camp","Group"]}}},{"name":"userUid","in":"query","required":false,"description":"Only search classes taught by a specific teacher. The userUid is the id of the teacher","schema":{"type":"string","format":"uuid"}},{"name":"order","in":"query","description":"Sort results by either upcoming, new, or relevance. Upcoming sorts by next section start date in ascending order, new sorts by class published date in descending order, and relevance sorts by the keyword relevance and popularity of the class.","schema":{"type":"string","enum":["upcoming","new","relevance"],"default":"relevance"}},{"name":"offset","in":"query","required":false,"description":"The offset for the results. Offset and limit used in combination to paginate in results. For instance, if limit is 10, to get next 10 results, the offset should be set to 10.","schema":{"type":"number","default":0}},{"name":"limit","in":"query","required":false,"description":"Number of results to return.","schema":{"type":"number","default":10}},{"name":"startAfter","in":"query","required":false,"description":"Search classes that have a section starting on or after a given date. Only today or future dates are allowed.","schema":{"type":"string","format":"date"},"examples":{"April152023":{"value":"2023-04-15"}}},{"name":"dow","in":"query","description":"The day of week to filter classes and only return classes that have a section on given days of the week.","schema":{"type":"array","items":{"type":"string","enum":["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]}},"style":"form","explode":true,"required":false,"examples":{"Mon":{"value":"Mon"},"Mon_Tue":{"value":"Mon,Tue"},"Mon_Thu":{"value":"Mon,Tue,Wed,Thu"},"Weekdays":{"value":"Mon,Tue,Wed,Thu,Fri"},"Weekend":{"value":"Sat, Sun"}}},{"name":"startAfterTime","in":"query","description":"The start time of the class in 24 hour format as hour of the day normalized by the user's timezone","schema":{"type":"number","minimum":6,"maximum":22}},{"name":"endByTime","in":"query","description":"The end time of the class in 24 hour format as hour of the day normalized by the user's timezone","schema":{"type":"number","minimum":6,"maximum":22}}],"responses":{"200":{"description":"A list of classes","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/class"}}}}}}}},"/teachers":{"get":{"operationId":"searchTeachers","description":"Returns a list of teachers","parameters":[{"name":"name","in":"query","required":true,"description":"Name of the teacher to search for","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Number of results to return.","schema":{"type":"number","default":10}}],"responses":{"200":{"description":"A list of teachers","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/teacher"}}}}}}}}},"components":{"schemas":{"class":{"type":"object","properties":{"uid":{"type":"string","format":"uuid","description":"Unique ID of the class in the system that can be used in other API end points"},"title":{"type":"string","description":"Title of the class"},"summary":{"type":"string","description":"Summary of the class"},"url":{"type":"string","format":"uri","description":"URL to the class detail page"},"photo":{"type":"string","format":"uri","description":"Photo of the class"},"is_ongoing_weekly":{"type":"boolean","description":"Whether this class is an ongoing class or not. When a class is an ongoing class, parents can enroll their children for any week of an ongoing class, because the sections of that class meet every week and the weeks don't depend on each other."},"age_min":{"type":"number","description":"The minimum age a learner should be to enroll in the class. Although Outschool has classes for different age groups, individual classes may only be appropriate for a certain age range."},"age_max":{"type":"number","description":"The maximum age a learner should be to enroll in the class. Although Outschool has classes for different age groups, individual classes may only be appropriate for a certain age range."},"teacher":{"$ref":"#/components/schemas/teacher"},"nextSection":{"$ref":"#/components/schemas/section","nullable":true,"description":"The next section of the class that the parent/caregiver can enroll their children in. This is usually what parents are looking for to enroll in a class."}}},"teacher":{"type":"object","properties":{"uid":{"type":"string","format":"uuid","description":"Unique ID of the teacher in the system that can be used in other API end points"},"name":{"type":"string","description":"Name of the teacher"},"about":{"type":"string","description":"A short summary the teacher provides about themselves"},"photo":{"type":"string","format":"uri","description":"Photo of the teacher"},"url":{"type":"string","format":"uri","description":"URL to the Outschool profile page of the teacher"}}},"section":{"type":"object","description":"Sections are what parents enroll their children in for a given class. They are separate cohorts of a class.","properties":{"uid":{"type":"string","format":"uuid","description":"Unique ID of the section in the system that can be used in other API end points"},"url":{"type":"string","format":"uri","description":"URL pointing to the section page"},"start_time":{"type":"string","format":"datetime","description":"The start time for the first meeting of a section."},"end_time":{"type":"string","format":"datetime","description":"The end time for the last meeting of a section."},"size_max":{"type":"number","description":"How many learners can enroll in the section."},"filledSpaceCount":{"type":"number","description":"How many learners are enrolled in the section. size_max - filledSpaceCount gives how many seats are left to enroll in."},"nextOngoingMeeting":{"$ref":"#/components/schemas/meeting","nullable":true,"description":"If the class is an ongoing class, this points to the next meeting for the section."}}},"meeting":{"type":"object","description":"The online meeting for a section. Meetings are held on Zoom.","properties":{"uid":{"type":"string","format":"uuid","description":"Unique ID of the meeting in the system that can be used in other API end points"},"start_time":{"type":"string","format":"datetime","description":"The start time of the meeting."},"end_time":{"type":"string","format":"datetime","description":"The end time of the meeting."}}}}}}
14 changes: 14 additions & 0 deletions camel/functions/open_api_specs/outschool/paths/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
# Licensed under the Apache License, Version 2.0 (the “License”);
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an “AS IS” BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========
path_dict = {"get_classes": "/classes", "search_teachers": "/teachers"}
Loading

0 comments on commit 2f26b55

Please sign in to comment.