├── .DS_Store ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── doc ├── Screenshot-1.png ├── Screenshot-2.png ├── Screenshot-3.png ├── Screenshot-4.png ├── Screenshot-5.png ├── index.png └── logo-20240412.png ├── docker-compose.yaml ├── free_ask_internet.py ├── requirements.txt ├── searxng ├── settings.yml └── uwsgi.ini └── server.py /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nashsu/FreeAskInternet/3fa58d17e9080171f4686c128df9f61b3265a4d9/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | *.py[cod] 3 | *$py.class 4 | 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.9.15 2 | 3 | WORKDIR /app 4 | COPY requirements.txt /app 5 | RUN pip3 install -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com -r requirements.txt --no-cache-dir 6 | COPY . /app 7 | EXPOSE 8000 8 | ENTRYPOINT ["python3"] 9 | CMD ["server.py"] 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FreeAskInternet 2 | 3 | ## 🎉🎉🎉 Yeah we have a logo now! 🎉🎉🎉 4 | 5 | ![lgoo](./doc/logo-20240412.png) 6 | 7 | > Running www.perplexity.ai like app complete FREE, LOCAL, PRIVATE and NO GPU NEED on any computer 8 | > [!IMPORTANT] 9 | > **If you are unable to use this project normally, it is most likely due to issues with your internet connection or your IP, you need free internet connection to use this project normally. 如果您无法正常使用此项目,很可能是由于您的 IP 存在问题,或者你不能自由访问互联网。** 10 | 11 | ## What is FreeAskInternet 12 | 13 | FreeAskInternet is a completely free, private and locally running search aggregator & answer generate using LLM, Without GPU needed. The user can ask a question and the system will use searxng to make a multi engine search and combine the search result to the ChatGPT3.5 LLM and generate the answer based on search results. All process running locally and No GPU or OpenAI or Google API keys are needed. 14 | 15 | ## Features 16 | 17 | - 🈚️ Completely FREE (no need for any API keys) 18 | - 💻 Completely LOCAL (no GPU need, any computer can run ) 19 | - 🔐 Completely PRIVATE (all thing running locally, using custom llm) 20 | - 👻 Runs WITHOUT LLM Hardware (NO GPU NEED!) 21 | - 🤩 Using Free ChatGPT3.5 / Qwen / Kimi / ZhipuAI(GLM) API (NO API keys need! Thx OpenAI) 22 | - 🐵 Custom LLM(ollama,llama.cpp) support, Yes we love ollama! 23 | - 🚀 Fast and easy to deploy with Docker Compose 24 | - 🌐 Web and Mobile friendly interface, designed for Web Search enhanced AI Chat, allowing for easy access from any device. 25 | 26 | ## Screenshots 27 | 28 | 1. index: 29 | 30 | ![index](./doc/index.png) 31 | 32 | 2. Search based AI Chat: 33 | 34 | ![index](./doc/Screenshot-4.png) 35 | 36 | 3. Multi LLM models and custom LLM like ollama support: 37 | 38 | ![index](./doc/Screenshot-5.png) 39 | 40 | ## How It Works? 41 | 42 | 1. System get user input question in FreeAskInternet UI interface( running locally), and call searxng (running locally) to make search on multi search engine. 43 | 2. crawl search result links content and pass to ChatGPT3.5 / Kimi / Qwen / ZhipuAI / ollama (by using custom llm), ask LLM to answer user question based on this contents as references. 44 | 3. Stream the answer to Chat UI. 45 | 4. We support custom LLM setting, so theoretically infinite llm support. 46 | 47 | ## Status 48 | 49 | This project is still in its very early days. Expect some bugs. 50 | 51 | ### Run the latest release 52 | 53 | ```bash 54 | git clone https://github.com/nashsu/FreeAskInternet.git 55 | cd ./FreeAskInternet 56 | docker-compose up -d 57 | ``` 58 | 59 | 🎉 You should now be able to open the web interface on http://localhost:3000. Nothing else is exposed by default.( For old web interface, accessing http://localhost:3030) 60 | 61 | ## How to get and set Kimi / Qwen / ZhipuAI Token? 62 | 63 | How to get Token? 64 | 65 | We are using [https://github.com/LLM-Red-Team](https://github.com/LLM-Red-Team) projects to provide those service, you can reference to their readme. 66 | 67 | Reference : [https://github.com/LLM-Red-Team/kimi-free-api](https://github.com/LLM-Red-Team/kimi-free-api) 68 | 69 | ![setting token](./doc/Screenshot-3.png) 70 | 71 | ## How to using custom LLM like ollama? (Yes we love ollama) 72 | 73 | 1. start ollama serve 74 | 75 | ```bash 76 | export OLLAMA_HOST=0.0.0.0 77 | ollama serve 78 | ``` 79 | 80 | 2. set ollama url in setting: 81 | You MUST using your computer's ip address, not localhost/127.0.0.1, because in docker you can't access this address. 82 | The model name is the model you want to serve by ollama. 83 | ![setting custom llm url](./doc/Screenshot-2.png) 84 | 85 | ollama model Reference : [https://ollama.com/library](https://ollama.com/library) 86 | 87 | ### How to update to latest 88 | 89 | ```bash 90 | cd ./FreeAskInternet 91 | git pull 92 | docker compose down 93 | docker compose rm backend 94 | docker compose rm free_ask_internet_ui 95 | docker image rm nashsu/free_ask_internet 96 | docker image rm nashsu/free_ask_internet_ui 97 | docker-compose up -d 98 | ``` 99 | 100 | ## Credits 101 | 102 | - ChatGPT-Next-Web : [https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web) 103 | - FreeGPT35: [https://github.com/missuo/FreeGPT35](https://github.com/missuo/FreeGPT35) 104 | - Kimi\Qwen\ZhipuAI [https://github.com/LLM-Red-Team](https://github.com/LLM-Red-Team) 105 | - searxng: [https://github.com/searxng/searxng](https://github.com/searxng/searxng) 106 | 107 | ## Special thanks to our logo designer 108 | 109 | [AdlerMurcus](https://github.com/AdlerMurcus) 110 | 111 | 112 | 113 | 114 | 115 | ## License 116 | 117 | Apache-2.0 license 118 | 119 | ## Star History 120 | 121 | [![Star History Chart](https://api.star-history.com/svg?repos=nashsu/FreeAskInternet&type=Date)](https://star-history.com/#nashsu/FreeAskInternet&Date) 122 | -------------------------------------------------------------------------------- /doc/Screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nashsu/FreeAskInternet/3fa58d17e9080171f4686c128df9f61b3265a4d9/doc/Screenshot-1.png -------------------------------------------------------------------------------- /doc/Screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nashsu/FreeAskInternet/3fa58d17e9080171f4686c128df9f61b3265a4d9/doc/Screenshot-2.png -------------------------------------------------------------------------------- /doc/Screenshot-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nashsu/FreeAskInternet/3fa58d17e9080171f4686c128df9f61b3265a4d9/doc/Screenshot-3.png -------------------------------------------------------------------------------- /doc/Screenshot-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nashsu/FreeAskInternet/3fa58d17e9080171f4686c128df9f61b3265a4d9/doc/Screenshot-4.png -------------------------------------------------------------------------------- /doc/Screenshot-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nashsu/FreeAskInternet/3fa58d17e9080171f4686c128df9f61b3265a4d9/doc/Screenshot-5.png -------------------------------------------------------------------------------- /doc/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nashsu/FreeAskInternet/3fa58d17e9080171f4686c128df9f61b3265a4d9/doc/index.png -------------------------------------------------------------------------------- /doc/logo-20240412.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nashsu/FreeAskInternet/3fa58d17e9080171f4686c128df9f61b3265a4d9/doc/logo-20240412.png -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | backend: 3 | image: docker.io/nashsu/free_ask_internet:latest 4 | depends_on: 5 | - llm-freegpt35 6 | restart: on-failure 7 | 8 | 9 | freeaskinternet-ui: 10 | image: docker.io/nashsu/free_ask_internet_ui:latest 11 | ports: 12 | - "3000:80" 13 | environment: 14 | BACKEND_HOST: "backend:8000" 15 | depends_on: 16 | - backend 17 | restart: always 18 | 19 | chatgpt-next-web: 20 | image: yidadaa/chatgpt-next-web 21 | ports: 22 | - "3030:3000" 23 | environment: 24 | OPENAI_API_KEY: "FreeAskInternet" 25 | # CODE: "FreeAskInternet" # 如果你想要设置页面的访问密码,请修改这里 26 | BASE_URL: "http://backend:8000" 27 | CUSTOM_MODELS: "-all,+gpt-3.5-turbo" 28 | depends_on: 29 | - llm-freegpt35 30 | restart: always 31 | 32 | llm-freegpt35: 33 | image: missuo/freegpt35:latest 34 | restart: always 35 | 36 | llm-kimi: 37 | image: vinlic/kimi-free-api:latest 38 | restart: always 39 | environment: 40 | - TZ=Asia/Shanghai 41 | 42 | llm-glm4: 43 | image: vinlic/glm-free-api:latest 44 | restart: always 45 | environment: 46 | - TZ=Asia/Shanghai 47 | 48 | 49 | llm-qwen: 50 | image: vinlic/qwen-free-api:latest 51 | restart: always 52 | environment: 53 | - TZ=Asia/Shanghai 54 | 55 | searxng: 56 | image: docker.io/searxng/searxng:latest 57 | volumes: 58 | - ./searxng:/etc/searxng:rw 59 | environment: 60 | - SEARXNG_BASE_URL=https://${SEARXNG_HOSTNAME:-localhost}/ 61 | cap_drop: 62 | - ALL 63 | cap_add: 64 | - CHOWN 65 | - SETGID 66 | - SETUID 67 | logging: 68 | driver: 'json-file' 69 | options: 70 | max-size: '1m' 71 | max-file: '1' 72 | restart: always 73 | -------------------------------------------------------------------------------- /free_ask_internet.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import json 4 | import os 5 | from pprint import pprint 6 | import requests 7 | import trafilatura 8 | from trafilatura import bare_extraction 9 | from concurrent.futures import ThreadPoolExecutor 10 | import concurrent 11 | import requests 12 | import openai 13 | import time 14 | from datetime import datetime 15 | from urllib.parse import urlparse 16 | import tldextract 17 | import platform 18 | import urllib.parse 19 | 20 | 21 | def extract_url_content(url): 22 | downloaded = trafilatura.fetch_url(url) 23 | content = trafilatura.extract(downloaded) 24 | 25 | return {"url":url, "content":content} 26 | 27 | 28 | 29 | 30 | def search_web_ref(query:str, debug=False): 31 | 32 | content_list = [] 33 | 34 | try: 35 | 36 | safe_string = urllib.parse.quote_plus(":all !general " + query) 37 | 38 | response = requests.get('http://searxng:8080?q=' + safe_string + '&format=json') 39 | response.raise_for_status() 40 | search_results = response.json() 41 | 42 | if debug: 43 | print("JSON Response:") 44 | pprint(search_results) 45 | pedding_urls = [] 46 | 47 | conv_links = [] 48 | 49 | if search_results.get('results'): 50 | for item in search_results.get('results')[0:9]: 51 | name = item.get('title') 52 | snippet = item.get('content') 53 | url = item.get('url') 54 | pedding_urls.append(url) 55 | 56 | if url: 57 | url_parsed = urlparse(url) 58 | domain = url_parsed.netloc 59 | icon_url = url_parsed.scheme + '://' + url_parsed.netloc + '/favicon.ico' 60 | site_name = tldextract.extract(url).domain 61 | 62 | conv_links.append({ 63 | 'site_name':site_name, 64 | 'icon_url':icon_url, 65 | 'title':name, 66 | 'url':url, 67 | 'snippet':snippet 68 | }) 69 | 70 | results = [] 71 | futures = [] 72 | 73 | executor = ThreadPoolExecutor(max_workers=10) 74 | for url in pedding_urls: 75 | futures.append(executor.submit(extract_url_content,url)) 76 | try: 77 | for future in futures: 78 | res = future.result(timeout=5) 79 | results.append(res) 80 | except concurrent.futures.TimeoutError: 81 | print("任务执行超时") 82 | executor.shutdown(wait=False,cancel_futures=True) 83 | 84 | for content in results: 85 | if content and content.get('content'): 86 | 87 | item_dict = { 88 | "url":content.get('url'), 89 | "content": content.get('content'), 90 | "length":len(content.get('content')) 91 | } 92 | content_list.append(item_dict) 93 | if debug: 94 | print("URL: {}".format(url)) 95 | print("=================") 96 | 97 | return conv_links,content_list 98 | except Exception as ex: 99 | raise ex 100 | 101 | 102 | def gen_prompt(question,content_list, lang="zh-CN", context_length_limit=11000,debug=False): 103 | 104 | limit_len = (context_length_limit - 2000) 105 | if len(question) > limit_len: 106 | question = question[0:limit_len] 107 | 108 | ref_content = [ item.get("content") for item in content_list] 109 | 110 | answer_language = ' Simplified Chinese ' 111 | if lang == "zh-CN": 112 | answer_language = ' Simplified Chinese ' 113 | if lang == "zh-TW": 114 | answer_language = ' Traditional Chinese ' 115 | if lang == "en-US": 116 | answer_language = ' English ' 117 | 118 | 119 | if len(ref_content) > 0: 120 | 121 | if False: 122 | prompts = ''' 123 | 您是一位由 nash_su 开发的大型语言人工智能助手。您将被提供一个用户问题,并需要撰写一个清晰、简洁且准确的答案。提供了一组与问题相关的上下文,每个都以[[citation:x]]这样的编号开头,x代表一个数字。请在适当的情况下在句子末尾引用上下文。答案必须正确、精确,并以专家的中立和职业语气撰写。请将答案限制在2000个标记内。不要提供与问题无关的信息,也不要重复。如果给出的上下文信息不足,请在相关主题后写上“信息缺失:”。请按照引用编号[citation:x]的格式在答案中对应部分引用上下文。如果一句话源自多个上下文,请列出所有相关的引用编号,例如[citation:3][citation:5],不要将引用集中在最后返回,而是在答案对应部分列出。除非是代码、特定的名称或引用编号,答案的语言应与问题相同。以下是上下文的内容集: 124 | ''' + "\n\n" + "```" 125 | ref_index = 1 126 | 127 | for ref_text in ref_content: 128 | 129 | prompts = prompts + "\n\n" + " [citation:{}] ".format(str(ref_index)) + ref_text 130 | ref_index += 1 131 | 132 | if len(prompts) >= limit_len: 133 | prompts = prompts[0:limit_len] 134 | prompts = prompts + ''' 135 | ``` 136 | 记住,不要一字不差的重复上下文内容. 回答必须使用简体中文,如果回答很长,请尽量结构化、分段落总结。请按照引用编号[citation:x]的格式在答案中对应部分引用上下文。如果一句话源自多个上下文,请列出所有相关的引用编号,例如[citation:3][citation:5],不要将引用集中在最后返回,而是在答案对应部分列出。下面是用户问题: 137 | ''' + question 138 | else: 139 | prompts = ''' 140 | You are a large language AI assistant develop by nash_su. You are given a user question, and please write clean, concise and accurate answer to the question. You will be given a set of related contexts to the question, each starting with a reference number like [[citation:x]], where x is a number. Please use the context and cite the context at the end of each sentence if applicable. 141 | Your answer must be correct, accurate and written by an expert using an unbiased and professional tone. Please limit to 1024 tokens. Do not give any information that is not related to the question, and do not repeat. Say "information is missing on" followed by the related topic, if the given context do not provide sufficient information. 142 | 143 | Please cite the contexts with the reference numbers, in the format [citation:x]. If a sentence comes from multiple contexts, please list all applicable citations, like [citation:3][citation:5]. Other than code and specific names and citations, your answer must be written in the same language as the question. 144 | Here are the set of contexts: 145 | ''' + "\n\n" + "```" 146 | ref_index = 1 147 | 148 | for ref_text in ref_content: 149 | 150 | prompts = prompts + "\n\n" + " [citation:{}] ".format(str(ref_index)) + ref_text 151 | ref_index += 1 152 | 153 | if len(prompts) >= limit_len: 154 | prompts = prompts[0:limit_len] 155 | prompts = prompts + ''' 156 | ``` 157 | Above is the reference contexts. Remember, don't repeat the context word for word. Answer in ''' + answer_language + '''. If the response is lengthy, structure it in paragraphs and summarize where possible. Cite the context using the format [citation:x] where x is the reference number. If a sentence originates from multiple contexts, list all relevant citation numbers, like [citation:3][citation:5]. Don't cluster the citations at the end but include them in the answer where they correspond. 158 | Remember, don't blindly repeat the contexts verbatim. And here is the user question: 159 | ''' + question 160 | 161 | 162 | else: 163 | prompts = question 164 | 165 | if debug: 166 | print(prompts) 167 | print("总长度:"+ str(len(prompts))) 168 | return prompts 169 | 170 | 171 | def chat(prompt, model:str,llm_auth_token:str,llm_base_url:str,using_custom_llm=False,stream=True, debug=False): 172 | openai.base_url = "http://127.0.0.1:3040/v1/" 173 | 174 | if model == "gpt3.5": 175 | openai.base_url = "http://llm-freegpt35:3040/v1/" 176 | 177 | if model == "kimi": 178 | openai.base_url = "http://llm-kimi:8000/v1/" 179 | if model == "glm4": 180 | openai.base_url = "http://llm-glm4:8000/v1/" 181 | if model == "qwen": 182 | openai.base_url = "http://llm-qwen:8000/v1/" 183 | 184 | 185 | if llm_auth_token == '': 186 | llm_auth_token = "CUSTOM" 187 | 188 | openai.api_key = llm_auth_token 189 | 190 | if using_custom_llm: 191 | openai.base_url = llm_base_url 192 | openai.api_key = llm_auth_token 193 | 194 | 195 | total_content = "" 196 | for chunk in openai.chat.completions.create( 197 | model=model, 198 | messages=[{ 199 | "role": "user", 200 | "content": prompt 201 | }], 202 | stream=True, 203 | max_tokens=1024,temperature=0.2 204 | ): 205 | stream_resp = chunk.dict() 206 | token = stream_resp["choices"][0]["delta"].get("content", "") 207 | if token: 208 | 209 | total_content += token 210 | yield token 211 | if debug: 212 | print(total_content) 213 | 214 | 215 | 216 | 217 | def ask_internet(query:str, debug=False): 218 | 219 | content_list = search_web_ref(query,debug=debug) 220 | if debug: 221 | print(content_list) 222 | prompt = gen_prompt(query,content_list,context_length_limit=6000,debug=debug) 223 | total_token = "" 224 | 225 | for token in chat(prompt=prompt): 226 | # for token in daxianggpt.chat(prompt=prompt): 227 | if token: 228 | total_token += token 229 | yield token 230 | yield "\n\n" 231 | # 是否返回参考资料 232 | if True: 233 | yield "---" 234 | yield "\n" 235 | yield "参考资料:\n" 236 | count = 1 237 | for url_content in content_list: 238 | url = url_content.get('url') 239 | yield "*[{}. {}]({})*".format(str(count),url,url ) 240 | yield "\n" 241 | count += 1 242 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | annotated-types==0.6.0 2 | anyio==4.3.0 3 | certifi==2024.2.2 4 | charset-normalizer==3.3.2 5 | click==8.1.7 6 | courlan==1.0.0 7 | dateparser==1.2.0 8 | distro==1.9.0 9 | exceptiongroup==1.2.0 10 | fastapi==0.110.1 11 | filelock==3.13.3 12 | h11==0.14.0 13 | htmldate==1.8.0 14 | httpcore==1.0.5 15 | httpx==0.27.0 16 | idna==3.6 17 | jusText==3.0.0 18 | langcodes==3.3.0 19 | lxml==5.1.1 20 | openai==1.16.2 21 | pydantic==2.6.4 22 | pydantic_core==2.16.3 23 | python-dateutil==2.9.0.post0 24 | pytz==2024.1 25 | regex==2023.12.25 26 | requests==2.31.0 27 | requests-file==2.0.0 28 | six==1.16.0 29 | sniffio==1.3.1 30 | sse-starlette==2.0.0 31 | starlette==0.37.2 32 | tld==0.13 33 | tldextract==5.1.2 34 | tqdm==4.66.2 35 | trafilatura==1.8.1 36 | typing_extensions==4.10.0 37 | tzlocal==5.2 38 | urllib3==2.2.1 39 | uvicorn==0.29.0 40 | -------------------------------------------------------------------------------- /searxng/settings.yml: -------------------------------------------------------------------------------- 1 | general: 2 | # Debug mode, only for development. Is overwritten by ${SEARXNG_DEBUG} 3 | debug: false 4 | # displayed name 5 | instance_name: "free_ask_internet" 6 | # For example: https://example.com/privacy 7 | privacypolicy_url: false 8 | # use true to use your own donation page written in searx/info/en/donate.md 9 | # use false to disable the donation link 10 | donation_url: false 11 | # mailto:contact@example.com 12 | contact_url: false 13 | # record stats 14 | enable_metrics: true 15 | 16 | brand: 17 | new_issue_url: https://github.com/searxng/searxng/issues/new 18 | docs_url: https://docs.searxng.org/ 19 | public_instances: https://searx.space 20 | wiki_url: https://github.com/searxng/searxng/wiki 21 | issue_url: https://github.com/searxng/searxng/issues 22 | # custom: 23 | # maintainer: "Jon Doe" 24 | # # Custom entries in the footer: [title]: [link] 25 | # links: 26 | # Uptime: https://uptime.searxng.org/history/darmarit-org 27 | # About: "https://searxng.org" 28 | 29 | search: 30 | # Filter results. 0: None, 1: Moderate, 2: Strict 31 | safe_search: 0 32 | # Existing autocomplete backends: "dbpedia", "duckduckgo", "google", "yandex", "mwmbl", 33 | # "seznam", "startpage", "stract", "swisscows", "qwant", "wikipedia" - leave blank to turn it off 34 | # by default. 35 | autocomplete: "" 36 | # minimun characters to type before autocompleter starts 37 | # Default search language - leave blank to detect from browser information or 38 | # use codes from 'languages.py' 39 | default_lang: "auto" 40 | ban_time_on_fail: 1 41 | max_ban_time_on_fail: 120 42 | suspended_times: 43 | SearxEngineAccessDenied: 86400 44 | SearxEngineCaptcha: 86400 45 | SearxEngineTooManyRequests: 3600 46 | cf_SearxEngineCaptcha: 1296000 47 | cf_SearxEngineAccessDenied: 86400 48 | recaptcha_SearxEngineCaptcha: 604800 49 | formats: 50 | - html 51 | - json 52 | 53 | server: 54 | # Is overwritten by ${SEARXNG_PORT} and ${SEARXNG_BIND_ADDRESS} 55 | port: 8080 56 | bind_address: "0.0.0.0" 57 | # public URL of the instance, to ensure correct inbound links. Is overwritten 58 | # by ${SEARXNG_URL}. 59 | base_url: http://localhost:/ # "http://example.com/location" 60 | limiter: false # rate limit the number of request on the instance, block some bots 61 | public_instance: false # enable features designed only for public instances 62 | 63 | # If your instance owns a /etc/searxng/settings.yml file, then set the following 64 | # values there. 65 | 66 | secret_key: "f884dadd9e6b23ea6c073a031b18daa0288ff1d82a1c5514089f0ecb32ac7a54" # Is overwritten by ${SEARXNG_SECRET} 67 | # Proxying image results through searx 68 | image_proxy: false 69 | # 1.0 and 1.1 are supported 70 | http_protocol_version: "1.0" 71 | # POST queries are more secure as they don't show up in history but may cause 72 | # problems when using Firefox containers 73 | method: "POST" 74 | default_http_headers: 75 | X-Content-Type-Options: nosniff 76 | X-Download-Options: noopen 77 | X-Robots-Tag: noindex, nofollow 78 | Referrer-Policy: no-referrer 79 | 80 | redis: 81 | # URL to connect redis database. Is overwritten by ${SEARXNG_REDIS_URL}. 82 | # https://docs.searxng.org/admin/settings/settings_redis.html#settings-redis 83 | url: false 84 | 85 | ui: 86 | # Custom static path - leave it blank if you didn't change 87 | static_path: "" 88 | static_use_hash: false 89 | # Custom templates path - leave it blank if you didn't change 90 | templates_path: "" 91 | # query_in_title: When true, the result page's titles contains the query 92 | # it decreases the privacy, since the browser can records the page titles. 93 | query_in_title: false 94 | # infinite_scroll: When true, automatically loads the next page when scrolling to bottom of the current page. 95 | infinite_scroll: false 96 | # ui theme 97 | default_theme: simple 98 | # center the results ? 99 | center_alignment: false 100 | # URL prefix of the internet archive, don't forget trailing slash (if needed). 101 | # cache_url: "https://webcache.googleusercontent.com/search?q=cache:" 102 | # Default interface locale - leave blank to detect from browser information or 103 | # use codes from the 'locales' config section 104 | default_locale: "" 105 | # Open result links in a new tab by default 106 | # results_on_new_tab: false 107 | theme_args: 108 | # style of simple theme: auto, light, dark 109 | simple_style: auto 110 | # Perform search immediately if a category selected. 111 | # Disable to select multiple categories at once and start the search manually. 112 | search_on_category_select: true 113 | # Hotkeys: default or vim 114 | hotkeys: default 115 | 116 | # Lock arbitrary settings on the preferences page. To find the ID of the user 117 | # setting you want to lock, check the ID of the form on the page "preferences". 118 | # 119 | # preferences: 120 | # lock: 121 | # - language 122 | # - autocomplete 123 | # - method 124 | # - query_in_title 125 | 126 | # searx supports result proxification using an external service: 127 | # https://github.com/asciimoo/morty uncomment below section if you have running 128 | # morty proxy the key is base64 encoded (keep the !!binary notation) 129 | # Note: since commit af77ec3, morty accepts a base64 encoded key. 130 | # 131 | # result_proxy: 132 | # url: http://127.0.0.1:3000/ 133 | # # the key is a base64 encoded string, the YAML !!binary prefix is optional 134 | # key: !!binary "your_morty_proxy_key" 135 | # # [true|false] enable the "proxy" button next to each result 136 | # proxify_results: true 137 | 138 | # communication with search engines 139 | # 140 | outgoing: 141 | # default timeout in seconds, can be override by engine 142 | request_timeout: 3.0 143 | # the maximum timeout in seconds 144 | # max_request_timeout: 10.0 145 | # suffix of searx_useragent, could contain information like an email address 146 | # to the administrator 147 | useragent_suffix: "" 148 | # The maximum number of concurrent connections that may be established. 149 | pool_connections: 100 150 | # Allow the connection pool to maintain keep-alive connections below this 151 | # point. 152 | pool_maxsize: 20 153 | # See https://www.python-httpx.org/http2/ 154 | enable_http2: true 155 | # uncomment below section if you want to use a custom server certificate 156 | # see https://www.python-httpx.org/advanced/#changing-the-verification-defaults 157 | # and https://www.python-httpx.org/compatibility/#ssl-configuration 158 | # verify: ~/.mitmproxy/mitmproxy-ca-cert.cer 159 | # 160 | # uncomment below section if you want to use a proxyq see: SOCKS proxies 161 | # https://2.python-requests.org/en/latest/user/advanced/#proxies 162 | # are also supported: see 163 | # https://2.python-requests.org/en/latest/user/advanced/#socks 164 | # 165 | # proxies: 166 | # all://: 167 | # - http://proxy1:8080 168 | # - http://proxy2:8080 169 | # 170 | # using_tor_proxy: true 171 | # 172 | # Extra seconds to add in order to account for the time taken by the proxy 173 | # 174 | # extra_proxy_timeout: 10 175 | # 176 | # uncomment below section only if you have more than one network interface 177 | # which can be the source of outgoing search requests 178 | # 179 | # source_ips: 180 | # - 1.1.1.1 181 | # - 1.1.1.2 182 | # - fe80::/126 183 | 184 | # External plugin configuration, for more details see 185 | # https://docs.searxng.org/dev/plugins.html 186 | # 187 | # plugins: 188 | # - plugin1 189 | # - plugin2 190 | # - ... 191 | 192 | # Comment or un-comment plugin to activate / deactivate by default. 193 | # 194 | # enabled_plugins: 195 | # # these plugins are enabled if nothing is configured .. 196 | # - 'Hash plugin' 197 | # - 'Self Information' 198 | # - 'Tracker URL remover' 199 | # - 'Ahmia blacklist' # activation depends on outgoing.using_tor_proxy 200 | # # these plugins are disabled if nothing is configured .. 201 | # - 'Hostname replace' # see hostname_replace configuration below 202 | # - 'Open Access DOI rewrite' 203 | # - 'Tor check plugin' 204 | # # Read the docs before activate: auto-detection of the language could be 205 | # # detrimental to users expectations / users can activate the plugin in the 206 | # # preferences if they want. 207 | # - 'Autodetect search language' 208 | 209 | # Configuration of the "Hostname replace" plugin: 210 | # 211 | # hostname_replace: 212 | # '(.*\.)?youtube\.com$': 'invidious.example.com' 213 | # '(.*\.)?youtu\.be$': 'invidious.example.com' 214 | # '(.*\.)?youtube-noocookie\.com$': 'yotter.example.com' 215 | # '(.*\.)?reddit\.com$': 'teddit.example.com' 216 | # '(.*\.)?redd\.it$': 'teddit.example.com' 217 | # '(www\.)?twitter\.com$': 'nitter.example.com' 218 | # # to remove matching host names from result list, set value to false 219 | # 'spam\.example\.com': false 220 | 221 | checker: 222 | # disable checker when in debug mode 223 | off_when_debug: true 224 | 225 | # use "scheduling: false" to disable scheduling 226 | # scheduling: interval or int 227 | 228 | # to activate the scheduler: 229 | # * uncomment "scheduling" section 230 | # * add "cache2 = name=searxngcache,items=2000,blocks=2000,blocksize=4096,bitmap=1" 231 | # to your uwsgi.ini 232 | 233 | # scheduling: 234 | # start_after: [300, 1800] # delay to start the first run of the checker 235 | # every: [86400, 90000] # how often the checker runs 236 | 237 | # additional tests: only for the YAML anchors (see the engines section) 238 | # 239 | additional_tests: 240 | rosebud: &test_rosebud 241 | matrix: 242 | query: rosebud 243 | lang: en 244 | result_container: 245 | - not_empty 246 | - ['one_title_contains', 'citizen kane'] 247 | test: 248 | - unique_results 249 | 250 | android: &test_android 251 | matrix: 252 | query: ['android'] 253 | lang: ['en', 'de', 'fr', 'zh-CN'] 254 | result_container: 255 | - not_empty 256 | - ['one_title_contains', 'google'] 257 | test: 258 | - unique_results 259 | 260 | # tests: only for the YAML anchors (see the engines section) 261 | tests: 262 | infobox: &tests_infobox 263 | infobox: 264 | matrix: 265 | query: ["linux", "new york", "bbc"] 266 | result_container: 267 | - has_infobox 268 | 269 | categories_as_tabs: 270 | general: 271 | images: 272 | videos: 273 | news: 274 | map: 275 | music: 276 | it: 277 | science: 278 | files: 279 | social media: 280 | 281 | engines: 282 | - name: 9gag 283 | engine: 9gag 284 | shortcut: 9g 285 | disabled: true 286 | 287 | - name: annas archive 288 | engine: annas_archive 289 | disabled: true 290 | shortcut: aa 291 | 292 | # - name: annas articles 293 | # engine: annas_archive 294 | # shortcut: aaa 295 | # # https://docs.searxng.org/dev/engines/online/annas_archive.html 296 | # aa_content: 'magazine' # book_fiction, book_unknown, book_nonfiction, book_comic 297 | # aa_ext: 'pdf' # pdf, epub, .. 298 | # aa_sort: oldest' # newest, oldest, largest, smallest 299 | 300 | - name: apk mirror 301 | engine: apkmirror 302 | timeout: 4.0 303 | shortcut: apkm 304 | disabled: true 305 | 306 | - name: apple app store 307 | engine: apple_app_store 308 | shortcut: aps 309 | disabled: true 310 | 311 | # Requires Tor 312 | - name: ahmia 313 | engine: ahmia 314 | categories: onions 315 | enable_http: true 316 | shortcut: ah 317 | 318 | - name: anaconda 319 | engine: xpath 320 | paging: true 321 | first_page_num: 0 322 | search_url: https://anaconda.org/search?q={query}&page={pageno} 323 | results_xpath: //tbody/tr 324 | url_xpath: ./td/h5/a[last()]/@href 325 | title_xpath: ./td/h5 326 | content_xpath: ./td[h5]/text() 327 | categories: it 328 | timeout: 6.0 329 | shortcut: conda 330 | disabled: true 331 | 332 | - name: arch linux wiki 333 | engine: archlinux 334 | shortcut: al 335 | 336 | - name: artic 337 | engine: artic 338 | shortcut: arc 339 | timeout: 4.0 340 | 341 | - name: arxiv 342 | engine: arxiv 343 | shortcut: arx 344 | timeout: 4.0 345 | 346 | - name: ask 347 | engine: ask 348 | shortcut: ask 349 | disabled: true 350 | 351 | # tmp suspended: dh key too small 352 | # - name: base 353 | # engine: base 354 | # shortcut: bs 355 | 356 | - name: bandcamp 357 | engine: bandcamp 358 | shortcut: bc 359 | categories: music 360 | 361 | - name: wikipedia 362 | engine: wikipedia 363 | shortcut: wp 364 | # add "list" to the array to get results in the results list 365 | display_type: ["infobox"] 366 | base_url: 'https://{language}.wikipedia.org/' 367 | categories: [general] 368 | 369 | - name: bilibili 370 | engine: bilibili 371 | shortcut: bil 372 | disabled: true 373 | 374 | - name: bing 375 | engine: bing 376 | shortcut: bi 377 | disabled: true 378 | 379 | - name: bing images 380 | engine: bing_images 381 | shortcut: bii 382 | 383 | - name: bing news 384 | engine: bing_news 385 | shortcut: bin 386 | 387 | - name: bing videos 388 | engine: bing_videos 389 | shortcut: biv 390 | 391 | - name: bitbucket 392 | engine: xpath 393 | paging: true 394 | search_url: https://bitbucket.org/repo/all/{pageno}?name={query} 395 | url_xpath: //article[@class="repo-summary"]//a[@class="repo-link"]/@href 396 | title_xpath: //article[@class="repo-summary"]//a[@class="repo-link"] 397 | content_xpath: //article[@class="repo-summary"]/p 398 | categories: [it, repos] 399 | timeout: 4.0 400 | disabled: true 401 | shortcut: bb 402 | about: 403 | website: https://bitbucket.org/ 404 | wikidata_id: Q2493781 405 | official_api_documentation: https://developer.atlassian.com/bitbucket 406 | use_official_api: false 407 | require_api_key: false 408 | results: HTML 409 | 410 | - name: bpb 411 | engine: bpb 412 | shortcut: bpb 413 | disabled: true 414 | 415 | - name: btdigg 416 | engine: btdigg 417 | shortcut: bt 418 | disabled: true 419 | 420 | - name: ccc-tv 421 | engine: xpath 422 | paging: false 423 | search_url: https://media.ccc.de/search/?q={query} 424 | url_xpath: //div[@class="caption"]/h3/a/@href 425 | title_xpath: //div[@class="caption"]/h3/a/text() 426 | content_xpath: //div[@class="caption"]/h4/@title 427 | categories: videos 428 | disabled: true 429 | shortcut: c3tv 430 | about: 431 | website: https://media.ccc.de/ 432 | wikidata_id: Q80729951 433 | official_api_documentation: https://github.com/voc/voctoweb 434 | use_official_api: false 435 | require_api_key: false 436 | results: HTML 437 | # We don't set language: de here because media.ccc.de is not just 438 | # for a German audience. It contains many English videos and many 439 | # German videos have English subtitles. 440 | 441 | - name: openverse 442 | engine: openverse 443 | categories: images 444 | shortcut: opv 445 | 446 | - name: chefkoch 447 | engine: chefkoch 448 | shortcut: chef 449 | # to show premium or plus results too: 450 | # skip_premium: false 451 | 452 | # - name: core.ac.uk 453 | # engine: core 454 | # categories: science 455 | # shortcut: cor 456 | # # get your API key from: https://core.ac.uk/api-keys/register/ 457 | # api_key: 'unset' 458 | 459 | - name: cppreference 460 | engine: cppreference 461 | shortcut: cpp 462 | paging: false 463 | disabled: true 464 | 465 | - name: crossref 466 | engine: crossref 467 | shortcut: cr 468 | timeout: 30 469 | disabled: true 470 | 471 | - name: crowdview 472 | engine: json_engine 473 | shortcut: cv 474 | categories: general 475 | paging: false 476 | search_url: https://crowdview-next-js.onrender.com/api/search-v3?query={query} 477 | results_query: results 478 | url_query: link 479 | title_query: title 480 | content_query: snippet 481 | disabled: true 482 | about: 483 | website: https://crowdview.ai/ 484 | 485 | - name: yep 486 | engine: yep 487 | shortcut: yep 488 | categories: general 489 | search_type: web 490 | disabled: true 491 | 492 | - name: yep images 493 | engine: yep 494 | shortcut: yepi 495 | categories: images 496 | search_type: images 497 | disabled: true 498 | 499 | - name: yep news 500 | engine: yep 501 | shortcut: yepn 502 | categories: news 503 | search_type: news 504 | disabled: true 505 | 506 | - name: curlie 507 | engine: xpath 508 | shortcut: cl 509 | categories: general 510 | disabled: true 511 | paging: true 512 | lang_all: '' 513 | search_url: https://curlie.org/search?q={query}&lang={lang}&start={pageno}&stime=92452189 514 | page_size: 20 515 | results_xpath: //div[@id="site-list-content"]/div[@class="site-item"] 516 | url_xpath: ./div[@class="title-and-desc"]/a/@href 517 | title_xpath: ./div[@class="title-and-desc"]/a/div 518 | content_xpath: ./div[@class="title-and-desc"]/div[@class="site-descr"] 519 | about: 520 | website: https://curlie.org/ 521 | wikidata_id: Q60715723 522 | use_official_api: false 523 | require_api_key: false 524 | results: HTML 525 | 526 | - name: currency 527 | engine: currency_convert 528 | categories: general 529 | shortcut: cc 530 | 531 | - name: bahnhof 532 | engine: json_engine 533 | search_url: https://www.bahnhof.de/api/stations/search/{query} 534 | url_prefix: https://www.bahnhof.de/ 535 | url_query: slug 536 | title_query: name 537 | content_query: state 538 | shortcut: bf 539 | disabled: true 540 | about: 541 | website: https://www.bahn.de 542 | wikidata_id: Q22811603 543 | use_official_api: false 544 | require_api_key: false 545 | results: JSON 546 | language: de 547 | tests: 548 | bahnhof: 549 | matrix: 550 | query: berlin 551 | lang: en 552 | result_container: 553 | - not_empty 554 | - ['one_title_contains', 'Berlin Hauptbahnhof'] 555 | test: 556 | - unique_results 557 | 558 | - name: deezer 559 | engine: deezer 560 | shortcut: dz 561 | disabled: true 562 | 563 | - name: destatis 564 | engine: destatis 565 | shortcut: destat 566 | disabled: true 567 | 568 | - name: deviantart 569 | engine: deviantart 570 | shortcut: da 571 | timeout: 3.0 572 | 573 | - name: ddg definitions 574 | engine: duckduckgo_definitions 575 | shortcut: ddd 576 | weight: 2 577 | disabled: true 578 | tests: *tests_infobox 579 | 580 | # cloudflare protected 581 | # - name: digbt 582 | # engine: digbt 583 | # shortcut: dbt 584 | # timeout: 6.0 585 | # disabled: true 586 | 587 | - name: docker hub 588 | engine: docker_hub 589 | shortcut: dh 590 | categories: [it, packages] 591 | 592 | - name: erowid 593 | engine: xpath 594 | paging: true 595 | first_page_num: 0 596 | page_size: 30 597 | search_url: https://www.erowid.org/search.php?q={query}&s={pageno} 598 | url_xpath: //dl[@class="results-list"]/dt[@class="result-title"]/a/@href 599 | title_xpath: //dl[@class="results-list"]/dt[@class="result-title"]/a/text() 600 | content_xpath: //dl[@class="results-list"]/dd[@class="result-details"] 601 | categories: [] 602 | shortcut: ew 603 | disabled: true 604 | about: 605 | website: https://www.erowid.org/ 606 | wikidata_id: Q1430691 607 | official_api_documentation: 608 | use_official_api: false 609 | require_api_key: false 610 | results: HTML 611 | 612 | # - name: elasticsearch 613 | # shortcut: es 614 | # engine: elasticsearch 615 | # base_url: http://localhost:9200 616 | # username: elastic 617 | # password: changeme 618 | # index: my-index 619 | # # available options: match, simple_query_string, term, terms, custom 620 | # query_type: match 621 | # # if query_type is set to custom, provide your query here 622 | # #custom_query_json: {"query":{"match_all": {}}} 623 | # #show_metadata: false 624 | # disabled: true 625 | 626 | - name: wikidata 627 | engine: wikidata 628 | shortcut: wd 629 | timeout: 3.0 630 | weight: 2 631 | # add "list" to the array to get results in the results list 632 | display_type: ["infobox"] 633 | tests: *tests_infobox 634 | categories: [general] 635 | 636 | - name: duckduckgo 637 | engine: duckduckgo 638 | shortcut: ddg 639 | 640 | - name: duckduckgo images 641 | engine: duckduckgo_extra 642 | categories: [images, web] 643 | ddg_category: images 644 | shortcut: ddi 645 | disabled: true 646 | 647 | - name: duckduckgo videos 648 | engine: duckduckgo_extra 649 | categories: [videos, web] 650 | ddg_category: videos 651 | shortcut: ddv 652 | disabled: true 653 | 654 | - name: duckduckgo news 655 | engine: duckduckgo_extra 656 | categories: [news, web] 657 | ddg_category: news 658 | shortcut: ddn 659 | disabled: true 660 | 661 | - name: duckduckgo weather 662 | engine: duckduckgo_weather 663 | shortcut: ddw 664 | disabled: true 665 | 666 | - name: apple maps 667 | engine: apple_maps 668 | shortcut: apm 669 | disabled: true 670 | timeout: 5.0 671 | 672 | - name: emojipedia 673 | engine: emojipedia 674 | timeout: 4.0 675 | shortcut: em 676 | disabled: true 677 | 678 | - name: tineye 679 | engine: tineye 680 | shortcut: tin 681 | timeout: 9.0 682 | disabled: true 683 | 684 | - name: etymonline 685 | engine: xpath 686 | paging: true 687 | search_url: https://etymonline.com/search?page={pageno}&q={query} 688 | url_xpath: //a[contains(@class, "word__name--")]/@href 689 | title_xpath: //a[contains(@class, "word__name--")] 690 | content_xpath: //section[contains(@class, "word__defination")] 691 | first_page_num: 1 692 | shortcut: et 693 | categories: [dictionaries] 694 | about: 695 | website: https://www.etymonline.com/ 696 | wikidata_id: Q1188617 697 | official_api_documentation: 698 | use_official_api: false 699 | require_api_key: false 700 | results: HTML 701 | 702 | # - name: ebay 703 | # engine: ebay 704 | # shortcut: eb 705 | # base_url: 'https://www.ebay.com' 706 | # disabled: true 707 | # timeout: 5 708 | 709 | - name: 1x 710 | engine: www1x 711 | shortcut: 1x 712 | timeout: 3.0 713 | disabled: true 714 | 715 | - name: fdroid 716 | engine: fdroid 717 | shortcut: fd 718 | disabled: true 719 | 720 | - name: flickr 721 | categories: images 722 | shortcut: fl 723 | # You can use the engine using the official stable API, but you need an API 724 | # key, see: https://www.flickr.com/services/apps/create/ 725 | # engine: flickr 726 | # api_key: 'apikey' # required! 727 | # Or you can use the html non-stable engine, activated by default 728 | engine: flickr_noapi 729 | 730 | - name: free software directory 731 | engine: mediawiki 732 | shortcut: fsd 733 | categories: [it, software wikis] 734 | base_url: https://directory.fsf.org/ 735 | search_type: title 736 | timeout: 5.0 737 | disabled: true 738 | about: 739 | website: https://directory.fsf.org/ 740 | wikidata_id: Q2470288 741 | 742 | # - name: freesound 743 | # engine: freesound 744 | # shortcut: fnd 745 | # disabled: true 746 | # timeout: 15.0 747 | # API key required, see: https://freesound.org/docs/api/overview.html 748 | # api_key: MyAPIkey 749 | 750 | - name: frinkiac 751 | engine: frinkiac 752 | shortcut: frk 753 | disabled: true 754 | 755 | - name: fyyd 756 | engine: fyyd 757 | shortcut: fy 758 | timeout: 8.0 759 | disabled: true 760 | 761 | - name: genius 762 | engine: genius 763 | shortcut: gen 764 | 765 | - name: gentoo 766 | engine: gentoo 767 | shortcut: ge 768 | timeout: 10.0 769 | 770 | - name: gitlab 771 | engine: json_engine 772 | paging: true 773 | search_url: https://gitlab.com/api/v4/projects?search={query}&page={pageno} 774 | url_query: web_url 775 | title_query: name_with_namespace 776 | content_query: description 777 | page_size: 20 778 | categories: [it, repos] 779 | shortcut: gl 780 | timeout: 10.0 781 | disabled: true 782 | about: 783 | website: https://about.gitlab.com/ 784 | wikidata_id: Q16639197 785 | official_api_documentation: https://docs.gitlab.com/ee/api/ 786 | use_official_api: false 787 | require_api_key: false 788 | results: JSON 789 | 790 | - name: github 791 | engine: github 792 | shortcut: gh 793 | 794 | # This a Gitea service. If you would like to use a different instance, 795 | # change codeberg.org to URL of the desired Gitea host. Or you can create a 796 | # new engine by copying this and changing the name, shortcut and search_url. 797 | 798 | - name: codeberg 799 | engine: json_engine 800 | search_url: https://codeberg.org/api/v1/repos/search?q={query}&limit=10 801 | url_query: html_url 802 | title_query: name 803 | content_query: description 804 | categories: [it, repos] 805 | shortcut: cb 806 | disabled: true 807 | about: 808 | website: https://codeberg.org/ 809 | wikidata_id: 810 | official_api_documentation: https://try.gitea.io/api/swagger 811 | use_official_api: false 812 | require_api_key: false 813 | results: JSON 814 | 815 | - name: goodreads 816 | engine: goodreads 817 | shortcut: good 818 | timeout: 4.0 819 | disabled: true 820 | 821 | - name: google 822 | engine: google 823 | shortcut: go 824 | # additional_tests: 825 | # android: *test_android 826 | 827 | - name: google images 828 | engine: google_images 829 | shortcut: goi 830 | # additional_tests: 831 | # android: *test_android 832 | # dali: 833 | # matrix: 834 | # query: ['Dali Christ'] 835 | # lang: ['en', 'de', 'fr', 'zh-CN'] 836 | # result_container: 837 | # - ['one_title_contains', 'Salvador'] 838 | 839 | - name: google news 840 | engine: google_news 841 | shortcut: gon 842 | # additional_tests: 843 | # android: *test_android 844 | 845 | - name: google videos 846 | engine: google_videos 847 | shortcut: gov 848 | # additional_tests: 849 | # android: *test_android 850 | 851 | - name: google scholar 852 | engine: google_scholar 853 | shortcut: gos 854 | 855 | - name: google play apps 856 | engine: google_play 857 | categories: [files, apps] 858 | shortcut: gpa 859 | play_categ: apps 860 | disabled: true 861 | 862 | - name: google play movies 863 | engine: google_play 864 | categories: videos 865 | shortcut: gpm 866 | play_categ: movies 867 | disabled: true 868 | 869 | - name: material icons 870 | engine: material_icons 871 | categories: images 872 | shortcut: mi 873 | disabled: true 874 | 875 | - name: gpodder 876 | engine: json_engine 877 | shortcut: gpod 878 | timeout: 4.0 879 | paging: false 880 | search_url: https://gpodder.net/search.json?q={query} 881 | url_query: url 882 | title_query: title 883 | content_query: description 884 | page_size: 19 885 | categories: music 886 | disabled: true 887 | about: 888 | website: https://gpodder.net 889 | wikidata_id: Q3093354 890 | official_api_documentation: https://gpoddernet.readthedocs.io/en/latest/api/ 891 | use_official_api: false 892 | requires_api_key: false 893 | results: JSON 894 | 895 | - name: habrahabr 896 | engine: xpath 897 | paging: true 898 | search_url: https://habr.com/en/search/page{pageno}/?q={query} 899 | results_xpath: //article[contains(@class, "tm-articles-list__item")] 900 | url_xpath: .//a[@class="tm-title__link"]/@href 901 | title_xpath: .//a[@class="tm-title__link"] 902 | content_xpath: .//div[contains(@class, "article-formatted-body")] 903 | categories: it 904 | timeout: 4.0 905 | disabled: true 906 | shortcut: habr 907 | about: 908 | website: https://habr.com/ 909 | wikidata_id: Q4494434 910 | official_api_documentation: https://habr.com/en/docs/help/api/ 911 | use_official_api: false 912 | require_api_key: false 913 | results: HTML 914 | 915 | - name: hackernews 916 | engine: hackernews 917 | shortcut: hn 918 | disabled: true 919 | 920 | - name: hoogle 921 | engine: xpath 922 | search_url: https://hoogle.haskell.org/?hoogle={query} 923 | results_xpath: '//div[@class="result"]' 924 | title_xpath: './/div[@class="ans"]//a' 925 | url_xpath: './/div[@class="ans"]//a/@href' 926 | content_xpath: './/div[@class="from"]' 927 | page_size: 20 928 | categories: [it, packages] 929 | shortcut: ho 930 | about: 931 | website: https://hoogle.haskell.org/ 932 | wikidata_id: Q34010 933 | official_api_documentation: https://hackage.haskell.org/api 934 | use_official_api: false 935 | require_api_key: false 936 | results: JSON 937 | 938 | - name: imdb 939 | engine: imdb 940 | shortcut: imdb 941 | timeout: 6.0 942 | disabled: true 943 | 944 | - name: imgur 945 | engine: imgur 946 | shortcut: img 947 | disabled: true 948 | 949 | - name: ina 950 | engine: ina 951 | shortcut: in 952 | timeout: 6.0 953 | disabled: true 954 | 955 | - name: invidious 956 | engine: invidious 957 | # Instanes will be selected randomly, see https://api.invidious.io/ for 958 | # instances that are stable (good uptime) and close to you. 959 | base_url: 960 | - https://invidious.io.lol 961 | - https://invidious.fdn.fr 962 | - https://yt.artemislena.eu 963 | - https://invidious.tiekoetter.com 964 | - https://invidious.flokinet.to 965 | - https://vid.puffyan.us 966 | - https://invidious.privacydev.net 967 | - https://inv.tux.pizza 968 | shortcut: iv 969 | timeout: 3.0 970 | disabled: true 971 | 972 | - name: jisho 973 | engine: jisho 974 | shortcut: js 975 | timeout: 3.0 976 | disabled: true 977 | 978 | - name: kickass 979 | engine: kickass 980 | base_url: 981 | - https://kickasstorrents.to 982 | - https://kickasstorrents.cr 983 | - https://kickasstorrent.cr 984 | - https://kickass.sx 985 | - https://kat.am 986 | shortcut: kc 987 | timeout: 4.0 988 | 989 | - name: lemmy communities 990 | engine: lemmy 991 | lemmy_type: Communities 992 | shortcut: leco 993 | 994 | - name: lemmy users 995 | engine: lemmy 996 | network: lemmy communities 997 | lemmy_type: Users 998 | shortcut: leus 999 | 1000 | - name: lemmy posts 1001 | engine: lemmy 1002 | network: lemmy communities 1003 | lemmy_type: Posts 1004 | shortcut: lepo 1005 | 1006 | - name: lemmy comments 1007 | engine: lemmy 1008 | network: lemmy communities 1009 | lemmy_type: Comments 1010 | shortcut: lecom 1011 | 1012 | - name: library genesis 1013 | engine: xpath 1014 | # search_url: https://libgen.is/search.php?req={query} 1015 | search_url: https://libgen.rs/search.php?req={query} 1016 | url_xpath: //a[contains(@href,"book/index.php?md5")]/@href 1017 | title_xpath: //a[contains(@href,"book/")]/text()[1] 1018 | content_xpath: //td/a[1][contains(@href,"=author")]/text() 1019 | categories: files 1020 | timeout: 7.0 1021 | disabled: true 1022 | shortcut: lg 1023 | about: 1024 | website: https://libgen.fun/ 1025 | wikidata_id: Q22017206 1026 | official_api_documentation: 1027 | use_official_api: false 1028 | require_api_key: false 1029 | results: HTML 1030 | 1031 | - name: z-library 1032 | engine: zlibrary 1033 | shortcut: zlib 1034 | categories: files 1035 | timeout: 7.0 1036 | 1037 | - name: library of congress 1038 | engine: loc 1039 | shortcut: loc 1040 | categories: images 1041 | 1042 | - name: lingva 1043 | engine: lingva 1044 | shortcut: lv 1045 | # set lingva instance in url, by default it will use the official instance 1046 | # url: https://lingva.thedaviddelta.com 1047 | 1048 | - name: lobste.rs 1049 | engine: xpath 1050 | search_url: https://lobste.rs/search?q={query}&what=stories&order=relevance 1051 | results_xpath: //li[contains(@class, "story")] 1052 | url_xpath: .//a[@class="u-url"]/@href 1053 | title_xpath: .//a[@class="u-url"] 1054 | content_xpath: .//a[@class="domain"] 1055 | categories: it 1056 | shortcut: lo 1057 | timeout: 5.0 1058 | disabled: true 1059 | about: 1060 | website: https://lobste.rs/ 1061 | wikidata_id: Q60762874 1062 | official_api_documentation: 1063 | use_official_api: false 1064 | require_api_key: false 1065 | results: HTML 1066 | 1067 | - name: azlyrics 1068 | shortcut: lyrics 1069 | engine: xpath 1070 | timeout: 4.0 1071 | disabled: true 1072 | categories: [music, lyrics] 1073 | paging: true 1074 | search_url: https://search.azlyrics.com/search.php?q={query}&w=lyrics&p={pageno} 1075 | url_xpath: //td[@class="text-left visitedlyr"]/a/@href 1076 | title_xpath: //span/b/text() 1077 | content_xpath: //td[@class="text-left visitedlyr"]/a/small 1078 | about: 1079 | website: https://azlyrics.com 1080 | wikidata_id: Q66372542 1081 | official_api_documentation: 1082 | use_official_api: false 1083 | require_api_key: false 1084 | results: HTML 1085 | 1086 | - name: mastodon users 1087 | engine: mastodon 1088 | mastodon_type: accounts 1089 | base_url: https://mastodon.social 1090 | shortcut: mau 1091 | 1092 | - name: mastodon hashtags 1093 | engine: mastodon 1094 | mastodon_type: hashtags 1095 | base_url: https://mastodon.social 1096 | shortcut: mah 1097 | 1098 | # - name: matrixrooms 1099 | # engine: mrs 1100 | # # https://docs.searxng.org/dev/engines/online/mrs.html 1101 | # # base_url: https://mrs-api-host 1102 | # shortcut: mtrx 1103 | # disabled: true 1104 | 1105 | - name: mdn 1106 | shortcut: mdn 1107 | engine: json_engine 1108 | categories: [it] 1109 | paging: true 1110 | search_url: https://developer.mozilla.org/api/v1/search?q={query}&page={pageno} 1111 | results_query: documents 1112 | url_query: mdn_url 1113 | url_prefix: https://developer.mozilla.org 1114 | title_query: title 1115 | content_query: summary 1116 | about: 1117 | website: https://developer.mozilla.org 1118 | wikidata_id: Q3273508 1119 | official_api_documentation: null 1120 | use_official_api: false 1121 | require_api_key: false 1122 | results: JSON 1123 | 1124 | - name: metacpan 1125 | engine: metacpan 1126 | shortcut: cpan 1127 | disabled: true 1128 | number_of_results: 20 1129 | 1130 | # - name: meilisearch 1131 | # engine: meilisearch 1132 | # shortcut: mes 1133 | # enable_http: true 1134 | # base_url: http://localhost:7700 1135 | # index: my-index 1136 | 1137 | - name: mixcloud 1138 | engine: mixcloud 1139 | shortcut: mc 1140 | 1141 | # MongoDB engine 1142 | # Required dependency: pymongo 1143 | # - name: mymongo 1144 | # engine: mongodb 1145 | # shortcut: md 1146 | # exact_match_only: false 1147 | # host: '127.0.0.1' 1148 | # port: 27017 1149 | # enable_http: true 1150 | # results_per_page: 20 1151 | # database: 'business' 1152 | # collection: 'reviews' # name of the db collection 1153 | # key: 'name' # key in the collection to search for 1154 | 1155 | - name: mozhi 1156 | engine: mozhi 1157 | base_url: 1158 | - https://mozhi.aryak.me 1159 | - https://translate.bus-hit.me 1160 | - https://nyc1.mz.ggtyler.dev 1161 | # mozhi_engine: google - see https://mozhi.aryak.me for supported engines 1162 | timeout: 4.0 1163 | shortcut: mz 1164 | disabled: true 1165 | 1166 | - name: mwmbl 1167 | engine: mwmbl 1168 | # api_url: https://api.mwmbl.org 1169 | shortcut: mwm 1170 | disabled: true 1171 | 1172 | - name: npm 1173 | engine: npm 1174 | shortcut: npm 1175 | timeout: 5.0 1176 | disabled: true 1177 | 1178 | - name: nyaa 1179 | engine: nyaa 1180 | shortcut: nt 1181 | disabled: true 1182 | 1183 | - name: mankier 1184 | engine: json_engine 1185 | search_url: https://www.mankier.com/api/v2/mans/?q={query} 1186 | results_query: results 1187 | url_query: url 1188 | title_query: name 1189 | content_query: description 1190 | categories: it 1191 | shortcut: man 1192 | about: 1193 | website: https://www.mankier.com/ 1194 | official_api_documentation: https://www.mankier.com/api 1195 | use_official_api: true 1196 | require_api_key: false 1197 | results: JSON 1198 | 1199 | # read https://docs.searxng.org/dev/engines/online/mullvad_leta.html 1200 | # - name: mullvadleta 1201 | # engine: mullvad_leta 1202 | # use_cache: true # Only 100 non-cache searches per day, suggested only for private instances 1203 | # search_url: https://leta.mullvad.net 1204 | # categories: [general, web] 1205 | # shortcut: ml 1206 | 1207 | - name: odysee 1208 | engine: odysee 1209 | shortcut: od 1210 | disabled: true 1211 | 1212 | - name: openairedatasets 1213 | engine: json_engine 1214 | paging: true 1215 | search_url: https://api.openaire.eu/search/datasets?format=json&page={pageno}&size=10&title={query} 1216 | results_query: response/results/result 1217 | url_query: metadata/oaf:entity/oaf:result/children/instance/webresource/url/$ 1218 | title_query: metadata/oaf:entity/oaf:result/title/$ 1219 | content_query: metadata/oaf:entity/oaf:result/description/$ 1220 | content_html_to_text: true 1221 | categories: "science" 1222 | shortcut: oad 1223 | timeout: 5.0 1224 | about: 1225 | website: https://www.openaire.eu/ 1226 | wikidata_id: Q25106053 1227 | official_api_documentation: https://api.openaire.eu/ 1228 | use_official_api: false 1229 | require_api_key: false 1230 | results: JSON 1231 | 1232 | - name: openairepublications 1233 | engine: json_engine 1234 | paging: true 1235 | search_url: https://api.openaire.eu/search/publications?format=json&page={pageno}&size=10&title={query} 1236 | results_query: response/results/result 1237 | url_query: metadata/oaf:entity/oaf:result/children/instance/webresource/url/$ 1238 | title_query: metadata/oaf:entity/oaf:result/title/$ 1239 | content_query: metadata/oaf:entity/oaf:result/description/$ 1240 | content_html_to_text: true 1241 | categories: science 1242 | shortcut: oap 1243 | timeout: 5.0 1244 | about: 1245 | website: https://www.openaire.eu/ 1246 | wikidata_id: Q25106053 1247 | official_api_documentation: https://api.openaire.eu/ 1248 | use_official_api: false 1249 | require_api_key: false 1250 | results: JSON 1251 | 1252 | # - name: opensemanticsearch 1253 | # engine: opensemantic 1254 | # shortcut: oss 1255 | # base_url: 'http://localhost:8983/solr/opensemanticsearch/' 1256 | 1257 | - name: openstreetmap 1258 | engine: openstreetmap 1259 | shortcut: osm 1260 | 1261 | - name: openrepos 1262 | engine: xpath 1263 | paging: true 1264 | search_url: https://openrepos.net/search/node/{query}?page={pageno} 1265 | url_xpath: //li[@class="search-result"]//h3[@class="title"]/a/@href 1266 | title_xpath: //li[@class="search-result"]//h3[@class="title"]/a 1267 | content_xpath: //li[@class="search-result"]//div[@class="search-snippet-info"]//p[@class="search-snippet"] 1268 | categories: files 1269 | timeout: 4.0 1270 | disabled: true 1271 | shortcut: or 1272 | about: 1273 | website: https://openrepos.net/ 1274 | wikidata_id: 1275 | official_api_documentation: 1276 | use_official_api: false 1277 | require_api_key: false 1278 | results: HTML 1279 | 1280 | - name: packagist 1281 | engine: json_engine 1282 | paging: true 1283 | search_url: https://packagist.org/search.json?q={query}&page={pageno} 1284 | results_query: results 1285 | url_query: url 1286 | title_query: name 1287 | content_query: description 1288 | categories: [it, packages] 1289 | disabled: true 1290 | timeout: 5.0 1291 | shortcut: pack 1292 | about: 1293 | website: https://packagist.org 1294 | wikidata_id: Q108311377 1295 | official_api_documentation: https://packagist.org/apidoc 1296 | use_official_api: true 1297 | require_api_key: false 1298 | results: JSON 1299 | 1300 | - name: pdbe 1301 | engine: pdbe 1302 | shortcut: pdb 1303 | # Hide obsolete PDB entries. Default is not to hide obsolete structures 1304 | # hide_obsolete: false 1305 | 1306 | - name: photon 1307 | engine: photon 1308 | shortcut: ph 1309 | 1310 | - name: pinterest 1311 | engine: pinterest 1312 | shortcut: pin 1313 | 1314 | - name: piped 1315 | engine: piped 1316 | shortcut: ppd 1317 | categories: videos 1318 | piped_filter: videos 1319 | timeout: 3.0 1320 | 1321 | # URL to use as link and for embeds 1322 | frontend_url: https://srv.piped.video 1323 | # Instance will be selected randomly, for more see https://piped-instances.kavin.rocks/ 1324 | backend_url: 1325 | - https://pipedapi.kavin.rocks 1326 | - https://pipedapi-libre.kavin.rocks 1327 | - https://pipedapi.adminforge.de 1328 | 1329 | - name: piped.music 1330 | engine: piped 1331 | network: piped 1332 | shortcut: ppdm 1333 | categories: music 1334 | piped_filter: music_songs 1335 | timeout: 3.0 1336 | 1337 | - name: piratebay 1338 | engine: piratebay 1339 | shortcut: tpb 1340 | # You may need to change this URL to a proxy if piratebay is blocked in your 1341 | # country 1342 | url: https://thepiratebay.org/ 1343 | timeout: 3.0 1344 | 1345 | - name: pixiv 1346 | shortcut: pv 1347 | engine: pixiv 1348 | disabled: true 1349 | inactive: true 1350 | pixiv_image_proxies: 1351 | - pximg.example.org 1352 | # A proxy is required to load the images. Hosting an image proxy server 1353 | # for Pixiv: 1354 | # --> https://codeberg.org/VnPower/PixivFE/wiki/Hosting-an-image-proxy-server-for-Pixiv 1355 | # Proxies from public instances. Ask the public instances owners if they 1356 | # agree to receive traffic from SearXNG! 1357 | # --> https://codeberg.org/VnPower/PixivFE#instances 1358 | # --> https://github.com/searxng/searxng/pull/3192#issuecomment-1941095047 1359 | # image proxy of https://pixiv.cat 1360 | # - https://i.pixiv.cat 1361 | # image proxy of https://www.pixiv.pics 1362 | # - https://pximg.cocomi.eu.org 1363 | # image proxy of https://pixivfe.exozy.me 1364 | # - https://pximg.exozy.me 1365 | # image proxy of https://pixivfe.ducks.party 1366 | # - https://pixiv.ducks.party 1367 | # image proxy of https://pixiv.perennialte.ch 1368 | # - https://pximg.perennialte.ch 1369 | 1370 | - name: podcastindex 1371 | engine: podcastindex 1372 | shortcut: podcast 1373 | 1374 | # Required dependency: psychopg2 1375 | # - name: postgresql 1376 | # engine: postgresql 1377 | # database: postgres 1378 | # username: postgres 1379 | # password: postgres 1380 | # limit: 10 1381 | # query_str: 'SELECT * from my_table WHERE my_column = %(query)s' 1382 | # shortcut : psql 1383 | 1384 | - name: presearch 1385 | engine: presearch 1386 | search_type: search 1387 | categories: [general, web] 1388 | shortcut: ps 1389 | timeout: 4.0 1390 | disabled: true 1391 | 1392 | - name: presearch images 1393 | engine: presearch 1394 | network: presearch 1395 | search_type: images 1396 | categories: [images, web] 1397 | timeout: 4.0 1398 | shortcut: psimg 1399 | disabled: true 1400 | 1401 | - name: presearch videos 1402 | engine: presearch 1403 | network: presearch 1404 | search_type: videos 1405 | categories: [general, web] 1406 | timeout: 4.0 1407 | shortcut: psvid 1408 | disabled: true 1409 | 1410 | - name: presearch news 1411 | engine: presearch 1412 | network: presearch 1413 | search_type: news 1414 | categories: [news, web] 1415 | timeout: 4.0 1416 | shortcut: psnews 1417 | disabled: true 1418 | 1419 | - name: pub.dev 1420 | engine: xpath 1421 | shortcut: pd 1422 | search_url: https://pub.dev/packages?q={query}&page={pageno} 1423 | paging: true 1424 | results_xpath: //div[contains(@class,"packages-item")] 1425 | url_xpath: ./div/h3/a/@href 1426 | title_xpath: ./div/h3/a 1427 | content_xpath: ./div/div/div[contains(@class,"packages-description")]/span 1428 | categories: [packages, it] 1429 | timeout: 3.0 1430 | disabled: true 1431 | first_page_num: 1 1432 | about: 1433 | website: https://pub.dev/ 1434 | official_api_documentation: https://pub.dev/help/api 1435 | use_official_api: false 1436 | require_api_key: false 1437 | results: HTML 1438 | 1439 | - name: pubmed 1440 | engine: pubmed 1441 | shortcut: pub 1442 | timeout: 3.0 1443 | 1444 | - name: pypi 1445 | shortcut: pypi 1446 | engine: pypi 1447 | 1448 | - name: qwant 1449 | qwant_categ: web 1450 | engine: qwant 1451 | shortcut: qw 1452 | categories: [general, web] 1453 | additional_tests: 1454 | rosebud: *test_rosebud 1455 | 1456 | - name: qwant news 1457 | qwant_categ: news 1458 | engine: qwant 1459 | shortcut: qwn 1460 | categories: news 1461 | network: qwant 1462 | 1463 | - name: qwant images 1464 | qwant_categ: images 1465 | engine: qwant 1466 | shortcut: qwi 1467 | categories: [images, web] 1468 | network: qwant 1469 | 1470 | - name: qwant videos 1471 | qwant_categ: videos 1472 | engine: qwant 1473 | shortcut: qwv 1474 | categories: [videos, web] 1475 | network: qwant 1476 | 1477 | # - name: library 1478 | # engine: recoll 1479 | # shortcut: lib 1480 | # base_url: 'https://recoll.example.org/' 1481 | # search_dir: '' 1482 | # mount_prefix: /export 1483 | # dl_prefix: 'https://download.example.org' 1484 | # timeout: 30.0 1485 | # categories: files 1486 | # disabled: true 1487 | 1488 | # - name: recoll library reference 1489 | # engine: recoll 1490 | # base_url: 'https://recoll.example.org/' 1491 | # search_dir: reference 1492 | # mount_prefix: /export 1493 | # dl_prefix: 'https://download.example.org' 1494 | # shortcut: libr 1495 | # timeout: 30.0 1496 | # categories: files 1497 | # disabled: true 1498 | 1499 | - name: radio browser 1500 | engine: radio_browser 1501 | shortcut: rb 1502 | 1503 | - name: reddit 1504 | engine: reddit 1505 | shortcut: re 1506 | page_size: 25 1507 | 1508 | - name: rottentomatoes 1509 | engine: rottentomatoes 1510 | shortcut: rt 1511 | disabled: true 1512 | 1513 | # Required dependency: redis 1514 | # - name: myredis 1515 | # shortcut : rds 1516 | # engine: redis_server 1517 | # exact_match_only: false 1518 | # host: '127.0.0.1' 1519 | # port: 6379 1520 | # enable_http: true 1521 | # password: '' 1522 | # db: 0 1523 | 1524 | # tmp suspended: bad certificate 1525 | # - name: scanr structures 1526 | # shortcut: scs 1527 | # engine: scanr_structures 1528 | # disabled: true 1529 | 1530 | - name: sepiasearch 1531 | engine: sepiasearch 1532 | shortcut: sep 1533 | 1534 | - name: soundcloud 1535 | engine: soundcloud 1536 | shortcut: sc 1537 | 1538 | - name: stackoverflow 1539 | engine: stackexchange 1540 | shortcut: st 1541 | api_site: 'stackoverflow' 1542 | categories: [it, q&a] 1543 | 1544 | - name: askubuntu 1545 | engine: stackexchange 1546 | shortcut: ubuntu 1547 | api_site: 'askubuntu' 1548 | categories: [it, q&a] 1549 | 1550 | - name: internetarchivescholar 1551 | engine: internet_archive_scholar 1552 | shortcut: ias 1553 | timeout: 15.0 1554 | 1555 | - name: superuser 1556 | engine: stackexchange 1557 | shortcut: su 1558 | api_site: 'superuser' 1559 | categories: [it, q&a] 1560 | 1561 | - name: searchcode code 1562 | engine: searchcode_code 1563 | shortcut: scc 1564 | disabled: true 1565 | 1566 | # - name: searx 1567 | # engine: searx_engine 1568 | # shortcut: se 1569 | # instance_urls : 1570 | # - http://127.0.0.1:8888/ 1571 | # - ... 1572 | # disabled: true 1573 | 1574 | - name: semantic scholar 1575 | engine: semantic_scholar 1576 | disabled: true 1577 | shortcut: se 1578 | 1579 | # Spotify needs API credentials 1580 | # - name: spotify 1581 | # engine: spotify 1582 | # shortcut: stf 1583 | # api_client_id: ******* 1584 | # api_client_secret: ******* 1585 | 1586 | # - name: solr 1587 | # engine: solr 1588 | # shortcut: slr 1589 | # base_url: http://localhost:8983 1590 | # collection: collection_name 1591 | # sort: '' # sorting: asc or desc 1592 | # field_list: '' # comma separated list of field names to display on the UI 1593 | # default_fields: '' # default field to query 1594 | # query_fields: '' # query fields 1595 | # enable_http: true 1596 | 1597 | # - name: springer nature 1598 | # engine: springer 1599 | # # get your API key from: https://dev.springernature.com/signup 1600 | # # working API key, for test & debug: "a69685087d07eca9f13db62f65b8f601" 1601 | # api_key: 'unset' 1602 | # shortcut: springer 1603 | # timeout: 15.0 1604 | 1605 | - name: startpage 1606 | engine: startpage 1607 | shortcut: sp 1608 | timeout: 6.0 1609 | disabled: true 1610 | additional_tests: 1611 | rosebud: *test_rosebud 1612 | 1613 | - name: tokyotoshokan 1614 | engine: tokyotoshokan 1615 | shortcut: tt 1616 | timeout: 6.0 1617 | disabled: true 1618 | 1619 | - name: solidtorrents 1620 | engine: solidtorrents 1621 | shortcut: solid 1622 | timeout: 4.0 1623 | base_url: 1624 | - https://solidtorrents.to 1625 | - https://bitsearch.to 1626 | 1627 | # For this demo of the sqlite engine download: 1628 | # https://liste.mediathekview.de/filmliste-v2.db.bz2 1629 | # and unpack into searx/data/filmliste-v2.db 1630 | # Query to test: "!demo concert" 1631 | # 1632 | # - name: demo 1633 | # engine: sqlite 1634 | # shortcut: demo 1635 | # categories: general 1636 | # result_template: default.html 1637 | # database: searx/data/filmliste-v2.db 1638 | # query_str: >- 1639 | # SELECT title || ' (' || time(duration, 'unixepoch') || ')' AS title, 1640 | # COALESCE( NULLIF(url_video_hd,''), NULLIF(url_video_sd,''), url_video) AS url, 1641 | # description AS content 1642 | # FROM film 1643 | # WHERE title LIKE :wildcard OR description LIKE :wildcard 1644 | # ORDER BY duration DESC 1645 | 1646 | - name: tagesschau 1647 | engine: tagesschau 1648 | # when set to false, display URLs from Tagesschau, and not the actual source 1649 | # (e.g. NDR, WDR, SWR, HR, ...) 1650 | use_source_url: true 1651 | shortcut: ts 1652 | disabled: true 1653 | 1654 | - name: tmdb 1655 | engine: xpath 1656 | paging: true 1657 | categories: movies 1658 | search_url: https://www.themoviedb.org/search?page={pageno}&query={query} 1659 | results_xpath: //div[contains(@class,"movie") or contains(@class,"tv")]//div[contains(@class,"card")] 1660 | url_xpath: .//div[contains(@class,"poster")]/a/@href 1661 | thumbnail_xpath: .//img/@src 1662 | title_xpath: .//div[contains(@class,"title")]//h2 1663 | content_xpath: .//div[contains(@class,"overview")] 1664 | shortcut: tm 1665 | disabled: true 1666 | 1667 | # Requires Tor 1668 | - name: torch 1669 | engine: xpath 1670 | paging: true 1671 | search_url: 1672 | http://xmh57jrknzkhv6y3ls3ubitzfqnkrwxhopf5aygthi7d6rplyvk3noyd.onion/cgi-bin/omega/omega?P={query}&DEFAULTOP=and 1673 | results_xpath: //table//tr 1674 | url_xpath: ./td[2]/a 1675 | title_xpath: ./td[2]/b 1676 | content_xpath: ./td[2]/small 1677 | categories: onions 1678 | enable_http: true 1679 | shortcut: tch 1680 | 1681 | # torznab engine lets you query any torznab compatible indexer. Using this 1682 | # engine in combination with Jackett opens the possibility to query a lot of 1683 | # public and private indexers directly from SearXNG. More details at: 1684 | # https://docs.searxng.org/dev/engines/online/torznab.html 1685 | # 1686 | # - name: Torznab EZTV 1687 | # engine: torznab 1688 | # shortcut: eztv 1689 | # base_url: http://localhost:9117/api/v2.0/indexers/eztv/results/torznab 1690 | # enable_http: true # if using localhost 1691 | # api_key: xxxxxxxxxxxxxxx 1692 | # show_magnet_links: true 1693 | # show_torrent_files: false 1694 | # # https://github.com/Jackett/Jackett/wiki/Jackett-Categories 1695 | # torznab_categories: # optional 1696 | # - 2000 1697 | # - 5000 1698 | 1699 | # tmp suspended - too slow, too many errors 1700 | # - name: urbandictionary 1701 | # engine : xpath 1702 | # search_url : https://www.urbandictionary.com/define.php?term={query} 1703 | # url_xpath : //*[@class="word"]/@href 1704 | # title_xpath : //*[@class="def-header"] 1705 | # content_xpath: //*[@class="meaning"] 1706 | # shortcut: ud 1707 | 1708 | - name: unsplash 1709 | engine: unsplash 1710 | shortcut: us 1711 | 1712 | - name: yandex music 1713 | engine: yandex_music 1714 | shortcut: ydm 1715 | disabled: true 1716 | # https://yandex.com/support/music/access.html 1717 | inactive: true 1718 | 1719 | - name: yahoo 1720 | engine: yahoo 1721 | shortcut: yh 1722 | disabled: true 1723 | 1724 | - name: yahoo news 1725 | engine: yahoo_news 1726 | shortcut: yhn 1727 | 1728 | - name: youtube 1729 | shortcut: yt 1730 | # You can use the engine using the official stable API, but you need an API 1731 | # key See: https://console.developers.google.com/project 1732 | # 1733 | # engine: youtube_api 1734 | # api_key: 'apikey' # required! 1735 | # 1736 | # Or you can use the html non-stable engine, activated by default 1737 | engine: youtube_noapi 1738 | 1739 | - name: dailymotion 1740 | engine: dailymotion 1741 | shortcut: dm 1742 | 1743 | - name: vimeo 1744 | engine: vimeo 1745 | shortcut: vm 1746 | 1747 | - name: wiby 1748 | engine: json_engine 1749 | paging: true 1750 | search_url: https://wiby.me/json/?q={query}&p={pageno} 1751 | url_query: URL 1752 | title_query: Title 1753 | content_query: Snippet 1754 | categories: [general, web] 1755 | shortcut: wib 1756 | disabled: true 1757 | about: 1758 | website: https://wiby.me/ 1759 | 1760 | - name: alexandria 1761 | engine: json_engine 1762 | shortcut: alx 1763 | categories: general 1764 | paging: true 1765 | search_url: https://api.alexandria.org/?a=1&q={query}&p={pageno} 1766 | results_query: results 1767 | title_query: title 1768 | url_query: url 1769 | content_query: snippet 1770 | timeout: 1.5 1771 | disabled: true 1772 | about: 1773 | website: https://alexandria.org/ 1774 | official_api_documentation: https://github.com/alexandria-org/alexandria-api/raw/master/README.md 1775 | use_official_api: true 1776 | require_api_key: false 1777 | results: JSON 1778 | 1779 | - name: wikibooks 1780 | engine: mediawiki 1781 | weight: 0.5 1782 | shortcut: wb 1783 | categories: [general, wikimedia] 1784 | base_url: "https://{language}.wikibooks.org/" 1785 | search_type: text 1786 | disabled: true 1787 | about: 1788 | website: https://www.wikibooks.org/ 1789 | wikidata_id: Q367 1790 | 1791 | - name: wikinews 1792 | engine: mediawiki 1793 | shortcut: wn 1794 | categories: [news, wikimedia] 1795 | base_url: "https://{language}.wikinews.org/" 1796 | search_type: text 1797 | srsort: create_timestamp_desc 1798 | about: 1799 | website: https://www.wikinews.org/ 1800 | wikidata_id: Q964 1801 | 1802 | - name: wikiquote 1803 | engine: mediawiki 1804 | weight: 0.5 1805 | shortcut: wq 1806 | categories: [general, wikimedia] 1807 | base_url: "https://{language}.wikiquote.org/" 1808 | search_type: text 1809 | disabled: true 1810 | additional_tests: 1811 | rosebud: *test_rosebud 1812 | about: 1813 | website: https://www.wikiquote.org/ 1814 | wikidata_id: Q369 1815 | 1816 | - name: wikisource 1817 | engine: mediawiki 1818 | weight: 0.5 1819 | shortcut: ws 1820 | categories: [general, wikimedia] 1821 | base_url: "https://{language}.wikisource.org/" 1822 | search_type: text 1823 | disabled: true 1824 | about: 1825 | website: https://www.wikisource.org/ 1826 | wikidata_id: Q263 1827 | 1828 | - name: wikispecies 1829 | engine: mediawiki 1830 | shortcut: wsp 1831 | categories: [general, science, wikimedia] 1832 | base_url: "https://species.wikimedia.org/" 1833 | search_type: text 1834 | disabled: true 1835 | about: 1836 | website: https://species.wikimedia.org/ 1837 | wikidata_id: Q13679 1838 | tests: 1839 | wikispecies: 1840 | matrix: 1841 | query: "Campbell, L.I. et al. 2011: MicroRNAs" 1842 | lang: en 1843 | result_container: 1844 | - not_empty 1845 | - ['one_title_contains', 'Tardigrada'] 1846 | test: 1847 | - unique_results 1848 | 1849 | - name: wiktionary 1850 | engine: mediawiki 1851 | shortcut: wt 1852 | categories: [dictionaries, wikimedia] 1853 | base_url: "https://{language}.wiktionary.org/" 1854 | search_type: text 1855 | about: 1856 | website: https://www.wiktionary.org/ 1857 | wikidata_id: Q151 1858 | 1859 | - name: wikiversity 1860 | engine: mediawiki 1861 | weight: 0.5 1862 | shortcut: wv 1863 | categories: [general, wikimedia] 1864 | base_url: "https://{language}.wikiversity.org/" 1865 | search_type: text 1866 | disabled: true 1867 | about: 1868 | website: https://www.wikiversity.org/ 1869 | wikidata_id: Q370 1870 | 1871 | - name: wikivoyage 1872 | engine: mediawiki 1873 | weight: 0.5 1874 | shortcut: wy 1875 | categories: [general, wikimedia] 1876 | base_url: "https://{language}.wikivoyage.org/" 1877 | search_type: text 1878 | disabled: true 1879 | about: 1880 | website: https://www.wikivoyage.org/ 1881 | wikidata_id: Q373 1882 | 1883 | - name: wikicommons.images 1884 | engine: wikicommons 1885 | shortcut: wc 1886 | categories: images 1887 | number_of_results: 10 1888 | 1889 | - name: wolframalpha 1890 | shortcut: wa 1891 | # You can use the engine using the official stable API, but you need an API 1892 | # key. See: https://products.wolframalpha.com/api/ 1893 | # 1894 | # engine: wolframalpha_api 1895 | # api_key: '' 1896 | # 1897 | # Or you can use the html non-stable engine, activated by default 1898 | engine: wolframalpha_noapi 1899 | timeout: 6.0 1900 | categories: general 1901 | disabled: true 1902 | 1903 | - name: dictzone 1904 | engine: dictzone 1905 | shortcut: dc 1906 | 1907 | - name: mymemory translated 1908 | engine: translated 1909 | shortcut: tl 1910 | timeout: 5.0 1911 | # You can use without an API key, but you are limited to 1000 words/day 1912 | # See: https://mymemory.translated.net/doc/usagelimits.php 1913 | # api_key: '' 1914 | 1915 | # Required dependency: mysql-connector-python 1916 | # - name: mysql 1917 | # engine: mysql_server 1918 | # database: mydatabase 1919 | # username: user 1920 | # password: pass 1921 | # limit: 10 1922 | # query_str: 'SELECT * from mytable WHERE fieldname=%(query)s' 1923 | # shortcut: mysql 1924 | 1925 | - name: 1337x 1926 | engine: 1337x 1927 | shortcut: 1337x 1928 | disabled: true 1929 | 1930 | - name: duden 1931 | engine: duden 1932 | shortcut: du 1933 | disabled: true 1934 | 1935 | - name: seznam 1936 | shortcut: szn 1937 | engine: seznam 1938 | disabled: true 1939 | 1940 | # - name: deepl 1941 | # engine: deepl 1942 | # shortcut: dpl 1943 | # # You can use the engine using the official stable API, but you need an API key 1944 | # # See: https://www.deepl.com/pro-api?cta=header-pro-api 1945 | # api_key: '' # required! 1946 | # timeout: 5.0 1947 | # disabled: true 1948 | 1949 | - name: mojeek 1950 | shortcut: mjk 1951 | engine: xpath 1952 | paging: true 1953 | categories: [general, web] 1954 | search_url: https://www.mojeek.com/search?q={query}&s={pageno}&lang={lang}&lb={lang} 1955 | results_xpath: //ul[@class="results-standard"]/li/a[@class="ob"] 1956 | url_xpath: ./@href 1957 | title_xpath: ../h2/a 1958 | content_xpath: ..//p[@class="s"] 1959 | suggestion_xpath: //div[@class="top-info"]/p[@class="top-info spell"]/em/a 1960 | first_page_num: 0 1961 | page_size: 10 1962 | max_page: 100 1963 | disabled: true 1964 | about: 1965 | website: https://www.mojeek.com/ 1966 | wikidata_id: Q60747299 1967 | official_api_documentation: https://www.mojeek.com/services/api.html/ 1968 | use_official_api: false 1969 | require_api_key: false 1970 | results: HTML 1971 | 1972 | - name: moviepilot 1973 | engine: moviepilot 1974 | shortcut: mp 1975 | disabled: true 1976 | 1977 | - name: naver 1978 | shortcut: nvr 1979 | categories: [general, web] 1980 | engine: xpath 1981 | paging: true 1982 | search_url: https://search.naver.com/search.naver?where=webkr&sm=osp_hty&ie=UTF-8&query={query}&start={pageno} 1983 | url_xpath: //a[@class="link_tit"]/@href 1984 | title_xpath: //a[@class="link_tit"] 1985 | content_xpath: //div[@class="total_dsc_wrap"]/a 1986 | first_page_num: 1 1987 | page_size: 10 1988 | disabled: true 1989 | about: 1990 | website: https://www.naver.com/ 1991 | wikidata_id: Q485639 1992 | official_api_documentation: https://developers.naver.com/docs/nmt/examples/ 1993 | use_official_api: false 1994 | require_api_key: false 1995 | results: HTML 1996 | language: ko 1997 | 1998 | - name: rubygems 1999 | shortcut: rbg 2000 | engine: xpath 2001 | paging: true 2002 | search_url: https://rubygems.org/search?page={pageno}&query={query} 2003 | results_xpath: /html/body/main/div/a[@class="gems__gem"] 2004 | url_xpath: ./@href 2005 | title_xpath: ./span/h2 2006 | content_xpath: ./span/p 2007 | suggestion_xpath: /html/body/main/div/div[@class="search__suggestions"]/p/a 2008 | first_page_num: 1 2009 | categories: [it, packages] 2010 | disabled: true 2011 | about: 2012 | website: https://rubygems.org/ 2013 | wikidata_id: Q1853420 2014 | official_api_documentation: https://guides.rubygems.org/rubygems-org-api/ 2015 | use_official_api: false 2016 | require_api_key: false 2017 | results: HTML 2018 | 2019 | - name: peertube 2020 | engine: peertube 2021 | shortcut: ptb 2022 | paging: true 2023 | # alternatives see: https://instances.joinpeertube.org/instances 2024 | # base_url: https://tube.4aem.com 2025 | categories: videos 2026 | disabled: true 2027 | timeout: 6.0 2028 | 2029 | - name: mediathekviewweb 2030 | engine: mediathekviewweb 2031 | shortcut: mvw 2032 | disabled: true 2033 | 2034 | - name: yacy 2035 | engine: yacy 2036 | categories: general 2037 | search_type: text 2038 | base_url: https://yacy.searchlab.eu 2039 | shortcut: ya 2040 | disabled: true 2041 | # required if you aren't using HTTPS for your local yacy instance 2042 | # https://docs.searxng.org/dev/engines/online/yacy.html 2043 | # enable_http: true 2044 | # timeout: 3.0 2045 | # search_mode: 'global' 2046 | 2047 | - name: yacy images 2048 | engine: yacy 2049 | categories: images 2050 | search_type: image 2051 | base_url: https://yacy.searchlab.eu 2052 | shortcut: yai 2053 | disabled: true 2054 | 2055 | - name: rumble 2056 | engine: rumble 2057 | shortcut: ru 2058 | base_url: https://rumble.com/ 2059 | paging: true 2060 | categories: videos 2061 | disabled: true 2062 | 2063 | - name: livespace 2064 | engine: livespace 2065 | shortcut: ls 2066 | categories: videos 2067 | disabled: true 2068 | timeout: 5.0 2069 | 2070 | - name: wordnik 2071 | engine: wordnik 2072 | shortcut: def 2073 | base_url: https://www.wordnik.com/ 2074 | categories: [dictionaries] 2075 | timeout: 5.0 2076 | 2077 | - name: woxikon.de synonyme 2078 | engine: xpath 2079 | shortcut: woxi 2080 | categories: [dictionaries] 2081 | timeout: 5.0 2082 | disabled: true 2083 | search_url: https://synonyme.woxikon.de/synonyme/{query}.php 2084 | url_xpath: //div[@class="upper-synonyms"]/a/@href 2085 | content_xpath: //div[@class="synonyms-list-group"] 2086 | title_xpath: //div[@class="upper-synonyms"]/a 2087 | no_result_for_http_status: [404] 2088 | about: 2089 | website: https://www.woxikon.de/ 2090 | wikidata_id: # No Wikidata ID 2091 | use_official_api: false 2092 | require_api_key: false 2093 | results: HTML 2094 | language: de 2095 | 2096 | - name: seekr news 2097 | engine: seekr 2098 | shortcut: senews 2099 | categories: news 2100 | seekr_category: news 2101 | disabled: true 2102 | 2103 | - name: seekr images 2104 | engine: seekr 2105 | network: seekr news 2106 | shortcut: seimg 2107 | categories: images 2108 | seekr_category: images 2109 | disabled: true 2110 | 2111 | - name: seekr videos 2112 | engine: seekr 2113 | network: seekr news 2114 | shortcut: sevid 2115 | categories: videos 2116 | seekr_category: videos 2117 | disabled: true 2118 | 2119 | - name: sjp.pwn 2120 | engine: sjp 2121 | shortcut: sjp 2122 | base_url: https://sjp.pwn.pl/ 2123 | timeout: 5.0 2124 | disabled: true 2125 | 2126 | - name: stract 2127 | engine: stract 2128 | shortcut: str 2129 | disabled: true 2130 | 2131 | - name: svgrepo 2132 | engine: svgrepo 2133 | shortcut: svg 2134 | timeout: 10.0 2135 | disabled: true 2136 | 2137 | - name: tootfinder 2138 | engine: tootfinder 2139 | shortcut: toot 2140 | 2141 | - name: voidlinux 2142 | engine: voidlinux 2143 | shortcut: void 2144 | disabled: true 2145 | 2146 | - name: wallhaven 2147 | engine: wallhaven 2148 | # api_key: abcdefghijklmnopqrstuvwxyz 2149 | shortcut: wh 2150 | 2151 | # wikimini: online encyclopedia for children 2152 | # The fulltext and title parameter is necessary for Wikimini because 2153 | # sometimes it will not show the results and redirect instead 2154 | - name: wikimini 2155 | engine: xpath 2156 | shortcut: wkmn 2157 | search_url: https://fr.wikimini.org/w/index.php?search={query}&title=Sp%C3%A9cial%3ASearch&fulltext=Search 2158 | url_xpath: //li/div[@class="mw-search-result-heading"]/a/@href 2159 | title_xpath: //li//div[@class="mw-search-result-heading"]/a 2160 | content_xpath: //li/div[@class="searchresult"] 2161 | categories: general 2162 | disabled: true 2163 | about: 2164 | website: https://wikimini.org/ 2165 | wikidata_id: Q3568032 2166 | use_official_api: false 2167 | require_api_key: false 2168 | results: HTML 2169 | language: fr 2170 | 2171 | - name: wttr.in 2172 | engine: wttr 2173 | shortcut: wttr 2174 | timeout: 9.0 2175 | 2176 | - name: yummly 2177 | engine: yummly 2178 | shortcut: yum 2179 | disabled: true 2180 | 2181 | - name: brave 2182 | engine: brave 2183 | shortcut: br 2184 | time_range_support: true 2185 | paging: true 2186 | categories: [general, web] 2187 | brave_category: search 2188 | # brave_spellcheck: true 2189 | 2190 | - name: brave.images 2191 | engine: brave 2192 | network: brave 2193 | shortcut: brimg 2194 | categories: [images, web] 2195 | brave_category: images 2196 | 2197 | - name: brave.videos 2198 | engine: brave 2199 | network: brave 2200 | shortcut: brvid 2201 | categories: [videos, web] 2202 | brave_category: videos 2203 | 2204 | - name: brave.news 2205 | engine: brave 2206 | network: brave 2207 | shortcut: brnews 2208 | categories: news 2209 | brave_category: news 2210 | 2211 | # - name: brave.goggles 2212 | # engine: brave 2213 | # network: brave 2214 | # shortcut: brgog 2215 | # time_range_support: true 2216 | # paging: true 2217 | # categories: [general, web] 2218 | # brave_category: goggles 2219 | # Goggles: # required! This should be a URL ending in .goggle 2220 | 2221 | - name: lib.rs 2222 | shortcut: lrs 2223 | engine: lib_rs 2224 | disabled: true 2225 | 2226 | - name: sourcehut 2227 | shortcut: srht 2228 | engine: xpath 2229 | paging: true 2230 | search_url: https://sr.ht/projects?page={pageno}&search={query} 2231 | results_xpath: (//div[@class="event-list"])[1]/div[@class="event"] 2232 | url_xpath: ./h4/a[2]/@href 2233 | title_xpath: ./h4/a[2] 2234 | content_xpath: ./p 2235 | first_page_num: 1 2236 | categories: [it, repos] 2237 | disabled: true 2238 | about: 2239 | website: https://sr.ht 2240 | wikidata_id: Q78514485 2241 | official_api_documentation: https://man.sr.ht/ 2242 | use_official_api: false 2243 | require_api_key: false 2244 | results: HTML 2245 | 2246 | - name: goo 2247 | shortcut: goo 2248 | engine: xpath 2249 | paging: true 2250 | search_url: https://search.goo.ne.jp/web.jsp?MT={query}&FR={pageno}0 2251 | url_xpath: //div[@class="result"]/p[@class='title fsL1']/a/@href 2252 | title_xpath: //div[@class="result"]/p[@class='title fsL1']/a 2253 | content_xpath: //p[contains(@class,'url fsM')]/following-sibling::p 2254 | first_page_num: 0 2255 | categories: [general, web] 2256 | disabled: true 2257 | timeout: 4.0 2258 | about: 2259 | website: https://search.goo.ne.jp 2260 | wikidata_id: Q249044 2261 | use_official_api: false 2262 | require_api_key: false 2263 | results: HTML 2264 | language: ja 2265 | 2266 | - name: bt4g 2267 | engine: bt4g 2268 | shortcut: bt4g 2269 | 2270 | - name: pkg.go.dev 2271 | engine: pkg_go_dev 2272 | shortcut: pgo 2273 | disabled: true 2274 | 2275 | # Doku engine lets you access to any Doku wiki instance: 2276 | # A public one or a privete/corporate one. 2277 | # - name: ubuntuwiki 2278 | # engine: doku 2279 | # shortcut: uw 2280 | # base_url: 'https://doc.ubuntu-fr.org' 2281 | 2282 | # Be careful when enabling this engine if you are 2283 | # running a public instance. Do not expose any sensitive 2284 | # information. You can restrict access by configuring a list 2285 | # of access tokens under tokens. 2286 | # - name: git grep 2287 | # engine: command 2288 | # command: ['git', 'grep', '{{QUERY}}'] 2289 | # shortcut: gg 2290 | # tokens: [] 2291 | # disabled: true 2292 | # delimiter: 2293 | # chars: ':' 2294 | # keys: ['filepath', 'code'] 2295 | 2296 | # Be careful when enabling this engine if you are 2297 | # running a public instance. Do not expose any sensitive 2298 | # information. You can restrict access by configuring a list 2299 | # of access tokens under tokens. 2300 | # - name: locate 2301 | # engine: command 2302 | # command: ['locate', '{{QUERY}}'] 2303 | # shortcut: loc 2304 | # tokens: [] 2305 | # disabled: true 2306 | # delimiter: 2307 | # chars: ' ' 2308 | # keys: ['line'] 2309 | 2310 | # Be careful when enabling this engine if you are 2311 | # running a public instance. Do not expose any sensitive 2312 | # information. You can restrict access by configuring a list 2313 | # of access tokens under tokens. 2314 | # - name: find 2315 | # engine: command 2316 | # command: ['find', '.', '-name', '{{QUERY}}'] 2317 | # query_type: path 2318 | # shortcut: fnd 2319 | # tokens: [] 2320 | # disabled: true 2321 | # delimiter: 2322 | # chars: ' ' 2323 | # keys: ['line'] 2324 | 2325 | # Be careful when enabling this engine if you are 2326 | # running a public instance. Do not expose any sensitive 2327 | # information. You can restrict access by configuring a list 2328 | # of access tokens under tokens. 2329 | # - name: pattern search in files 2330 | # engine: command 2331 | # command: ['fgrep', '{{QUERY}}'] 2332 | # shortcut: fgr 2333 | # tokens: [] 2334 | # disabled: true 2335 | # delimiter: 2336 | # chars: ' ' 2337 | # keys: ['line'] 2338 | 2339 | # Be careful when enabling this engine if you are 2340 | # running a public instance. Do not expose any sensitive 2341 | # information. You can restrict access by configuring a list 2342 | # of access tokens under tokens. 2343 | # - name: regex search in files 2344 | # engine: command 2345 | # command: ['grep', '{{QUERY}}'] 2346 | # shortcut: gr 2347 | # tokens: [] 2348 | # disabled: true 2349 | # delimiter: 2350 | # chars: ' ' 2351 | # keys: ['line'] 2352 | 2353 | doi_resolvers: 2354 | oadoi.org: 'https://oadoi.org/' 2355 | doi.org: 'https://doi.org/' 2356 | doai.io: 'https://dissem.in/' 2357 | sci-hub.se: 'https://sci-hub.se/' 2358 | sci-hub.st: 'https://sci-hub.st/' 2359 | sci-hub.ru: 'https://sci-hub.ru/' 2360 | 2361 | default_doi_resolver: 'oadoi.org' 2362 | -------------------------------------------------------------------------------- /searxng/uwsgi.ini: -------------------------------------------------------------------------------- 1 | [uwsgi] 2 | # Who will run the code 3 | uid = searxng 4 | gid = searxng 5 | 6 | # Number of workers (usually CPU count) 7 | # default value: %k (= number of CPU core, see Dockerfile) 8 | workers = %k 9 | 10 | # Number of threads per worker 11 | # default value: 4 (see Dockerfile) 12 | threads = 4 13 | 14 | # The right granted on the created socket 15 | chmod-socket = 666 16 | 17 | # Plugin to use and interpreter config 18 | single-interpreter = true 19 | master = true 20 | plugin = python3 21 | lazy-apps = true 22 | enable-threads = 4 23 | 24 | # Module to import 25 | module = searx.webapp 26 | 27 | # Virtualenv and python path 28 | pythonpath = /usr/local/searxng/ 29 | chdir = /usr/local/searxng/searx/ 30 | 31 | # automatically set processes name to something meaningful 32 | auto-procname = true 33 | 34 | # Disable request logging for privacy 35 | disable-logging = true 36 | log-5xx = true 37 | 38 | # Set the max size of a request (request-body excluded) 39 | buffer-size = 8192 40 | 41 | # No keep alive 42 | # See https://github.com/searx/searx-docker/issues/24 43 | add-header = Connection: close 44 | 45 | # uwsgi serves the static files 46 | static-map = /static=/usr/local/searxng/searx/static 47 | # expires set to one day 48 | static-expires = /* 86400 49 | static-gzip-all = True 50 | offload-threads = 4 51 | -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import time 4 | import uvicorn 5 | import sys 6 | import getopt 7 | import json 8 | import os 9 | from pprint import pprint 10 | import requests 11 | import trafilatura 12 | from trafilatura import bare_extraction 13 | from concurrent.futures import ThreadPoolExecutor 14 | import concurrent 15 | import requests 16 | import openai 17 | import time 18 | from datetime import datetime 19 | from urllib.parse import urlparse 20 | import platform 21 | import urllib.parse 22 | import free_ask_internet 23 | from pydantic import BaseModel, Field 24 | from fastapi import FastAPI, HTTPException 25 | from fastapi.middleware.cors import CORSMiddleware 26 | from contextlib import asynccontextmanager 27 | from typing import Any, Dict, List, Literal, Optional, Union 28 | from sse_starlette.sse import ServerSentEvent, EventSourceResponse 29 | from fastapi.responses import StreamingResponse 30 | 31 | app = FastAPI() 32 | 33 | app.add_middleware( 34 | CORSMiddleware, 35 | allow_origins=["*"], 36 | allow_credentials=True, 37 | allow_methods=["*"], 38 | allow_headers=["*"], 39 | ) 40 | 41 | 42 | class ModelCard(BaseModel): 43 | id: str 44 | object: str = "model" 45 | created: int = Field(default_factory=lambda: int(time.time())) 46 | owned_by: str = "owner" 47 | root: Optional[str] = None 48 | parent: Optional[str] = None 49 | permission: Optional[list] = None 50 | 51 | 52 | class ModelList(BaseModel): 53 | object: str = "list" 54 | data: List[ModelCard] = [] 55 | 56 | 57 | class ChatMessage(BaseModel): 58 | role: Literal["user", "assistant", "system"] 59 | content: str 60 | 61 | 62 | class DeltaMessage(BaseModel): 63 | role: Optional[Literal["user", "assistant", "system"]] = None 64 | content: Optional[str] = None 65 | 66 | 67 | class QueryRequest(BaseModel): 68 | query:str 69 | model: str 70 | ask_type: Literal["search", "llm"] 71 | llm_auth_token: Optional[str] = "CUSTOM" 72 | llm_base_url: Optional[str] = "" 73 | using_custom_llm:Optional[bool] = False 74 | lang:Optional[str] = "zh-CN" 75 | 76 | class ChatCompletionRequest(BaseModel): 77 | model: str 78 | messages: List[ChatMessage] 79 | temperature: Optional[float] = None 80 | top_p: Optional[float] = None 81 | max_length: Optional[int] = None 82 | stream: Optional[bool] = False 83 | 84 | 85 | class ChatCompletionResponseChoice(BaseModel): 86 | index: int 87 | message: ChatMessage 88 | finish_reason: Literal["stop", "length"] 89 | 90 | 91 | class ChatCompletionResponseStreamChoice(BaseModel): 92 | index: int 93 | delta: DeltaMessage 94 | finish_reason: Optional[Literal["stop", "length"]] 95 | 96 | 97 | class ChatCompletionResponse(BaseModel): 98 | model: str 99 | object: Literal["chat.completion", "chat.completion.chunk"] 100 | choices: List[Union[ChatCompletionResponseChoice, 101 | ChatCompletionResponseStreamChoice]] 102 | created: Optional[int] = Field(default_factory=lambda: int(time.time())) 103 | 104 | class SearchItem(BaseModel): 105 | url: str 106 | icon_url: str 107 | site_name:str 108 | snippet:str 109 | title:str 110 | 111 | class SearchItemList(BaseModel): 112 | search_items: List[SearchItem] = [] 113 | 114 | class SearchResp(BaseModel): 115 | code:int 116 | msg:str 117 | data: List[SearchItem] = [] 118 | 119 | 120 | @app.get("/v1/models", response_model=ModelList) 121 | async def list_models(): 122 | global model_args 123 | model_card = ModelCard(id="gpt-3.5-turbo") 124 | return ModelList(data=[model_card]) 125 | 126 | 127 | @app.post("/v1/chat/completions", response_model=ChatCompletionResponse) 128 | async def create_chat_completion(request: ChatCompletionRequest): 129 | global model, tokenizer 130 | print(request) 131 | if request.messages[-1].role != "user": 132 | raise HTTPException(status_code=400, detail="Invalid request") 133 | query = request.messages[-1].content 134 | 135 | 136 | generate = predict(query, "", request.model) 137 | return EventSourceResponse(generate, media_type="text/event-stream") 138 | 139 | 140 | 141 | def predict(query: str, history: None, model_id: str): 142 | choice_data = ChatCompletionResponseStreamChoice( 143 | index=0, 144 | delta=DeltaMessage(role="assistant"), 145 | finish_reason=None 146 | ) 147 | chunk = ChatCompletionResponse(model=model_id, choices=[ 148 | choice_data], object="chat.completion.chunk") 149 | yield "{}".format(chunk.json(exclude_unset=True)) 150 | new_response = "" 151 | current_length = 0 152 | for token in free_ask_internet.ask_internet(query=query): 153 | 154 | new_response += token 155 | if len(new_response) == current_length: 156 | continue 157 | 158 | new_text = new_response[current_length:] 159 | current_length = len(new_response) 160 | 161 | choice_data = ChatCompletionResponseStreamChoice( 162 | index=0, 163 | delta=DeltaMessage(content=new_text,role="assistant"), 164 | finish_reason=None 165 | ) 166 | chunk = ChatCompletionResponse(model=model_id, choices=[ 167 | choice_data], object="chat.completion.chunk") 168 | yield "{}".format(chunk.json(exclude_unset=True)) 169 | 170 | choice_data = ChatCompletionResponseStreamChoice( 171 | index=0, 172 | delta=DeltaMessage(), 173 | finish_reason="stop" 174 | ) 175 | chunk = ChatCompletionResponse(model=model_id, choices=[ 176 | choice_data], object="chat.completion.chunk") 177 | yield "{}".format(chunk.json(exclude_unset=True)) 178 | yield '[DONE]' 179 | 180 | 181 | 182 | @app.post("/api/search/get_search_refs", response_model=SearchResp) 183 | async def get_search_refs(request: QueryRequest): 184 | 185 | global search_results 186 | search_results = [] 187 | search_item_list = [] 188 | if request.ask_type == "search": 189 | search_links,search_results = free_ask_internet.search_web_ref(request.query) 190 | for search_item in search_links: 191 | snippet = search_item.get("snippet") 192 | url = search_item.get("url") 193 | icon_url = search_item.get("icon_url") 194 | site_name = search_item.get("site_name") 195 | title = search_item.get("title") 196 | 197 | 198 | si = SearchItem(snippet=snippet,url=url,icon_url=icon_url,site_name=site_name,title=title) 199 | 200 | search_item_list.append(si) 201 | 202 | resp = SearchResp(code=0,msg="success",data=search_item_list) 203 | 204 | return resp 205 | 206 | def generator(prompt:str, model:str, llm_auth_token:str,llm_base_url:str, using_custom_llm=False,is_failed=False): 207 | if is_failed: 208 | yield "搜索失败,没有返回结果" 209 | else: 210 | total_token = "" 211 | for token in free_ask_internet.chat(prompt=prompt,model=model,llm_auth_token=llm_auth_token,llm_base_url=llm_base_url,using_custom_llm=using_custom_llm,stream=True): 212 | total_token += token 213 | yield token 214 | 215 | @app.post("/api/search/stream/{search_uuid}") 216 | async def stream(search_uuid:str,request: QueryRequest): 217 | global search_results 218 | 219 | if request.ask_type == "llm": 220 | 221 | answer_language = ' Simplified Chinese ' 222 | if request.lang == "zh-CN": 223 | answer_language = ' Simplified Chinese ' 224 | if request.lang == "zh-TW": 225 | answer_language = ' Traditional Chinese ' 226 | if request.lang == "en-US": 227 | answer_language = ' English ' 228 | prompt = ' You are a large language AI assistant develop by nash_su. Answer user question in ' + answer_language + '. And here is the user question: ' + request.query 229 | generate = generator(prompt,model=request.model,llm_auth_token=request.llm_auth_token, llm_base_url=request.llm_base_url, using_custom_llm=request.using_custom_llm) 230 | else: 231 | prompt = None 232 | limit_count = 10 233 | 234 | while limit_count > 0: 235 | try: 236 | if len(search_results) > 0: 237 | prompt = free_ask_internet.gen_prompt(request.query,search_results,lang=request.lang,context_length_limit=8000) 238 | break 239 | else: 240 | limit_count -= 1 241 | time.sleep(1) 242 | except Exception as err: 243 | limit_count -= 1 244 | time.sleep(1) 245 | total_token = "" 246 | if prompt: 247 | generate = generator(prompt,model=request.model,llm_auth_token=request.llm_auth_token, llm_base_url=request.llm_base_url, using_custom_llm=request.using_custom_llm) 248 | else: 249 | generate = generator(prompt,model=request.model,llm_auth_token=request.llm_auth_token,llm_base_url=request.llm_base_url, using_custom_llm=request.using_custom_llm,is_failed=True) 250 | 251 | # return EventSourceResponse(generate, media_type="text/event-stream") 252 | return StreamingResponse(generate, media_type="text/event-stream") 253 | 254 | def main(): 255 | 256 | port = 8000 257 | 258 | search_results = [] 259 | 260 | 261 | uvicorn.run(app, host='0.0.0.0', port=port, workers=1) 262 | 263 | 264 | if __name__ == "__main__": 265 | main() 266 | --------------------------------------------------------------------------------