Skip to content

Commit e453028

Browse files
authored
Merge pull request #26 from code-yeongyu/feature/cookie-parsing
2 parents ef1db33 + 32d3e33 commit e453028

15 files changed

+394
-27
lines changed

.github/workflows/test.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Test
2+
on:
3+
pull_request:
4+
5+
jobs:
6+
test:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v3
10+
with:
11+
fetch-depth: 0
12+
- name: Set up Python 3.9
13+
uses: actions/setup-python@v4
14+
with:
15+
python-version: 3.9
16+
17+
- uses: snok/[email protected]
18+
with:
19+
virtualenvs-create: true
20+
virtualenvs-in-project: true
21+
22+
- name: Cache Dependencies
23+
uses: actions/cache@v2
24+
id: cache-dependencies
25+
with:
26+
path: .venv
27+
key: venv-${{ runner.os }}-${{ hashFiles('./poetry.lock') }}
28+
29+
- name: Install Dependencies if cache doesn't hit
30+
if: steps.cache-dependencies.cache-hit != 'true'
31+
run: poetry install
32+
33+
- name: Run test
34+
run: poetry run invoke test

.vscode/launch.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "AiShell Debug",
9+
"type": "python",
10+
"request": "launch",
11+
"module": "aishell",
12+
"justMyCode": true,
13+
"args": [
14+
"print helloworld"
15+
]
16+
}
17+
]
18+
}

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,15 @@ aishell --help
3838

3939
### For those who want to use reverse-engineered `ChatGPT`
4040

41-
1. Login on <https://chat.openai.com/>
42-
1. Get your 'accessToken` from <https://chat.openai.com/api/auth/session>
43-
1. Set the API key as an environment variable `CHATGPT_ACCESS_KEY`
44-
1. Enjoy AiShell
41+
- Permanent Login Method
42+
1. Login on <https://chat.openai.com/>
43+
1. Get your 'accessToken` from <https://chat.openai.com/api/auth/session>
44+
1. Set the API key as an environment variable `CHATGPT_ACCESS_TOKEN`
45+
- Temporary Login Method
46+
1. Just run `aishell <query>`
47+
1. Browser opens up. Login there.
48+
1. Tell AiShell which browser you use.
49+
1. Enjoy AiShell
4550

4651
### For those who want to use `Official ChatGPT(GPT3.5-turbo)` or `GPT-3`
4752

aishell/adapters/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .openai_chatgpt_adapter import OpenAIChatGPTAdapter as OpenAIChatGPTAdapter
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from http.cookiejar import Cookie
2+
from typing import Optional
3+
4+
from yt_dlp.cookies import SUPPORTED_BROWSERS, extract_cookies_from_browser
5+
from yt_dlp.utils import YoutubeDLCookieJar
6+
7+
8+
class OpenAIChatGPTAdapter:
9+
10+
def __init__(self, browser_name: str):
11+
if browser_name not in SUPPORTED_BROWSERS: # type: ignore
12+
raise ValueError(f'Browser {browser_name} is not supported. Supported browsers are: {SUPPORTED_BROWSERS}')
13+
self.BROWSER_NAME = browser_name
14+
15+
def get_openai_cookies(self) -> dict[str, Optional[str]]:
16+
all_cookies: YoutubeDLCookieJar = extract_cookies_from_browser(self.BROWSER_NAME)
17+
try:
18+
openai_cookies: dict[str, Cookie] = all_cookies.__dict__['_cookies']['chat.openai.com']['/']
19+
except KeyError as error:
20+
raise ValueError('Could not find OpenAI cookies. Make sure you are logged in to OpenAI.') from error
21+
22+
cookies: dict[str, Optional[str]] = {key: cookie.value for key, cookie in openai_cookies.items()}
23+
24+
return cookies
25+
26+
def get_openai_session_token(self) -> Optional[str]:
27+
return self.get_openai_cookies()['__Secure-next-auth.session-token']

aishell/adapters/test/__init__.py

Whitespace-only changes.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import pytest
2+
from yt_dlp.cookies import SUPPORTED_BROWSERS
3+
4+
from aishell.adapters import OpenAIChatGPTAdapter
5+
6+
7+
class TestChatGPTAccessTokenAdapterInit:
8+
9+
def test_fail_when_invalid_browser_name_is_given(self) -> None:
10+
'''잘못된 브라우저 이름을 입력했을 때 ValueError가 발생한다.'''
11+
with pytest.raises(ValueError):
12+
OpenAIChatGPTAdapter('invalid_browser_name')
13+
14+
@pytest.mark.parametrize('browser_name', SUPPORTED_BROWSERS)
15+
def test_success_when_valid_browser_name_is_given(self, browser_name: str) -> None:
16+
'''올바른 브라우저 이름을 입력했을 때 ValueError가 발생하지 않는다'''
17+
OpenAIChatGPTAdapter(browser_name)

aishell/cli.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,40 @@
11
import os
2+
import webbrowser
23

34
import typer
45
from rich.console import Console
6+
from yt_dlp.cookies import SUPPORTED_BROWSERS
57

8+
from aishell.adapters.openai_chatgpt_adapter import OpenAIChatGPTAdapter
9+
from aishell.exceptions import UnauthorizedAccessError
610
from aishell.models.language_model import LanguageModel
711
from aishell.query_clients import GPT3Client, OfficialChatGPTClient, QueryClient, ReverseEngineeredChatGPTClient
812

913
cli_app = typer.Typer()
1014

1115

16+
def _open_chatgpt_browser():
17+
CHATGPT_LOGIN_URL = 'https://chat.openai.com/auth/login?next=/chat'
18+
webbrowser.open(CHATGPT_LOGIN_URL)
19+
20+
1221
@cli_app.command()
13-
def ask(question: str, language_model: LanguageModel = LanguageModel.OFFICIAL_CHATGPT):
22+
def ask(question: str, language_model: LanguageModel = LanguageModel.REVERSE_ENGINEERED_CHATGPT):
1423
query_client: QueryClient
1524
if language_model == LanguageModel.GPT3:
1625
query_client = GPT3Client()
1726
elif language_model == LanguageModel.OFFICIAL_CHATGPT:
1827
query_client = OfficialChatGPTClient()
1928
elif language_model == LanguageModel.REVERSE_ENGINEERED_CHATGPT:
20-
query_client = ReverseEngineeredChatGPTClient()
29+
try:
30+
query_client = ReverseEngineeredChatGPTClient()
31+
except UnauthorizedAccessError:
32+
print('You are not logged in to OpenAI, attempting to log you in...')
33+
_open_chatgpt_browser()
34+
BROWSER_NAME = typer.prompt(f'Which browser did you use to log in? [{SUPPORTED_BROWSERS}]')
35+
adapter = OpenAIChatGPTAdapter(BROWSER_NAME)
36+
session_token = adapter.get_openai_session_token()
37+
query_client = ReverseEngineeredChatGPTClient(session_token=session_token)
2138

2239
query_client.query(question)
2340

aishell/exceptions/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .unauthorized_access_error import UnauthorizedAccessError as UnauthorizedAccessError
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class UnauthorizedAccessError(Exception):
2+
pass

0 commit comments

Comments
 (0)