├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README-ZH.md ├── README.md └── docker-compose ├── chatgpt-next-web └── docker-compose.yml ├── chatgpt-web └── docker-compose.yml ├── lobe-chat └── docker-compose.yml └── open-webui └── docker-compose.yml /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | 162 | browser_data/ -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # v2.3.11 2 | 3 | ## Feature 4 | - 支持TTS 5 | - 更新到指纹浏览器Chrome 132,使用固定指纹 6 | 7 | ## Bugfix 8 | - 修复Cloudflare在IP质量较差时无法通过的问题 9 | - 解决Python升级打包出错 10 | 11 | ## Enhancement 12 | - 优化Cloudflare解决流程 13 | 14 | 15 | # v2.2.0 16 | 17 | ## Feature 18 | - 支持对话 19 | 20 | # v2.1.0 21 | 22 | ## Feature 23 | - 支持Google账号登录 24 | 25 | # v2.0.0 26 | 27 | ## Feature 28 | - 支持登录模式: 不登录,邮箱登录 29 | - 支持全部文字模型,以及模型切换 30 | - 支持高速流式输出 31 | - 支持通过Cloudflare验证 32 | - 支持浏览器指纹 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README-ZH.md: -------------------------------------------------------------------------------- 1 | # LLM Web API 2 | 3 | [![](https://img.shields.io/github/license/adryfish/llm-web-api.svg)](LICENSE) 4 | ![](https://img.shields.io/github/stars/adryfish/llm-web-api.svg) 5 | ![](https://img.shields.io/github/forks/adryfish/llm-web-api.svg) 6 | 7 | 使用`Playwright`将网页版ChatGPT转换成`API`接口 8 | 9 | ## 功能列表 10 | - 通过`Cloudflare`验证破解 11 | - 登录模式支持免登录、邮箱登录和Google登录 12 | - 高速流式输出 13 | - 模型切换,动态显示支持模型 14 | - 对话支持 15 | - TTS支持(文本转语音支持) 16 | 17 | 与ChatGPT接口完全兼容。 18 | 19 | ## 使用方法 20 | 21 | ### 使用Docker运行 22 | 23 | ```shell 24 | docker run --name llm-web-api --rm -it -p 5000:5000 adryfish/llm-web-api 25 | ``` 26 | 27 | ### 使用Docker compose 28 | 29 | 详细配置见下方环境变量 30 | 31 | ```yml 32 | services: 33 | llm-web-api: 34 | image: adryfish/llm-web-api 35 | container_name: llm-web-api 36 | ports: 37 | - "5000:5000" 38 | volumes: 39 | # 浏览器数据,如何要保留浏览器登录信息,需要配置 40 | - ./data:/app/data 41 | environment: 42 | # PROXY_SERVER: "" # 代理服务器地址 43 | # OPENAI_LOGIN_TYPE: "" # 登录类型,nologin or email或者google 44 | # OPENAI_LOGIN_EMAIL: "" # 登录邮箱 45 | # OPENAI_LOGIN_PASSWORD: "" # 登录密码 46 | restart: unless-stopped 47 | ``` 48 | 49 | ### 环境变量 50 | 51 | 所有的环境变量均为可选。 52 | 53 | | 变量名 | 描述 | 默认值 | 54 | |-----------------------|----------------------------------------|--------| 55 | | PROXY_SERVER | 代理服务器地址 | None | 56 | | DATA_DIR | 数据存放目录 | 当前目录/data | 57 | | OPENAI_LOGIN_TYPE | ChatGPT 的登录类型, nologin, email, google | nologin| 58 | | OPENAI_LOGIN_EMAIL | 对于 email 登录方式,提供 email 帐号 | None | 59 | | OPENAI_LOGIN_PASSWORD | 对于 email 登录方式,提供密码 | None | 60 | | OPENAI_LOGIN_APP_PASSWORD | app password(非必须) | None | 61 | | GOOGLE_LOGIN_EMAIL | google登录邮箱 | None | 62 | | GOOGLE_LOGIN_PASSWORD | google登录邮箱密码 | None | 63 | | GOOGLE_LOGIN_OTP_SECRET | google登录二次认证secret | None | 64 | | GOOGLE_LOGIN_RECOVERY_EMAIL | google登录恢复邮箱 | None | 65 | 66 | 67 | ## 原理 68 | 使用`Playwright`控制指纹浏览器,模拟用户操作,发送请求到OpenAI网页, 将响应转换成API接口。 69 | 70 | ## 接口列表 71 | 72 | 目前支持与openai兼容的 `/v1/chat/completions` 接口,可自行使用与openai或其他兼容的客户端接入接口 73 | 74 | ### 对话补全 75 | 76 | 对话补全接口,与openai的 [chat-completions-api](https://platform.openai.com/docs/api-reference/chat) 兼容。 77 | 78 | **POST /v1/chat/completions** 79 | 80 | 请求数据: 81 | ```jsonc 82 | { 83 | "model": "gpt-4o", 84 | "messages": [ 85 | { 86 | "role": "user", 87 | "content": "Hello" 88 | } 89 | ], 90 | // 可选: 如果使用SSE流请设置为true,默认false 91 | "stream": false 92 | // 可选: 如果启用,响应中将包含元数据 (message_id 和 conversation_id) 93 | // 如果同时提供 parent_message_id 和 conversation_id,则请求将在现有对话上下文中继续。 94 | // 如果未设置,则请求将被视为新的对话。 95 | // "meta": { 96 | // "enable": true, 97 | // "parent_message_id": "5363437e-b364-4b72-b3d6-415deeed11ab", # 可选 98 | // "conversation_id": "6774f183-f70c-800b-9965-6c110d3a3485" # 可选 99 | // } 100 | } 101 | ``` 102 | 103 | 响应数据: 104 | ```jsonc 105 | { 106 | "id": "chatcmpl-fZc6l869OzRu8rp7X8Dhj0COfTsR6", 107 | "object": "chat.completion", 108 | "created": 1733726226, 109 | "model": "gpt-4o", 110 | "choices": [ 111 | { 112 | "index": 0, 113 | "message": { 114 | "role": "assistant", 115 | "content": "Hi there! How can I assist you today? 😊" 116 | }, 117 | "logprobs": null, 118 | "finish_reason": "stop" 119 | } 120 | ], 121 | "usage": { 122 | "prompt_tokens": 1, 123 | "completion_tokens": 11, 124 | "total_tokens": 12 125 | }, 126 | // 如何没有设置ENABLE_REQUEST_METADATA=True,则不会有meta数据返回 127 | "meta": { 128 | "message_id": "dffd63ef-63ac-4d40-b6de-e33ec40de9e2", 129 | "conversation_id": "6774f183-f70c-800b-9965-6c110d3a3485" 130 | } 131 | } 132 | ``` 133 | 134 | ### 语音合成API 135 | 136 | 语音合成API,与OpenAI的 [Audio Speech API](https://platform.openai.com/docs/api-reference/audio) 兼容。允许用户将文本转换为语音。 137 | 138 | **POST /v1/audio/speech** 139 | 140 | 请求数据: 141 | ```jsonc 142 | { 143 | "input": "你好,你今天怎么样?", 144 | "voice": "cove", 145 | "model": "tts-1", 146 | // 可选:指定返回格式,默认为 "aac" 147 | "response_format": "mp3" 148 | } 149 | ``` 150 | 151 | 响应数据: 152 | 153 | 如果请求成功,API 将返回所请求格式的音频文件。 154 | 155 | 156 | ## 用例 157 | ### 使用Python OpenAI官方库 158 | #### Python 159 | ```python 160 | import openai 161 | 162 | openai.api_key = 'anything' 163 | openai.base_url = "http://localhost:5000/v1/" 164 | 165 | completion = openai.chat.completions.create( 166 | model="gpt-4o", 167 | messages=[ 168 | {"role": "user", "content": "Hello"}, 169 | ], 170 | ) 171 | 172 | print(completion.choices[0].message.content) 173 | ``` 174 | 175 | #### Node.js 176 | 177 | ```javascript 178 | import OpenAI from 'openai'; 179 | 180 | const openai = new OpenAI({ 181 | apiKey: "anything", 182 | baseURL: "http://localhost:5000/v1/", 183 | }); 184 | 185 | const chatCompletion = await openai.chat.completions.create({ 186 | messages: [{ role: 'user', content: 'Echo Hello' }], 187 | model: 'gpt-4o', 188 | }); 189 | 190 | console.log(chatCompletion.choices[0].message.content); 191 | ``` 192 | 193 | 194 | ## 同类项目 195 | - chat2api: https://github.com/lanqian528/chat2api 196 | 197 | ## Star History 198 | 199 | [![Star History Chart](https://api.star-history.com/svg?repos=adryfish/llm-web-api&type=Date)](https://star-history.com/#adryfish/llm-web-api&Date) 200 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LLM Web API 2 | 3 | [![](https://img.shields.io/github/license/adryfish/llm-web-api.svg)](LICENSE) 4 | ![](https://img.shields.io/github/stars/adryfish/llm-web-api.svg) 5 | ![](https://img.shields.io/github/forks/adryfish/llm-web-api.svg) 6 | 7 | [中文文档](README-ZH.md) 8 | 9 | ChatGPT Web Page to API interface. 10 | 11 | ## Features 12 | - Bypass `Cloudflare` challenge 13 | - Login mode: no-login, email, google login 14 | - High-speed streaming output 15 | - Model switching, Dynamically display supported models 16 | - Conversation support 17 | - TTS support 18 | 19 | Compatible with the `ChatGPT` API. 20 | 21 | 22 | ## Usage 23 | 24 | ### Run with Docker 25 | 26 | ```shell 27 | docker run --name llm-web-api --rm -it -p 5000:5000 adryfish/llm-web-api 28 | ``` 29 | 30 | ### Docker compose 31 | 32 | See detailed configuration below for environment variables. 33 | 34 | ```yml 35 | services: 36 | llm-web-api: 37 | image: adryfish/llm-web-api 38 | container_name: llm-web-api 39 | ports: 40 | - "5000:5000" 41 | volumes: 42 | # Browser data. Configure if you want to retain browser login information. 43 | - ./data:/app/data 44 | environment: 45 | # PROXY_SERVER: "" # Proxy server address 46 | # OPENAI_LOGIN_TYPE: "" # Login Type,nologin or email or google 47 | # OPENAI_LOGIN_EMAIL: "" # Login email 48 | # OPENAI_LOGIN_PASSWORD: "" # Login password 49 | restart: unless-stopped 50 | ``` 51 | 52 | ### Environment 53 | 54 | All environment variables are optional. 55 | 56 | | Variable | Description | Default | 57 | |-----------------------|------------------------------------------|--------| 58 | | PROXY_SERVER | Proxy server address | None | 59 | | DATA_DIR | Data storage directory | ./data | 60 | | OPENAI_LOGIN_TYPE | ChatGPT login type: `nologin`, `email`, `google` | nologin | 61 | | OPENAI_LOGIN_EMAIL | Email account for email login | None | 62 | | OPENAI_LOGIN_PASSWORD | Password for email login | None | 63 | | OPENAI_LOGIN_APP_PASSWORD | App password for email verification | None | 64 | | GOOGLE_LOGIN_EMAIL | Google login email | None | 65 | | GOOGLE_LOGIN_PASSWORD | Google login password | None | 66 | | GOOGLE_LOGIN_OTP_SECRET | Google login 2FA secret | None | 67 | | GOOGLE_LOGIN_RECOVERY_EMAIL | Google login recovery email | None | 68 | 69 | 70 | ## How it works 71 | 72 | The system uses `Playwright` to control a fingerprint browser, simulating user operations to send requests to the OpenAI website and converting the responses into API interfaces. 73 | 74 | ## API 75 | 76 | Currently supports the OpenAI-compatible /v1/chat/completions API, which can be accessed using OpenAI or other compatible clients. 77 | 78 | ### Chat completion 79 | 80 | Chat completion API,compatible with OpenAI [Chat Completions API](https://platform.openai.com/docs/api-reference/chat)。 81 | 82 | **POST /v1/chat/completions** 83 | 84 | **Request:** 85 | ```jsonc 86 | { 87 | "model": "gpt-4o", 88 | "messages": [ 89 | { 90 | "role": "user", 91 | "content": "Hello" 92 | } 93 | ], 94 | // Optional: If using SSE stream, set to true, default is false 95 | "stream": false 96 | // Optional: If enabled, the response will include meta information(message_id and conversation id) 97 | // If both parent_message_id and conversation_id are provided, the request will continue within the existing conversation context. 98 | // If they are not set, the request will be treated as a new conversation. 99 | // "meta": { 100 | // "enable": true, 101 | // "parent_message_id": "5363437e-b364-4b72-b3d6-415deeed11ab", # Optional 102 | // "conversation_id": "6774f183-f70c-800b-9965-6c110d3a3485" # Optional 103 | // } 104 | } 105 | ``` 106 | 107 | **Response:** 108 | ```jsonc 109 | { 110 | "id": "chatcmpl-fZc6l869OzRu8rp7X8Dhj0COfTsR6", 111 | "object": "chat.completion", 112 | "created": 1733726226, 113 | "model": "gpt-4o", 114 | "choices": [ 115 | { 116 | "index": 0, 117 | "message": { 118 | "role": "assistant", 119 | "content": "Hi there! How can I assist you today? 😊" 120 | }, 121 | "logprobs": null, 122 | "finish_reason": "stop" 123 | } 124 | ], 125 | "usage": { 126 | "prompt_tokens": 1, 127 | "completion_tokens": 11, 128 | "total_tokens": 12 129 | }, 130 | "meta": { 131 | "message_id": "dffd63ef-63ac-4d40-b6de-e33ec40de9e2", 132 | "conversation_id": "6774f183-f70c-800b-9965-6c110d3a3485" 133 | } 134 | } 135 | ``` 136 | 137 | ### Audio Create Speech 138 | 139 | Audio Speech API, compatible with OpenAI's [Audio Speech API](https://platform.openai.com/docs/api-reference/audio). It allows users to generate speech from text input. 140 | 141 | **POST /v1/audio/speech** 142 | 143 | **Request:** 144 | ```jsonc 145 | { 146 | "input": "Hello, how are you?", 147 | "voice": "cove" 148 | "model": "tts-1", 149 | // Optional: specify response format, default is "aac" 150 | "response_format": "mp3", 151 | } 152 | ``` 153 | 154 | **Response:** 155 | 156 | If successful, the API returns an audio file in the requested format. 157 | 158 | 159 | ## Examples 160 | ### Using OpenAI Official Library 161 | #### Python 162 | ```python 163 | import openai 164 | 165 | openai.api_key = 'anything' 166 | openai.base_url = "http://localhost:5000/v1/" 167 | 168 | completion = openai.chat.completions.create( 169 | model="gpt-4o-mini", 170 | messages=[ 171 | {"role": "user", "content": "Hello"}, 172 | ], 173 | ) 174 | 175 | print(completion.choices[0].message.content) 176 | ``` 177 | 178 | #### Node.js 179 | 180 | ```javascript 181 | import OpenAI from 'openai'; 182 | 183 | const openai = new OpenAI({ 184 | apiKey: "anything", 185 | baseURL: "http://localhost:5000/v1/", 186 | }); 187 | 188 | const chatCompletion = await openai.chat.completions.create({ 189 | messages: [{ role: 'user', content: 'Echo Hello' }], 190 | model: 'gpt-4o-mini', 191 | }); 192 | 193 | console.log(chatCompletion.choices[0].message.content); 194 | ``` 195 | 196 | ## Similar Projects 197 | - chat2api: https://github.com/lanqian528/chat2api 198 | 199 | ## Star History 200 | 201 | [![Star History Chart](https://api.star-history.com/svg?repos=adryfish/llm-web-api&type=Date)](https://star-history.com/#adryfish/llm-web-api&Date) -------------------------------------------------------------------------------- /docker-compose/chatgpt-next-web/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | chatgpt-next-web: 3 | image: yidadaa/chatgpt-next-web 4 | ports: 5 | - "3000:3000" 6 | environment: 7 | OPENAI_API_KEY: "anything" 8 | BASE_URL: "http://chatgpt:5000" 9 | CUSTOM_MODELS: "-all,+gpt-3.5-turbo" # 非登录用户,免费用户 10 | # CUSTOM_MODELS: "-all,+gpt-3.5-turbo,gpt-4,gpt4o" # Plus用户 11 | depends_on: 12 | - chatgpt 13 | restart: unless-stopped 14 | 15 | chatgpt: 16 | image: adryfish/llm-web-api 17 | container_name: llm-web-api 18 | ports: 19 | - "5000:5000" 20 | # volumes: 21 | # # 浏览器数据,如何要保留浏览器登录信息,需要配置 22 | # - ./browser_data:/app/browser_data 23 | # environment: 24 | # PROXY_SERVER: "" # 代理服务器地址 25 | # USER_AGENT: "" # 浏览器User-Agent 26 | # OPENAI_LOGIN_TYPE: "" # 登录类型,nologin or email 27 | # OPENAI_LOGIN_EMAIL: "" # 登录邮箱 28 | # OPENAI_LOGIN_PASSWORD: "" # 登录密码 29 | restart: unless-stopped -------------------------------------------------------------------------------- /docker-compose/chatgpt-web/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | chatgpt-web: 3 | image: chenzhaoyu94/chatgpt-web # always use latest, pull the tag image again to update 4 | container_name: chatgpt-web 5 | ports: 6 | - 3002:3002 7 | environment: 8 | OPENAI_API_KEY: "sk-xxx" 9 | # API interface address, optional, available when OPENAI_API_KEY is set 10 | OPENAI_API_BASE_URL: "http://chatgpt:5000/v1" 11 | # API model, optional, available when OPENAI_API_KEY is set, https://platform.openai.com/docs/models 12 | # gpt-4, gpt-4o, gpt-4-turbo, gpt-4-turbo-preview, gpt-4-0125-preview, gpt-4-1106-preview, gpt-4-0314, gpt-4-0613, gpt-4-32k, gpt-4-32k-0314, gpt-4-32k-0613, gpt-3.5-turbo-16k, gpt-3.5-turbo-16k-0613, gpt-3.5-turbo, gpt-3.5-turbo-0301, gpt-3.5-turbo-0613, text-davinci-003, text-davinci-002, code-davinci-002 13 | OPENAI_API_MODEL: "gpt-3.5-turbo" 14 | depends_on: 15 | - chatgpt 16 | restart: unless-stopped 17 | 18 | chatgpt: 19 | image: adryfish/llm-web-api 20 | container_name: llm-web-api 21 | ports: 22 | - "5000:5000" 23 | # volumes: 24 | # # 浏览器数据,如何要保留浏览器登录信息,需要配置 25 | # - ./browser_data:/app/browser_data 26 | # environment: 27 | # PROXY_SERVER: "" # 代理服务器地址 28 | # USER_AGENT: "" # 浏览器User-Agent 29 | # OPENAI_LOGIN_TYPE: "" # 登录类型,nologin or email 30 | # OPENAI_LOGIN_EMAIL: "" # 登录邮箱 31 | # OPENAI_LOGIN_PASSWORD: "" # 登录密码 32 | restart: unless-stopped -------------------------------------------------------------------------------- /docker-compose/lobe-chat/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | lobe-chat: 3 | image: lobehub/lobe-chat:latest 4 | container_name: lobe-chat 5 | ports: 6 | - "3210:3210" 7 | environment: 8 | OPENAI_API_KEY: "anything" 9 | OPENAI_PROXY_URL: "http://chatgpt:5000/v1" 10 | depends_on: 11 | - chatgpt 12 | restart: unless-stopped 13 | 14 | 15 | chatgpt: 16 | image: adryfish/llm-web-api 17 | container_name: llm-web-api 18 | ports: 19 | - "5000:5000" 20 | # volumes: 21 | # # 浏览器数据,如何要保留浏览器登录信息,需要配置 22 | # - ./browser_data:/app/browser_data 23 | # environment: 24 | # PROXY_SERVER: "" # 代理服务器地址 25 | # USER_AGENT: "" # 浏览器User-Agent 26 | # OPENAI_LOGIN_TYPE: "" # 登录类型,nologin or email 27 | # OPENAI_LOGIN_EMAIL: "" # 登录邮箱 28 | # OPENAI_LOGIN_PASSWORD: "" # 登录密码 29 | restart: unless-stopped -------------------------------------------------------------------------------- /docker-compose/open-webui/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | open-webui: 3 | image: ghcr.io/open-webui/open-webui:main 4 | container_name: open-webui 5 | ports: 6 | - "4000:8080" 7 | environment: 8 | - OPENAI_API_KEY=sk-xxxxxxxx 9 | - OPENAI_API_BASE_URL=http://chatgpt:5000/v1 10 | # - HF_ENDPOINT=https://hf-mirror.com/ # 如果无法访问HuggingFace,加上这个参数 11 | volumes: 12 | - ./data:/app/backend/data 13 | restart: unless-stopped 14 | 15 | chatgpt: 16 | image: adryfish/llm-web-api 17 | container_name: llm-web-api 18 | ports: 19 | - "5000:5000" 20 | # volumes: 21 | # # 浏览器数据,如何要保留浏览器登录信息,需要配置 22 | # - ./browser_data:/app/browser_data 23 | # environment: 24 | # PROXY_SERVER: "" # 代理服务器地址 25 | # USER_AGENT: "" # 浏览器User-Agent 26 | # OPENAI_LOGIN_TYPE: "" # 登录类型,nologin or email 27 | # OPENAI_LOGIN_EMAIL: "" # 登录邮箱 28 | # OPENAI_LOGIN_PASSWORD: "" # 登录密码 29 | restart: unless-stopped 30 | --------------------------------------------------------------------------------