Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit 60aeec3

Browse files
authored
Merge pull request #58 from Integration-Automation/dev
Add image upload using URL | File path | base64
2 parents b2453bb + 118580e commit 60aeec3

File tree

7 files changed

+161
-33
lines changed

7 files changed

+161
-33
lines changed

stable.toml renamed to dev.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ requires = ["setuptools>=61.0"]
55
build-backend = "setuptools.build_meta"
66

77
[project]
8-
name = "re_edge_gpt"
9-
version = "0.0.17"
8+
name = "re_edge_gpt_dev"
9+
version = "0.0.18"
1010
authors = [
1111
{ name = "JE-Chen", email = "jechenmailman@gmail.com" },
1212
]

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ requires = ["setuptools>=61.0"]
55
build-backend = "setuptools.build_meta"
66

77
[project]
8-
name = "re_edge_gpt_dev"
9-
version = "0.0.17"
8+
name = "re_edge_gpt"
9+
version = "0.0.18"
1010
authors = [
1111
{ name = "JE-Chen", email = "jechenmailman@gmail.com" },
1212
]

re_edge_gpt/chathub.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import asyncio
22
import json
3-
import os
43
import ssl
54
import sys
65
from time import time
@@ -20,6 +19,7 @@
2019
from .conversation_style import CONVERSATION_STYLE_TYPE
2120
from .proxy import get_proxy
2221
from .request import ChatHubRequest
22+
from .upload_image import upload_image, upload_image_url
2323
from .utilities import append_identifier
2424
from .utilities import get_ran_hex
2525
from .utilities import guess_locale
@@ -50,6 +50,7 @@ def __init__(
5050
client_id=conversation.struct["clientId"],
5151
conversation_id=conversation.struct["conversationId"],
5252
)
53+
self.conversation_id = conversation.struct["conversationId"] or self.request.conversation_id
5354
self.cookies = cookies
5455
self.proxy: str = get_proxy(proxy)
5556
self.session = httpx.AsyncClient(
@@ -68,7 +69,7 @@ async def get_conversation(
6869
conversation_signature: str = None,
6970
client_id: str = None,
7071
) -> dict:
71-
conversation_id = conversation_id or self.request.conversation_id
72+
self.conversation_id = conversation_id or self.request.conversation_id
7273
conversation_signature = (
7374
conversation_signature or self.request.conversation_signature
7475
)
@@ -101,6 +102,8 @@ async def ask_stream(
101102
webpage_context: Union[str, None] = None,
102103
search_result: bool = False,
103104
locale: str = guess_locale(),
105+
# Use for attachment
106+
attachment: dict = None,
104107
) -> Generator[bool, Union[dict, str], None]:
105108
""" """
106109
if self.encrypted_conversation_signature is not None:
@@ -119,13 +122,23 @@ async def ask_stream(
119122
proxy=self.proxy,
120123
)
121124
await _initial_handshake(wss)
125+
# Image
126+
image_url = None
127+
if attachment is not None:
128+
if attachment.get("image_url") is not None:
129+
response = await upload_image_url(**attachment, conversation_id=self.conversation_id)
130+
else:
131+
response = await upload_image(**attachment)
132+
if response:
133+
image_url = f"https://www.bing.com/images/blob?bcid={response}"
122134
# Construct a ChatHub request
123135
self.request.update(
124136
prompt=prompt,
125137
conversation_style=conversation_style,
126138
webpage_context=webpage_context,
127139
search_result=search_result,
128140
locale=locale,
141+
image_url=image_url,
129142
)
130143
# Send request
131144
await wss.send_str(append_identifier(self.request.struct))

re_edge_gpt/re_edge_gpt.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ async def ask(
9494
search_result: bool = False,
9595
locale: str = guess_locale(),
9696
simplify_response: bool = False,
97+
attachment: dict[str, str] = None
9798
):
9899
"""
99100
Ask a question to the bot
@@ -115,6 +116,7 @@ async def ask(
115116
webpage_context=webpage_context,
116117
search_result=search_result,
117118
locale=locale,
119+
attachment=attachment,
118120
):
119121
if final:
120122
if not simplify_response:

re_edge_gpt/request.py

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,8 @@ def update(
3131
webpage_context: Union[str, None] = None,
3232
search_result: bool = False,
3333
locale: str = guess_locale(),
34+
image_url: str = None
3435
) -> None:
35-
options = [
36-
"deepleo",
37-
"enable_debug_commands",
38-
"disable_emoji_spoken_text",
39-
"enablemm",
40-
]
4136
if conversation_style:
4237
if not isinstance(conversation_style, ConversationStyle):
4338
conversation_style = getattr(ConversationStyle, conversation_style)
@@ -65,7 +60,20 @@ def update(
6560
"arguments": [
6661
{
6762
"source": "cib",
68-
"optionsSets": options,
63+
"optionsSets": [
64+
"nlu_direct_response_filter",
65+
"deepleo",
66+
"disable_emoji_spoken_text",
67+
"responsible_ai_policy_235",
68+
"enablemm",
69+
"iycapbing",
70+
"iyxapbing",
71+
"dv3sugg",
72+
"iyoloxap",
73+
"iyoloneutral",
74+
"gencontentv3",
75+
"nojbf",
76+
],
6977
"allowedMessageTypes": [
7078
"ActionRequest",
7179
"Chat",
@@ -79,30 +87,30 @@ def update(
7987
"AdsQuery",
8088
"SemanticSerp",
8189
"GenerateContentQuery",
82-
"SearchQuery",
90+
"SearchQuery"
8391
],
8492
"sliceIds": [
8593
"winmuid1tf",
86-
"styleoff",
87-
"ccadesk",
88-
"smsrpsuppv4cf",
89-
"ssrrcache",
90-
"contansperf",
91-
"crchatrev",
92-
"winstmsg2tf",
93-
"creatgoglt",
94-
"creatorv2t",
95-
"sydconfigoptt",
96-
"adssqovroff",
97-
"530pstho",
98-
"517opinion",
99-
"418dhlth",
100-
"512sprtic1s0",
101-
"emsgpr",
102-
"525ptrcps0",
94+
"newmma-prod",
95+
"imgchatgptv2",
96+
"tts2",
97+
"voicelang2",
98+
"anssupfotest",
99+
"emptyoson",
100+
"tempcacheread",
101+
"temptacache",
102+
"ctrlworkpay",
103+
"winlongmsg2tf",
104+
"628fabocs0",
105+
"531rai268s0",
106+
"602refusal",
107+
"621alllocs0",
108+
"621docxfmtho",
109+
"621preclsvn",
110+
"330uaug",
103111
"529rweas0",
104-
"515oscfing2s0",
105-
"524vidansgs0",
112+
"0626snptrcs0",
113+
"619dagslnv1nr"
106114
],
107115
"verbosity": "verbose",
108116
"traceId": get_ran_hex(32),
@@ -119,6 +127,8 @@ def update(
119127
"messageType": "Chat",
120128
"messageId": message_id,
121129
"requestId": message_id,
130+
"imageUrl": image_url if image_url else None,
131+
"originalImageUrl": image_url if image_url else None,
122132
},
123133
"tone": conversation_style.name.capitalize(), # Make first letter uppercase
124134
"requestId": message_id,

re_edge_gpt/upload_image.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import base64
2+
import json
3+
4+
import aiohttp
5+
6+
payload = {
7+
"imageInfo": {},
8+
"knowledgeRequest": {
9+
"invokedSkills": ["ImageById"],
10+
"subscriptionId": "Bing.Chat.Multimodal",
11+
"invokedSkillsRequestData": {"enableFaceBlur": True},
12+
"convoData": {
13+
"convoid": "",
14+
"convotone": "Balanced"
15+
}
16+
}
17+
}
18+
19+
20+
async def upload_image_url(image_url: str, conversation_id: str, proxy: str = None, face_blur: bool = True):
21+
async with aiohttp.ClientSession(
22+
headers={"Referer": "https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx"},
23+
) as session:
24+
url = "https://www.bing.com/images/kblob"
25+
26+
new_payload = payload
27+
new_payload.get("knowledgeRequest").update(
28+
{"invokedSkillsRequestData": {"enableFaceBlur": face_blur}})
29+
new_payload.get("imageInfo").update({"url": image_url})
30+
new_payload.get("knowledgeRequest").get("convoData").update({"convoid": conversation_id})
31+
data = aiohttp.FormData()
32+
data.add_field('knowledgeRequest', json.dumps(new_payload), content_type="application/json")
33+
async with session.post(url, data=data, proxy=proxy) as resp:
34+
return (await resp.json())["blobId"]
35+
36+
37+
async def upload_image(filename: str = None, base64_image: str = None, proxy: str = None, face_blur: bool = True):
38+
async with aiohttp.ClientSession(
39+
headers={"Referer": "https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx"},
40+
) as session:
41+
url = "https://www.bing.com/images/kblob"
42+
43+
new_payload = payload.get("knowledgeRequest").update(
44+
{"invokedSkillsRequestData": {"enableFaceBlur": face_blur}})
45+
46+
if filename is not None:
47+
with open(filename, 'rb') as f:
48+
file_data = f.read()
49+
image_base64 = base64.b64encode(file_data)
50+
elif base64_image is not None:
51+
image_base64 = base64_image
52+
else:
53+
raise Exception('no image provided')
54+
55+
data = aiohttp.FormData()
56+
data.add_field('knowledgeRequest', json.dumps(new_payload), content_type="application/json")
57+
data.add_field('imageBase64', image_base64, content_type="application/octet-stream")
58+
59+
async with session.post(url, data=data, proxy=proxy) as resp:
60+
return (await resp.json())["blobId"]
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import asyncio
2+
import json
3+
from pathlib import Path
4+
5+
from re_edge_gpt import Chatbot
6+
from re_edge_gpt import ConversationStyle
7+
8+
9+
# If you are using jupyter pls install this package
10+
# from nest_asyncio import apply
11+
12+
13+
async def test_ask() -> None:
14+
bot = None
15+
try:
16+
cookies: list[dict] = json.loads(open(
17+
str(Path(str(Path.cwd()) + "/bing_cookies.json")), encoding="utf-8").read())
18+
bot = await Chatbot.create(cookies=cookies)
19+
response = await bot.ask(
20+
prompt="What does this image show?",
21+
conversation_style=ConversationStyle.balanced,
22+
simplify_response=True,
23+
attachment={"image_url": r"https://images.yourstory.com/cs/2/96eabe90392211eb93f18319e8c07a74/Image54nh-1683225460858.jpg"})
24+
# If you are using non ascii char you need set ensure_ascii=False
25+
print(json.dumps(response, indent=2, ensure_ascii=False))
26+
# Raw response
27+
# print(response)
28+
assert response
29+
except Exception as error:
30+
raise error
31+
finally:
32+
if bot is not None:
33+
await bot.close()
34+
35+
36+
if __name__ == "__main__":
37+
# If you are using jupyter pls use nest_asyncio apply()
38+
# apply()
39+
try:
40+
loop = asyncio.get_running_loop()
41+
except RuntimeError:
42+
loop = asyncio.get_event_loop()
43+
loop.run_until_complete(test_ask())

0 commit comments

Comments
 (0)