Giter Club home page Giter Club logo

webai-to-api's Introduction

NOTE: This is a research project. Please do not use it commercially and use it responsibly.


WebAI to API

This project implements a web API that offers a unified interface to Google Gemini, and Claude 3.

Image

Key Features

  • Self-hosted: Python/FastAPI enables flexibility to run anywhere. Not locked into proprietary platforms.

  • Streaming support: Real-time responses from Claude streaming.

  • Lightweight and scalable: Built with FastAPI for high performance.

  • API Key: No API Key required.

Status

Claude-3 API integration is also fully implemented and available

Google Gemini API integration available now

UI Configuration: Implement routing for localhost:8000/WebAI path

⚙️ PIP: In progress


Image


This repository is up-to-date.
Please don't forget to give a Star ⭐




Prerequisites

Python version >= 3.10 Accounts on the following (all offer free signups):

Then, add your token(s) to the Config.conf file. (see Configuration section).


Note

Note: Claude and Gemini offer Auto Login options - you can either log in through your browser and skip this step.


Installation


Step 1. Clone Repository

git clone https://github.com/Amm1rr/WebAI-to-API.git && cd WebAI-to-API

python -m venv .venv

source .venv/bin/activate  # Linux/macOS
.venv\Scripts\activate     # Windows


pip install -r requirements.txt

Step 2. Start Web Server

Navigate into the webai2api directory, and run the web server:

cd WebAI-to-API/webai2api/

python run.py

Now the API documentation and Configuration Web UI should be available at the following addresses:

Tip

Open Web UI Configuration: http://localhost:8000/WebAI

Open API documentation: http://localhost:8000/docs


Available Endpoints:



Input / Output

# Input:
_____

    {
      "message": "Hi, Who are you?",
      "stream": true
    }


--------------------


# Output:
_____

    {
      I am a Chatbot assistant :)
    }


--------------------


# Response Output:
_____

# Streaming
  "String"


# Not Streaming
  "String"




Web UI Development Environment Setup (Optional)

Prerequisites:

First , Navigate to the UI directory:

cd WebAI-to-API/webai2api/UI
  1. Install dependencies:
npm install
  1. Build the project:
npm run build

Example

Once you have launched the web server using python webai2api\run.py:

Note

Note: The first argument to run the example determines whether to return streaming or not.

cd examples/


python WebAPI-to-API/webai2api/test.py

OR

python example_claude.py false
python example_claude.py true

python example_gemini.py

or try Claude with cURL

run this cURL command in a terminal window:

curl -X 'POST' \
  'http://localhost:8000/claude' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "message": "who are you?",
  "stream": false
}'

Note

Note: The session_id is configured in the Config.conf file. If you send this variable empty, it will use the Config.conf


Usage

How to find tokens

Note

Note: Claude and Gemini offer two authentication options - you can either log in through your browser and skip this step, or you can follow the instructions below to configure the authentication.

Important

"The auto login by browser issue is caused by using multiple accounts or browser profiles. It will take some time to fully resolve. A future update will address it. For now, if you have problems logging in with your browsers, try logging in with just one browser or manually copy sessions and cookies as a workaround, as described in the instructions below."


The easiest way is to just log in to the chatbot websites. (Claude | Gemini)
OR
First you need to add your tokens to the Config.conf file (see Configuration section).


Gemini

Image

Method 1:
For Gemini, all you need to do is login to your account using your web browser. (Firefox, Chrome, Safari, Edge...)

Method 2:
Google Gemini: Please obtain the cookies mentioned here from an authorized session on gemini.google.com. The cookies can be used to send POST requests to the /gemini endpoint along with a message in a JSON payload. It is important that the session_id, which is your __Secure-1PSID cookie, and the session_idts and session_idcc, which is your Secure-1PSIDTS and Secure-1PSIDCC cookie, are included in the request. (Screenshot)

Name Session Name
session_id __Secure-1PSID
session_idts __Secure-1PSIDTS
session_idcc __Secure-1PSIDCC
  1. Login to gemini.google.com
  2. Open Developer Tools (Press F12)
  3. Go to Application Tab
  4. Go to Cookies Tab
  5. Copy the content of __Secure-1PSID and __Secure-1PSIDTS and __Secure-1PSIDCC. Copy the value of those cookie.
  6. Set in Config.conf file.



Claude

Image

Method 1:
For Claude, all you need to do is login to your account using your web browser. (Firefox, Chrome, Safari, Edge...)

Method 2:
Claude: You can get cookie from the browser's developer tools network tab ( see for any claude.ai requests check out cookie ,copy whole value ) or storage tab ( You can find cookie of claude.ai ,there will be four values ) (Screenshot)

  1. Login to claude.ai
  2. Open Developer Tools (Press F12)
  3. Go to Network Tab
  4. Select an ajax request (like step 3 in picture)
  5. Copy the content of Cookie
  6. Set in Config.conf file.

Configuration


How to find tokens

Note

Note: Claude and Gemini present Auto Login options - logging in through your browser or configuring Claude and Gemini using the provided config file.


Configuring the Model Type for /v1/chat/completions

You can specify the model type in the settings for the /v1/chat/completions endpoint. The available options are "Claude" and "Gemini". By default, the system uses the "Claude" model.

# Case-Sensitive

[Main]
Model=Claude
# or
Model=Gemini

Config File Path:

  • WebAI-to-API\webai2api\Config.conf
# Case-Sensitive

[Main]
Model = [Claude] or [Gemini]

[Claude]
COOKIE=[YOURS]

[Gemini]
SESSION_ID=[YOURS]
SESSION_IDTS=[YOURS]
SESSION_IDCC=[YOURS]

Licensing

This project is licensed under the MIT License. Feel free to use it however you like.


webai-to-api's People

Contributors

amm1rr avatar jumbophp avatar linkedlist771 avatar niazlv avatar paulkass avatar sourcery-ai-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

webai-to-api's Issues

Claude does not work at all

←[31mERROR←[0m:    Exception in ASGI application
Traceback (most recent call last):
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 408, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 84, in __call__
    return await self.app(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\fastapi\applications.py", line 289, in __call__
    await super().__call__(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\middleware\errors.py", line 184, in __call__
    raise exc
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\middleware\errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\middleware\cors.py", line 83, in __call__
    await self.app(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\middleware\exceptions.py", line 79, in __call__
    raise exc
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\middleware\exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 20, in __call__
    raise e
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 17, in __call__
    await self.app(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\routing.py", line 66, in app
    response = await func(request)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\fastapi\routing.py", line 273, in app
    raw_response = await run_endpoint_function(
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\fastapi\routing.py", line 190, in run_endpoint_function
    return await dependant.call(**values)
  File "D:\AI\WebAI-to-API\src\main.py", line 552, in ask_claude
    claude = Client(cookie)
  File "D:\AI\WebAI-to-API\src\claude.py", line 14, in __init__
    self.organization_id = self.get_organization_id()
  File "D:\AI\WebAI-to-API\src\claude.py", line 34, in get_organization_id
    uuid = res[0]['uuid']
KeyError: 0

No surprise: res value is {'error': {'type': 'permission_error', 'message': 'Invalid authorization'}}
But I have doublechecked my token value in Config.conf, and it is correct.

Change Claude to ChatGPT endpoint

http://127.0.0.1:8000/claude/v1/chat/completions would be much more compatible with most existing tools, because it's very rare when a tool has possibility to customize particular endpoint.
Usually it is possible to enter custom api base, like http://127.0.0.1:8000/claude/v1

P.S
Still, some tools expect that api base will by in the root, and allow to customize only host.

Streaming is not working with examples.

None of following examples produces streaming:

python example_bard.py true
python example_chatgpt1.py true
python example_chatgpt2.py true
python example_claude.py true

P.S.
Same with direct curl requests.

You should set 'COOKIE' in 'Config.conf' file for the Claude or login with a browser to Claude.ai account.

I had set cookie value in the 'Config.conf', but it still failed.

INFO:root:claude_routes.py
INFO:root:gemini_routes.py
INFO:root:v1_routes.py
INFO:root:http_routes.py
INFO:root:http_routes.py.initialize_cookies
INFO:root:utility.py./getCookie_Claude
{'Error': "You should set 'COOKIE' in 'Config.conf' file for the Claude or login with a browser to Claude.ai account."}
INFO:root:utility.py./getCookie_Gemini
Traceback (most recent call last):
File "/home/colin/workspace/WebAI-to-API/webai2api/webai2api/utils/utility.py", line 118, in getCookie_Gemini
cookie = get_cookiestring("Google")
File "/home/colin/workspace/WebAI-to-API/webai2api/webai2api/utils/utility.py", line 66, in get_cookiestring
domain = domains[service_name]
KeyError: 'Google'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/home/colin/workspace/WebAI-to-API/webai2api/run.py", line 3, in
from webai2api.main import app
File "/home/colin/workspace/WebAI-to-API/webai2api/webai2api/main.py", line 5, in
from .routes.http_routes import web_ui_middleware
File "/home/colin/workspace/WebAI-to-API/webai2api/webai2api/routes/http_routes.py", line 32, in
initialize_cookies()
File "/home/colin/workspace/WebAI-to-API/webai2api/webai2api/routes/http_routes.py", line 27, in initialize_cookies
COOKIE_GEMINI = utility.getCookie_Gemini()
File "/home/colin/workspace/WebAI-to-API/webai2api/webai2api/utils/utility.py", line 127, in getCookie_Gemini
cookies = browser_cookie3.load(domain_name=domain)
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/browser_cookie3/init.py", line 1233, in load
for cookie in cookie_fn(domain_name=domain_name):
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/browser_cookie3/init.py", line 1160, in chrome
return Chrome(cookie_file, domain_name, key_file).load()
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/browser_cookie3/init.py", line 626, in init
super().init(browser='Chrome', cookie_file=cookie_file,
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/browser_cookie3/init.py", line 416, in init
self.__add_key_and_cookie_file(**kwargs)
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/browser_cookie3/init.py", line 431, in __add_key_and_cookie_file
USE_DBUS_LINUX).get_password(os_crypt_name)
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/browser_cookie3/init.py", line 232, in get_password
return self.__get_secretstorage_password(os_crypt_name)
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/browser_cookie3/init.py", line 247, in __get_secretstorage_password
return self.__methods_map.get('secretstorage')(schema, os_crypt_name)
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/browser_cookie3/init.py", line 303, in __get_secretstorage_item_jeepney
with _JeepneyConnection(*args) as connection:
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/browser_cookie3/init.py", line 195, in enter
self.__connection = open_dbus_connection()
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/jeepney/io/blocking.py", line 342, in open_dbus_connection
sock = prep_socket(bus_addr, enable_fds, timeout=auth_timeout)
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/jeepney/io/blocking.py", line 310, in prep_socket
with_sock_deadline(sock.connect, addr)
File "/home/colin/anaconda3/envs/claude/lib/python3.10/site-packages/jeepney/io/blocking.py", line 307, in with_sock_deadline
return meth(*args)
FileNotFoundError: [Errno 2] No such file or directory

Bard to ChatGPT

It would be nice to have such adapter, similar to "Claude to ChatGPT"

Claude to ChatGPT does not stream

Testing http://127.0.0.1:8000/v1/chat/completions/Claude

With "stream": false it works.

With "stream": true it outputs: Error : __enter__

P.S.
http://127.0.0.1:8000/v1/chat/completions is also ok

Error accessing Bard cookies

PermissionError: [Errno 13] Permission denied: 'C:\\Users\\xxx\\AppData\\Roaming\\..\\Local\\Microsoft\\Edge\\User Data\\Default\\Network\\Cookies'

And this file is actually locked by Edge.exe.
But even if I force-close all Edge instances, I get another error:

Error: Failed to retrieve the Google Bard website.
Error: Session not found.

But I am definitely logged in.

What is most important: I have all cookies set in Config.conf, so I wonder why it ever tries to read browser data..

Cannot use gpt-4

How can I use gpt-4 as the model for the API? I have a plus account but I don't see where I can specify the model

Update Claude model

At the moment claude is broken.
Changes needed:

diff --git a/src/claude.py b/src/claude.py
index 19071a6..51217f3 100644
--- a/src/claude.py
+++ b/src/claude.py
@@ -101,7 +101,7 @@ class Client:
       "completion": {
         "prompt": f"{prompt}",
         "timezone": "Europe/London",
-        "model": "claude-2"
+        "model": "claude-2.1"
       },
       "organization_uuid": f"{self.organization_id}",
       "conversation_uuid": f"{conversation_id}",
@@ -169,7 +170,7 @@ class Client:
       "completion": {
         "prompt": f"{prompt}",
         "timezone": "Europe/London",
-        "model": "claude-2"
+        "model": "claude-2.1"
       },
       "organization_uuid": f"{self.organization_id}",
       "conversation_uuid": f"{conversation_id}",

But.. better use constant, or common func.

Response text should not be quoted

At the moment endpoints \bard and \chatgpt with "stream": false, and \claude (with any value) produce quoted text.

  • the whole response is in "quotes"
  • with special symbols escaped
    • New line = \n
    • Quote = \"

Example:

" Here is a little song about \"Fire and Ice\":\n\nSome say the world will end in fire, \nSome say in ice.\nFrom what I've tasted of desire\nI hold with those who favor fire.\nBut if it had to perish twice,\nI think
 I know enough of hate\nTo say that for destruction ice\nIs also great\nAnd would suffice."

How to get Claude Cookie

image

I still don't understand how to get this session key.

The format is still not correct. When I copy all the values it appears like this:

   File "/usr/local/lib/python3.10/dist-packages/browser_cookie3/__init__.py", line 195, in __enter__
     self.__connection = open_dbus_connection()
   File "/usr/lib/python3/dist-packages/jeepney/io/blocking.py", line 332, in open_dbus_connection
     bus_addr = get_bus(bus)
   File "/usr/lib/python3/dist-packages/jeepney/bus.py", line 53, in get_bus
     return find_session_bus()
   File "/usr/lib/python3/dist-packages/jeepney/bus.py", line 42, in find_session_bus
     addr = os.environ['DBUS_SESSION_BUS_ADDRESS']
   File "/usr/lib/python3.10/os.py", line 680, in __getitem__
     raise KeyError(key) from None
KeyError: 'DBUS_SESSION_BUS_ADDRESS'

Can anyone provide an example in a Video or Image with a detailed explanation?

Mistypes in README.MD

  1. http://128.0.0.1:8000
    Perhaps should be http://127.0.0.1:8000 or http://localhost:8000
# Input:
_____

    {
      "session_id": "session-ID",
      "message": "Hi, Who are you?",
      "stream": True
    }

It is not clear whether it is python source or json.
(For json should br "stream": true)

claude: Internal Server Error

When using http://127.0.0.1:8000/claude

Output in server console:

Traceback (most recent call last):
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 408, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 84, in __call__
    return await self.app(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\fastapi\applications.py", line 289, in __call__
    await super().__call__(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\middleware\errors.py", line 184, in __call__
    raise exc
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\middleware\errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\middleware\cors.py", line 83, in __call__
    await self.app(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\middleware\exceptions.py", line 79, in __call__
    raise exc
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\middleware\exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 20, in __call__
    raise e
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\fastapi\middleware\asyncexitstack.py", line 17, in __call__
    await self.app(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\starlette\routing.py", line 66, in app
    response = await func(request)
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\fastapi\routing.py", line 273, in app
    raw_response = await run_endpoint_function(
  File "D:\AI\WebAI-to-API\venv\lib\site-packages\fastapi\routing.py", line 190, in run_endpoint_function
    return await dependant.call(**values)
  File "D:\AI\WebAI-to-API\src\main.py", line 546, in ask_claude
    claude = Client(cookie)
  File "D:\AI\WebAI-to-API\src\claude.py", line 14, in __init__
    self.organization_id = self.get_organization_id()
  File "D:\AI\WebAI-to-API\src\claude.py", line 34, in get_organization_id
    uuid = res[0]['uuid']
KeyError: 0

P.S.
I was testing with curl.
But example_claude.py is ok

chatgpt: Incorrect API key provided

http://127.0.0.1:8000/chatgpt fails, but http://127.0.0.1:8000/v1/chat/completions is ok.

P.S.
I am testing with curl.
But example_chatgpt1.py and example_chatgpt2.py work.

ChatGPT - Error 500 Undocumented

for chat gpt i am getting this error:

Unable to load site

Please try again later. If you are using a VPN, try turning it off. Check thestatus page for information on outages. and for claude i am getting this server response :
Code Details
500Undocumented Error: Internal Server ErrorResponse bodyDownloadInternal Server Error

Bug: streaming process waiting problem

in the [claude.py](https://github.com/Amm1rr/WebAI-to-API/blob/master/src/claude.py) line 239:

    answer = ""
    with httpx.stream("POST", url, headers=headers, data=payload) as r:
      for text in r.iter_text():
        response_parse_text = await parse_text(text)

        text_res = ""
        if response_parse_text:
            for text in response_parse_text:
                text_res += text

        answer = ''.join(text_res)
        print(answer)
    
        yield answer

I was testing the streaming output results and found that you need to add a async method right behind the yeild in the async function. for example:

yield answer
await asyncio.sleep(0)

Otherwise the function will be blocked until all the streaming data are received. There are two ways to solve it:

  • make the async def stream_message sync,
  • Add a async method below the yield.

I have no idea make this happen, if you figure it out what is happening, catch me later.

Bard response: {"Error":"Check the Bard session."}

In server console: Error: Session not found.

SESSION_ID and SESSION_IDTS are set in Config.conf

Note:
I have usually several logon sessions, but i tried all cookies with no success (such as __Secure-3PSID)

P.S.
I was testing with curl.
But example_bard.py works..

claude failed to parse with error response

tried with claude 2 and claude 2.1 all give the following response:

response.content.decode('utf-8')
'{"type":"error","error":{"type":"not_found_error","message":"Not Found"}}'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.