├── .gitignore ├── .well-known ├── ai-plugin.json ├── askup_logo.png └── openapi.yaml ├── Makefile ├── README.md ├── app.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .venv 3 | __pycache__/ 4 | linegptup*.json 5 | -------------------------------------------------------------------------------- /.well-known/ai-plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema_version": "v1", 3 | "name_for_model": "retrieval", 4 | "name_for_human": "AskUp Search", 5 | "description_for_model": "Plugin for searching through recent news, image, shopping, web, book, movie, blogs, local information, etc. The results will be json. Please is this to find answers to questions and retrieve relevant information. Use it whenever a user asks something about recent information.", 6 | "description_for_human": "Search through your documents.", 7 | "auth": { 8 | "type": "none" 9 | }, 10 | "api": { 11 | "type": "openapi", 12 | "url": "https://askup-plugin.sung.devstage.ai/.well-known/openapi.yaml", 13 | "has_user_authentication": false 14 | }, 15 | "logo_url": "https://askup-plugin.sung.devstage.ai/.well-known/askup_logo.png", 16 | "contact_email": "hunkim@gmail.com", 17 | "legal_info_url": "https://upstage.ai" 18 | } -------------------------------------------------------------------------------- /.well-known/askup_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hunkim/chatgpt-askup-search-plugin/42707d9c8003a6ee0447c42f0feeb9aac79f5aec/.well-known/askup_logo.png -------------------------------------------------------------------------------- /.well-known/openapi.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.1.0 2 | info: 3 | title: AskUp Search API 4 | description: A retrieval API for querying and filtering json results based on keyword based queries 5 | version: 1.0.0 6 | servers: 7 | - url: https://askup-plugin.sung.devstage.ai 8 | paths: 9 | /search/web: 10 | get: 11 | summary: Web search 12 | operationId: search_web_get 13 | parameters: 14 | - name: query 15 | in: query 16 | required: true 17 | schema: 18 | type: string 19 | description: Search query. 20 | responses: 21 | '200': 22 | description: Web search results relayed from Naver. 23 | content: 24 | application/json: 25 | schema: 26 | type: object 27 | 28 | /search/blog: 29 | get: 30 | summary: Blog search 31 | operationId: search_blog_get 32 | parameters: 33 | - name: query 34 | in: query 35 | required: true 36 | schema: 37 | type: string 38 | description: Search query. 39 | responses: 40 | '200': 41 | description: Blog search results relayed from Naver. 42 | content: 43 | application/json: 44 | schema: 45 | type: object 46 | 47 | /search/movie: 48 | get: 49 | summary: Movie search 50 | operationId: search_movie_get 51 | parameters: 52 | - name: query 53 | in: query 54 | required: true 55 | schema: 56 | type: string 57 | description: Search query. 58 | responses: 59 | '200': 60 | description: Movie search results relayed from Naver. 61 | content: 62 | application/json: 63 | schema: 64 | type: object 65 | 66 | /search/news: 67 | get: 68 | summary: News search 69 | operationId: search_news_get 70 | parameters: 71 | - name: query 72 | in: query 73 | required: true 74 | schema: 75 | type: string 76 | description: Search query. 77 | responses: 78 | '200': 79 | description: News search results relayed from Naver. 80 | content: 81 | application/json: 82 | schema: 83 | type: object 84 | 85 | /search/local: 86 | get: 87 | summary: Local search 88 | operationId: search_local_get 89 | parameters: 90 | - name: query 91 | in: query 92 | required: true 93 | schema: 94 | type: string 95 | description: Search query. 96 | responses: 97 | '200': 98 | description: Local search results relayed from Naver. 99 | content: 100 | application/json: 101 | schema: 102 | type: object 103 | 104 | /search/book: 105 | get: 106 | summary: Book search 107 | operationId: search_book_get 108 | parameters: 109 | - name: query 110 | in: query 111 | required: true 112 | schema: 113 | type: string 114 | description: Search query. 115 | responses: 116 | '200': 117 | description: Book search results relayed from Naver. 118 | content: 119 | application/json: 120 | schema: 121 | type: object 122 | 123 | /search/shop: 124 | get: 125 | summary: Shop search 126 | operationId: search_shop_get 127 | parameters: 128 | - name: query 129 | in: query 130 | required: true 131 | schema: 132 | type: string 133 | description: Search query. 134 | responses: 135 | '200': 136 | description: Shop search results relayed from Naver. 137 | content: 138 | application/json: 139 | schema: 140 | type: object 141 | 142 | /search/image: 143 | get: 144 | summary: Image search 145 | operationId: search_image_get 146 | parameters: 147 | - name: query 148 | in: query 149 | required: true 150 | schema: 151 | type: string 152 | description: Search query. 153 | responses: 154 | '200': 155 | description: Image search results relayed from Naver. 156 | content: 157 | application/json: 158 | schema: 159 | type: object 160 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VENV = .venv 2 | PYTHON = $(VENV)/bin/python3 3 | PIP = $(VENV)/bin/pip3 4 | UVICORN = $(VENV)/bin/uvicorn 5 | 6 | include .env 7 | export 8 | 9 | # Need to use python 3.9 for aws lambda 10 | $(VENV)/bin/activate: requirements.txt 11 | python3 -m venv $(VENV) 12 | $(PIP) install -r requirements.txt 13 | 14 | app: $(VENV)/bin/activate 15 | $(UVICORN) app:app --reload --port 1034 16 | 17 | clean: 18 | rm -rf __pycache__ 19 | rm -rf $(VENV) 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # chatgpt-askup-search-plugin 2 | AskUp Search ChatGPT Plugin 3 | 4 | ## Install 5 | image 6 | 7 | ## Enjoy 8 | image 9 | 10 | ## Code and Contributions 11 | Feel free to send us PR 12 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | import os 2 | from typing import Optional 3 | 4 | import httpx 5 | from fastapi import Depends, FastAPI, HTTPException 6 | from fastapi.staticfiles import StaticFiles 7 | from pydantic import BaseModel 8 | 9 | app = FastAPI() 10 | app.mount("/.well-known", StaticFiles(directory=".well-known"), 11 | name=".well-known") 12 | 13 | 14 | API_BASE_URL = "https://openapi.naver.com/v1/search/" 15 | 16 | # Set your Naver API credentials here or as environment variables 17 | NAVER_CLIENT_ID = os.environ["NAVER_CLIENT_ID"] 18 | NAVER_CLIENT_SECRET = os.environ["NAVER_CLIENT_SECRET"] 19 | 20 | 21 | async def get_naver_headers(): 22 | return { 23 | "X-Naver-Client-Id": NAVER_CLIENT_ID, 24 | "X-Naver-Client-Secret": NAVER_CLIENT_SECRET, 25 | } 26 | 27 | @app.get("/search/news", response_model=dict, summary="News search") 28 | async def search_news(query: str, headers: dict = Depends(get_naver_headers)): 29 | """ 30 | Relay Naver news search results. 31 | 32 | Args: 33 | query (str): Search query. 34 | """ 35 | async with httpx.AsyncClient() as client: 36 | response = await client.get(API_BASE_URL + "news.json", params={"query": query}, headers=headers) 37 | return response.json() 38 | 39 | 40 | @app.get("/search/local", response_model=dict, summary="Local search") 41 | async def search_local(query: str, headers: dict = Depends(get_naver_headers)): 42 | """ 43 | Relay Naver local search results. 44 | 45 | Args: 46 | query (str): Search query. 47 | """ 48 | async with httpx.AsyncClient() as client: 49 | response = await client.get(API_BASE_URL + "local.json", params={"query": query}, headers=headers) 50 | return response.json() 51 | 52 | 53 | @app.get("/search/blog", response_model=dict, summary="Blog search") 54 | async def search_blog(query: str, headers: dict = Depends(get_naver_headers)): 55 | """ 56 | Relay Naver blog search results. 57 | 58 | Args: 59 | query (str): Search query. 60 | """ 61 | async with httpx.AsyncClient() as client: 62 | response = await client.get(API_BASE_URL + "blog.json", params={"query": query}, headers=headers) 63 | return response.json() 64 | 65 | 66 | @app.get("/search/image", response_model=dict, summary="Image search") 67 | async def search_image(query: str, headers: dict = Depends(get_naver_headers)): 68 | """ 69 | Relay Naver image search results. 70 | 71 | Args: 72 | query (str): Search query. 73 | """ 74 | async with httpx.AsyncClient() as client: 75 | response = await client.get(API_BASE_URL + "image", params={"query": query}, headers=headers) 76 | return response.json() 77 | 78 | 79 | @app.get("/search/movie", response_model=dict, summary="Movie search") 80 | async def search_movie(query: str, headers: dict = Depends(get_naver_headers)): 81 | """ 82 | Relay Naver movie search results. 83 | 84 | Args: 85 | query (str): Search query. 86 | """ 87 | async with httpx.AsyncClient() as client: 88 | response = await client.get(API_BASE_URL + "movie.json", params={"query": query}, headers=headers) 89 | return response.json() 90 | 91 | 92 | @app.get("/search/web", response_model=dict, summary="Web search") 93 | async def search_web(query: str, headers: dict = Depends(get_naver_headers)): 94 | """ 95 | Relay Naver web search results. 96 | 97 | Args: 98 | query (str): Search query. 99 | """ 100 | async with httpx.AsyncClient() as client: 101 | response = await client.get(API_BASE_URL + "webkr.json", params={"query": query}, headers=headers) 102 | return response.json() 103 | 104 | 105 | 106 | @app.get("/search/book", response_model=dict, summary="Book search") 107 | async def search_book(query: str, headers: dict = Depends(get_naver_headers)): 108 | """ 109 | Relay Naver book search results. 110 | 111 | Args: 112 | query (str): Search query. 113 | """ 114 | async with httpx.AsyncClient() as client: 115 | response = await client.get(API_BASE_URL + "book.json", params={"query": query}, headers=headers) 116 | return response.json() 117 | 118 | 119 | 120 | 121 | @app.get("/search/shop", response_model=dict, summary="Shop search") 122 | async def search_shop(query: str, headers: dict = Depends(get_naver_headers)): 123 | """ 124 | Relay Naver shop search results. 125 | 126 | Args: 127 | query (str): Search query. 128 | """ 129 | async with httpx.AsyncClient() as client: 130 | response = await client.get(API_BASE_URL + "shop.json", params={"query": query}, headers=headers) 131 | return response.json() -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | fastapi[all] 3 | --------------------------------------------------------------------------------