Skip to content

Commit cf10e87

Browse files
Created api wrapper for inflection pi
1 parent 81a3b35 commit cf10e87

File tree

7 files changed

+212
-0
lines changed

7 files changed

+212
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,4 @@ cython_debug/
152152
#.idea/
153153

154154
# Added files to ignore
155+
test.py

example.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from pi import Pi
2+
3+
prompt = "How are you?"
4+
5+
chatbot = Pi("TOKEN HERE", proxy=False)
6+
7+
response = chatbot.send_message(prompt)
8+
9+
print(response)

setup.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from setuptools import setup, find_packages
2+
from pathlib import Path
3+
4+
base_path = Path(__file__).parent
5+
long_description = (base_path / "README.md").read_text(encoding='utf-8')
6+
7+
VERSION = '0.1.1'
8+
DESCRIPTION = 'A reverse engineered API for Inflection AI Personal Intelligence, called PI'
9+
LONG_DESCRIPTION = 'A reverse engineered API for Inflection AI Personal Intelligence, called PI'
10+
11+
setup(
12+
name="inflection-pi-api",
13+
version=VERSION,
14+
author="hansfzlorenzana",
15+
description=DESCRIPTION,
16+
long_description_content_type="text/markdown",
17+
long_description=long_description,
18+
packages=find_packages(),
19+
python_requires=">=3.7",
20+
install_requires=['httpx', 'websocket-client', 'requests_toolbelt', 'loguru'],
21+
extras_require={
22+
'proxy': ['ballyregan; python_version>="3.9"']
23+
},
24+
keywords=['python', 'pi-api', 'inflection', 'chatgpt', 'pi', 'ai', 'api', 'chatbot'],
25+
classifiers=[
26+
"Programming Language :: Python :: 3",
27+
"License :: OSI Approved :: GNU General Public License (GPL)",
28+
"Operating System :: OS Independent"
29+
],
30+
url="https://github.com/hansfzlorenzana/Inflection-Pi-API"
31+
)

src/__init__.py

Whitespace-only changes.

src/pi.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import json
2+
from curl_cffi import requests
3+
import re
4+
from proxies import fetch_proxy
5+
from time import sleep
6+
from httpx import Client
7+
8+
9+
class Pi:
10+
11+
def __init__(self, cookie: str, proxy: bool=False):
12+
13+
if proxy == True:
14+
proxies = fetch_proxy()
15+
for p in range(len(proxies)):
16+
try:
17+
self.client = Client(timeout=180, proxies= {"http://": f"{proxies[p]}"})
18+
print(f"Connection established with {proxies[p]}")
19+
break
20+
except:
21+
print(f"Connection failed with {proxies[p]}. Trying {p+1}/{len(proxies)} ...")
22+
sleep(1)
23+
else:
24+
self.client = Client(timeout=180)
25+
self.cookie = cookie
26+
27+
def send_message(self, prompt):
28+
29+
payload = json.dumps({"text": prompt})
30+
31+
url = "https://pi.ai/api/chat"
32+
33+
headers = {
34+
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0',
35+
'Accept-Language': 'en-US,en;q=0.7',
36+
'Referer': 'https://pi.ai/api/chat',
37+
'Content-Type': 'application/json',
38+
'Sec-Fetch-Dest': 'empty',
39+
'Sec-Fetch-Mode': 'cors',
40+
'Sec-Fetch-Site': 'same-origin',
41+
'Connection': 'keep-alive',
42+
'Cookie': f'{self.cookie}'
43+
}
44+
45+
response = requests.post( url, headers=headers, data=payload,impersonate="chrome110",timeout=500)
46+
decoded_data = response.content.decode("utf-8")
47+
48+
decoded_data = re.sub('\n+', '\n', decoded_data).strip()
49+
data_strings = decoded_data.split('\n')
50+
completions = []
51+
52+
for data_string in data_strings:
53+
# Check if the string starts with 'data:'
54+
if data_string.startswith('data:'):
55+
# Extract the JSON data part
56+
json_str = data_string[6:].strip()
57+
try:
58+
data = json.loads(json_str)
59+
if 'text' in data:
60+
completions.append(data['text'])
61+
except json.JSONDecodeError:
62+
# Handle invalid JSON here (skip or log the error)
63+
pass
64+
65+
answer = ''.join(completions)
66+
67+
return answer

src/pi_httpx.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import json
2+
import re
3+
from proxies import fetch_proxy
4+
from time import sleep
5+
from httpx import Client
6+
7+
8+
class Pi:
9+
10+
def __init__(self, cookie: str, proxy: bool=False):
11+
12+
if proxy == True:
13+
proxies = fetch_proxy()
14+
for p in range(len(proxies)):
15+
try:
16+
self.client = Client(timeout=180, proxies= {"http://": f"{proxies[p]}"})
17+
print(f"Connection established with {proxies[p]}")
18+
break
19+
except:
20+
print(f"Connection failed with {proxies[p]}. Trying {p+1}/{len(proxies)} ...")
21+
sleep(1)
22+
else:
23+
self.client = Client(timeout=180)
24+
self.cookie = cookie
25+
26+
def send_message(self, prompt):
27+
28+
payload = json.dumps({"text": prompt})
29+
30+
url = "https://pi.ai/api/chat"
31+
32+
headers = {
33+
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0',
34+
'Host': 'www.pi.ai',
35+
'Accept': '*/*',
36+
'Accept-Language': 'en-US,en;q=0.7',
37+
'Referer': 'https://pi.ai/api/chat',
38+
'Content-Type': 'application/json',
39+
'Sec-Fetch-Dest': 'empty',
40+
'Sec-Fetch-Mode': 'cors',
41+
'Sec-Fetch-Site': 'same-origin',
42+
'Connection': 'keep-alive',
43+
'Cookie': f'{self.cookie}'
44+
}
45+
46+
try:
47+
response = self.client.post(url, headers=headers, content=payload, timeout=500)
48+
response.raise_for_status()
49+
50+
decoded_data = response.content.decode("utf-8")
51+
decoded_data = re.sub('\n+', '\n', decoded_data).strip()
52+
data_strings = decoded_data.split('\n')
53+
completions = []
54+
55+
for data_string in data_strings:
56+
if data_string.startswith('data:'):
57+
json_str = data_string[6:].strip()
58+
try:
59+
data = json.loads(json_str)
60+
if 'text' in data:
61+
completions.append(data['text'])
62+
except json.JSONDecodeError:
63+
pass
64+
65+
answer = ''.join(completions)
66+
return answer
67+
68+
except Exception as e:
69+
print(f"An error occurred: {e}")
70+
return None
71+
finally:
72+
self.client.close()

src/proxies.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from ballyregan import ProxyFetcher
2+
from ballyregan.models import Protocols, Anonymities
3+
from fp.fp import FreeProxy
4+
5+
def fetch_proxy():
6+
fetcher = ProxyFetcher()
7+
try:
8+
proxies = fetcher.get(
9+
limit=10,
10+
protocols=[Protocols.HTTP],
11+
anonymities=[Anonymities.ANONYMOUS],
12+
)
13+
except:
14+
print("No Anonymous proxies found. Switching to normal proxies ...")
15+
proxies = fetcher.get(
16+
limit=10,
17+
protocols=[Protocols.HTTP],
18+
)
19+
return proxies
20+
21+
def fetch_free_proxy():
22+
try:
23+
proxies = FreeProxy(country_id=['US'],
24+
anonym=True,
25+
elite=True
26+
).get()
27+
except:
28+
print("No Anonymous proxies found. Switching to normal proxies ...")
29+
proxies = FreeProxy(country_id=['US']
30+
).get()
31+
return proxies
32+

0 commit comments

Comments
 (0)