metaai-sdk 2.3.6__py3-none-any.whl → 3.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- metaai_api/api_server.py +28 -7
- metaai_api/main.py +119 -16
- metaai_api/utils.py +91 -6
- metaai_api/video_generation.py +1 -1
- {metaai_sdk-2.3.6.dist-info → metaai_sdk-3.0.1.dist-info}/METADATA +107 -14
- metaai_sdk-3.0.1.dist-info/RECORD +13 -0
- metaai_sdk-2.3.6.dist-info/RECORD +0 -13
- {metaai_sdk-2.3.6.dist-info → metaai_sdk-3.0.1.dist-info}/WHEEL +0 -0
- {metaai_sdk-2.3.6.dist-info → metaai_sdk-3.0.1.dist-info}/licenses/LICENSE +0 -0
- {metaai_sdk-2.3.6.dist-info → metaai_sdk-3.0.1.dist-info}/top_level.txt +0 -0
metaai_api/api_server.py
CHANGED
|
@@ -107,12 +107,14 @@ class ImageRequest(BaseModel):
|
|
|
107
107
|
new_conversation: bool = False
|
|
108
108
|
media_ids: Optional[list] = None
|
|
109
109
|
attachment_metadata: Optional[dict] = None # {'file_size': int, 'mime_type': str}
|
|
110
|
+
orientation: Optional[str] = None # 'VERTICAL', 'LANDSCAPE' (not HORIZONTAL), or 'SQUARE'
|
|
110
111
|
|
|
111
112
|
|
|
112
113
|
class VideoRequest(BaseModel):
|
|
113
114
|
prompt: str
|
|
114
115
|
media_ids: Optional[list] = None
|
|
115
116
|
attachment_metadata: Optional[dict] = None # {'file_size': int, 'mime_type': str}
|
|
117
|
+
orientation: Optional[str] = None # 'VERTICAL', 'LANDSCAPE', or 'SQUARE'
|
|
116
118
|
wait_before_poll: int = Field(10, ge=0, le=60)
|
|
117
119
|
max_attempts: int = Field(30, ge=1, le=60)
|
|
118
120
|
wait_seconds: int = Field(5, ge=1, le=30)
|
|
@@ -206,7 +208,14 @@ async def chat(body: ChatRequest, cookies: Dict[str, str] = Depends(get_cookies)
|
|
|
206
208
|
raise HTTPException(status_code=400, detail="Streaming not supported via HTTP JSON; set stream=false")
|
|
207
209
|
ai = MetaAI(cookies=cookies, proxy=_get_proxies())
|
|
208
210
|
try:
|
|
209
|
-
return cast(Dict[str, Any],
|
|
211
|
+
return cast(Dict[str, Any], await run_in_threadpool(
|
|
212
|
+
ai.prompt,
|
|
213
|
+
body.message,
|
|
214
|
+
stream=False,
|
|
215
|
+
new_conversation=body.new_conversation,
|
|
216
|
+
media_ids=body.media_ids,
|
|
217
|
+
attachment_metadata=body.attachment_metadata
|
|
218
|
+
))
|
|
210
219
|
except Exception as exc: # noqa: BLE001
|
|
211
220
|
await cache.refresh_after_error()
|
|
212
221
|
raise HTTPException(status_code=502, detail=str(exc)) from exc
|
|
@@ -218,13 +227,15 @@ async def image(body: ImageRequest, cookies: Dict[str, str] = Depends(get_cookie
|
|
|
218
227
|
try:
|
|
219
228
|
# Automatically prepend "generate image of" to the prompt
|
|
220
229
|
prompt = f"generate image of {body.prompt}" if not body.prompt.lower().startswith(("generate image", "create image")) else body.prompt
|
|
221
|
-
return cast(Dict[str, Any],
|
|
222
|
-
prompt,
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
230
|
+
return cast(Dict[str, Any], await run_in_threadpool(
|
|
231
|
+
ai.prompt,
|
|
232
|
+
prompt,
|
|
233
|
+
stream=False,
|
|
234
|
+
new_conversation=body.new_conversation,
|
|
235
|
+
media_ids=body.media_ids,
|
|
226
236
|
attachment_metadata=body.attachment_metadata,
|
|
227
|
-
is_image_generation=True # Image generation uses DISCOVER entrypoint
|
|
237
|
+
is_image_generation=True, # Image generation uses DISCOVER entrypoint
|
|
238
|
+
orientation=body.orientation # Support VERTICAL, HORIZONTAL, SQUARE
|
|
228
239
|
))
|
|
229
240
|
except Exception as exc: # noqa: BLE001
|
|
230
241
|
await cache.refresh_after_error()
|
|
@@ -233,6 +244,10 @@ async def image(body: ImageRequest, cookies: Dict[str, str] = Depends(get_cookie
|
|
|
233
244
|
|
|
234
245
|
@app.post("/video")
|
|
235
246
|
async def video(body: VideoRequest, cookies: Dict[str, str] = Depends(get_cookies)) -> Dict[str, Any]:
|
|
247
|
+
# Force refresh cookies before video generation for best results
|
|
248
|
+
await cache.refresh_if_needed(force=True)
|
|
249
|
+
cookies = await cache.snapshot()
|
|
250
|
+
|
|
236
251
|
ai = MetaAI(cookies=cookies, proxy=_get_proxies())
|
|
237
252
|
try:
|
|
238
253
|
# Automatically prepend "generate a video" to the prompt
|
|
@@ -242,6 +257,7 @@ async def video(body: VideoRequest, cookies: Dict[str, str] = Depends(get_cookie
|
|
|
242
257
|
prompt,
|
|
243
258
|
body.media_ids,
|
|
244
259
|
body.attachment_metadata,
|
|
260
|
+
body.orientation,
|
|
245
261
|
body.wait_before_poll,
|
|
246
262
|
body.max_attempts,
|
|
247
263
|
body.wait_seconds,
|
|
@@ -254,6 +270,10 @@ async def video(body: VideoRequest, cookies: Dict[str, str] = Depends(get_cookie
|
|
|
254
270
|
|
|
255
271
|
@app.post("/video/async")
|
|
256
272
|
async def video_async(body: VideoRequest, cookies: Dict[str, str] = Depends(get_cookies)) -> Dict[str, str]:
|
|
273
|
+
# Force refresh cookies before video generation
|
|
274
|
+
await cache.refresh_if_needed(force=True)
|
|
275
|
+
cookies = await cache.snapshot()
|
|
276
|
+
|
|
257
277
|
job = await jobs.create()
|
|
258
278
|
asyncio.create_task(_run_video_job(job.job_id, body, cookies))
|
|
259
279
|
return {"job_id": job.job_id, "status": "pending"}
|
|
@@ -322,6 +342,7 @@ async def _run_video_job(job_id: str, body: VideoRequest, cookies: Dict[str, str
|
|
|
322
342
|
body.prompt,
|
|
323
343
|
body.media_ids,
|
|
324
344
|
body.attachment_metadata,
|
|
345
|
+
body.orientation,
|
|
325
346
|
body.wait_before_poll,
|
|
326
347
|
body.max_attempts,
|
|
327
348
|
body.wait_seconds,
|
metaai_api/main.py
CHANGED
|
@@ -12,6 +12,8 @@ from metaai_api.utils import (
|
|
|
12
12
|
generate_offline_threading_id,
|
|
13
13
|
extract_value,
|
|
14
14
|
format_response,
|
|
15
|
+
detect_challenge_page,
|
|
16
|
+
handle_meta_ai_challenge,
|
|
15
17
|
)
|
|
16
18
|
|
|
17
19
|
from metaai_api.utils import get_fb_session, get_session
|
|
@@ -29,7 +31,13 @@ class MetaAI:
|
|
|
29
31
|
"""
|
|
30
32
|
|
|
31
33
|
def __init__(
|
|
32
|
-
self,
|
|
34
|
+
self,
|
|
35
|
+
fb_email: Optional[str] = None,
|
|
36
|
+
fb_password: Optional[str] = None,
|
|
37
|
+
cookies: Optional[dict] = None,
|
|
38
|
+
proxy: Optional[dict] = None,
|
|
39
|
+
lsd: Optional[str] = None,
|
|
40
|
+
fb_dtsg: Optional[str] = None
|
|
33
41
|
):
|
|
34
42
|
self.session = get_session()
|
|
35
43
|
self.session.headers.update(
|
|
@@ -47,37 +55,116 @@ class MetaAI:
|
|
|
47
55
|
|
|
48
56
|
if cookies is not None:
|
|
49
57
|
self.cookies = cookies
|
|
58
|
+
# Add manually provided tokens if available
|
|
59
|
+
if lsd:
|
|
60
|
+
self.cookies["lsd"] = lsd
|
|
61
|
+
if fb_dtsg:
|
|
62
|
+
self.cookies["fb_dtsg"] = fb_dtsg
|
|
50
63
|
# Auto-fetch lsd and fb_dtsg if not present in cookies
|
|
51
64
|
if "lsd" not in self.cookies or "fb_dtsg" not in self.cookies:
|
|
52
65
|
self._fetch_missing_tokens()
|
|
53
66
|
else:
|
|
54
67
|
self.cookies = self.get_cookies()
|
|
68
|
+
# Override with manually provided tokens if available
|
|
69
|
+
if lsd:
|
|
70
|
+
self.cookies["lsd"] = lsd
|
|
71
|
+
if fb_dtsg:
|
|
72
|
+
self.cookies["fb_dtsg"] = fb_dtsg
|
|
55
73
|
|
|
56
74
|
self.external_conversation_id = None
|
|
57
75
|
self.offline_threading_id = None
|
|
58
76
|
|
|
59
|
-
def _fetch_missing_tokens(self):
|
|
77
|
+
def _fetch_missing_tokens(self, max_retries: int = 3):
|
|
60
78
|
"""
|
|
61
79
|
Fetch lsd and fb_dtsg tokens if they're missing from cookies.
|
|
80
|
+
Handles Meta AI challenge pages automatically.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
max_retries (int): Maximum number of retry attempts.
|
|
62
84
|
"""
|
|
63
85
|
try:
|
|
64
|
-
cookies_str = "; ".join([f"{k}={v}" for k, v in self.cookies.items() if v])
|
|
65
|
-
|
|
66
86
|
session = HTMLSession()
|
|
67
|
-
|
|
68
|
-
|
|
87
|
+
# Set cookies on session object (not as header string)
|
|
88
|
+
session.cookies.update(self.cookies)
|
|
69
89
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
90
|
+
headers = {
|
|
91
|
+
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
|
|
92
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
93
|
+
}
|
|
74
94
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
95
|
+
for attempt in range(max_retries):
|
|
96
|
+
logging.info(f"Fetching tokens from Meta AI (attempt {attempt + 1}/{max_retries})...")
|
|
97
|
+
response = session.get("https://meta.ai", headers=headers)
|
|
98
|
+
|
|
99
|
+
# Check if we got a challenge page
|
|
100
|
+
challenge_url = detect_challenge_page(response.text)
|
|
101
|
+
if challenge_url:
|
|
102
|
+
logging.warning("Meta AI returned a challenge page. Attempting to handle it...")
|
|
103
|
+
if handle_meta_ai_challenge(session, challenge_url=challenge_url, cookies_dict=self.cookies):
|
|
104
|
+
# Retry fetching tokens after handling challenge
|
|
105
|
+
response = session.get("https://meta.ai", headers=headers)
|
|
106
|
+
else:
|
|
107
|
+
logging.error("Failed to handle Meta AI challenge.")
|
|
108
|
+
if attempt < max_retries - 1:
|
|
109
|
+
time.sleep(2)
|
|
110
|
+
continue
|
|
111
|
+
else:
|
|
112
|
+
break
|
|
113
|
+
|
|
114
|
+
# Extract tokens from HTTP response - try multiple patterns
|
|
115
|
+
if "lsd" not in self.cookies:
|
|
116
|
+
# Try JavaScript pattern first (original method)
|
|
117
|
+
lsd = extract_value(response.text, start_str='"LSD",[],{"token":"', end_str='"}')
|
|
118
|
+
|
|
119
|
+
# If not found, try HTML input field pattern
|
|
120
|
+
if not lsd:
|
|
121
|
+
from bs4 import BeautifulSoup
|
|
122
|
+
soup = BeautifulSoup(response.text, 'html.parser')
|
|
123
|
+
lsd_input = soup.find("input", {"name": "lsd"})
|
|
124
|
+
if lsd_input and lsd_input.get("value"):
|
|
125
|
+
lsd = lsd_input["value"] # type: ignore
|
|
126
|
+
|
|
127
|
+
if lsd:
|
|
128
|
+
self.cookies["lsd"] = lsd
|
|
129
|
+
logging.info("Successfully fetched lsd token.")
|
|
130
|
+
else:
|
|
131
|
+
logging.warning("Could not extract lsd token from response.")
|
|
132
|
+
|
|
133
|
+
if "fb_dtsg" not in self.cookies:
|
|
134
|
+
# Try JavaScript pattern first (original method)
|
|
135
|
+
fb_dtsg = extract_value(response.text, start_str='DTSGInitData",[],{"token":"', end_str='"')
|
|
136
|
+
|
|
137
|
+
# If not found, try alternative patterns
|
|
138
|
+
if not fb_dtsg:
|
|
139
|
+
fb_dtsg = extract_value(response.text, start_str='"DTSGInitialData",[],{"token":"', end_str='"')
|
|
140
|
+
if not fb_dtsg:
|
|
141
|
+
fb_dtsg = extract_value(response.text, start_str='{"token":"', end_str='","async_get_token"')
|
|
142
|
+
|
|
143
|
+
if fb_dtsg:
|
|
144
|
+
self.cookies["fb_dtsg"] = fb_dtsg
|
|
145
|
+
logging.info("Successfully fetched fb_dtsg token.")
|
|
146
|
+
else:
|
|
147
|
+
logging.warning("Could not extract fb_dtsg token from response.")
|
|
148
|
+
if fb_dtsg:
|
|
149
|
+
self.cookies["fb_dtsg"] = fb_dtsg
|
|
150
|
+
logging.info("Successfully fetched fb_dtsg token.")
|
|
151
|
+
else:
|
|
152
|
+
logging.warning("Could not extract fb_dtsg token from response.")
|
|
153
|
+
|
|
154
|
+
# Check if we got both tokens
|
|
155
|
+
if ("lsd" in self.cookies and self.cookies["lsd"]) and \
|
|
156
|
+
("fb_dtsg" in self.cookies and self.cookies["fb_dtsg"]):
|
|
157
|
+
logging.info("Token fetch completed successfully.")
|
|
158
|
+
break
|
|
159
|
+
|
|
160
|
+
if attempt < max_retries - 1:
|
|
161
|
+
logging.warning(f"Tokens not fully fetched. Retrying in 2 seconds...")
|
|
162
|
+
time.sleep(2)
|
|
163
|
+
|
|
79
164
|
except Exception as e:
|
|
80
|
-
|
|
165
|
+
logging.error(f"Error fetching tokens: {e}")
|
|
166
|
+
logging.warning("Some features may not work without lsd/fb_dtsg tokens.")
|
|
167
|
+
logging.info("Consider manually providing 'lsd' and 'fb_dtsg' tokens in the MetaAI constructor.")
|
|
81
168
|
|
|
82
169
|
def get_access_token(self) -> str:
|
|
83
170
|
"""
|
|
@@ -619,6 +706,7 @@ class MetaAI:
|
|
|
619
706
|
def get_cookies(self) -> dict:
|
|
620
707
|
"""
|
|
621
708
|
Extracts necessary cookies from the Meta AI main page.
|
|
709
|
+
Handles challenge pages automatically.
|
|
622
710
|
|
|
623
711
|
Returns:
|
|
624
712
|
dict: A dictionary containing essential cookies.
|
|
@@ -629,10 +717,25 @@ class MetaAI:
|
|
|
629
717
|
if self.fb_email is not None and self.fb_password is not None:
|
|
630
718
|
fb_session = get_fb_session(self.fb_email, self.fb_password)
|
|
631
719
|
headers = {"cookie": f"abra_sess={fb_session['abra_sess']}"}
|
|
720
|
+
|
|
632
721
|
response = session.get(
|
|
633
|
-
"https://
|
|
722
|
+
"https://meta.ai",
|
|
634
723
|
headers=headers,
|
|
635
724
|
)
|
|
725
|
+
|
|
726
|
+
# Check for challenge page
|
|
727
|
+
challenge_url = detect_challenge_page(response.text)
|
|
728
|
+
if challenge_url:
|
|
729
|
+
logging.warning("Meta AI returned a challenge page during get_cookies. Attempting to handle it...")
|
|
730
|
+
cookies_dict = {}
|
|
731
|
+
if fb_session:
|
|
732
|
+
cookies_dict = {"abra_sess": fb_session["abra_sess"]}
|
|
733
|
+
if handle_meta_ai_challenge(session, challenge_url=challenge_url, cookies_dict=cookies_dict):
|
|
734
|
+
# Retry after handling challenge
|
|
735
|
+
response = session.get("https://meta.ai", headers=headers)
|
|
736
|
+
else:
|
|
737
|
+
logging.error("Failed to handle challenge page in get_cookies.")
|
|
738
|
+
|
|
636
739
|
cookies = {
|
|
637
740
|
"_js_datr": extract_value(
|
|
638
741
|
response.text, start_str='_js_datr":{"value":"', end_str='",'
|
metaai_api/utils.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import random
|
|
3
|
+
import re
|
|
3
4
|
import time
|
|
4
5
|
from typing import Dict, Optional
|
|
5
6
|
|
|
@@ -54,11 +55,87 @@ def extract_value(text: str, start_str: str, end_str: str) -> str:
|
|
|
54
55
|
Returns:
|
|
55
56
|
str: The extracted value.
|
|
56
57
|
"""
|
|
57
|
-
start = text.find(start_str)
|
|
58
|
+
start = text.find(start_str)
|
|
59
|
+
if start == -1:
|
|
60
|
+
return ""
|
|
61
|
+
start += len(start_str)
|
|
58
62
|
end = text.find(end_str, start)
|
|
63
|
+
if end == -1:
|
|
64
|
+
return ""
|
|
59
65
|
return text[start:end]
|
|
60
66
|
|
|
61
67
|
|
|
68
|
+
def detect_challenge_page(html_text: str) -> Optional[str]:
|
|
69
|
+
"""
|
|
70
|
+
Detect if Meta AI returned a challenge/verification page.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
html_text (str): The HTML response text.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Optional[str]: The challenge verification URL if found, None otherwise.
|
|
77
|
+
"""
|
|
78
|
+
# Check for challenge page indicators
|
|
79
|
+
if "executeChallenge" in html_text or "__rd_verify" in html_text:
|
|
80
|
+
# Extract the verification URL using regex
|
|
81
|
+
match = re.search(r"fetch\('(/__rd_verify[^']+)'", html_text)
|
|
82
|
+
if match:
|
|
83
|
+
return match.group(1)
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def handle_meta_ai_challenge(session: requests.Session, base_url: str = "https://meta.ai",
|
|
88
|
+
challenge_url: Optional[str] = None, cookies_dict: Optional[dict] = None,
|
|
89
|
+
max_retries: int = 3) -> bool:
|
|
90
|
+
"""
|
|
91
|
+
Handle Meta AI challenge page by making the verification POST request.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
session (requests.Session): The requests session to use.
|
|
95
|
+
base_url (str): The base URL for Meta AI.
|
|
96
|
+
challenge_url (Optional[str]): The challenge verification URL.
|
|
97
|
+
cookies_dict (Optional[dict]): Cookies to include in the request.
|
|
98
|
+
max_retries (int): Maximum number of retry attempts.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
bool: True if challenge was handled successfully, False otherwise.
|
|
102
|
+
"""
|
|
103
|
+
if not challenge_url:
|
|
104
|
+
return False
|
|
105
|
+
|
|
106
|
+
full_url = f"{base_url}{challenge_url}"
|
|
107
|
+
headers = {
|
|
108
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
|
109
|
+
"Accept": "*/*",
|
|
110
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
111
|
+
"Referer": base_url,
|
|
112
|
+
"Origin": base_url,
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if cookies_dict:
|
|
116
|
+
cookies_str = "; ".join([f"{k}={v}" for k, v in cookies_dict.items() if v])
|
|
117
|
+
headers["Cookie"] = cookies_str
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
for attempt in range(max_retries):
|
|
121
|
+
logging.info(f"Handling Meta AI challenge (attempt {attempt + 1}/{max_retries})...")
|
|
122
|
+
response = session.post(full_url, headers=headers, timeout=10)
|
|
123
|
+
|
|
124
|
+
if response.status_code == 200:
|
|
125
|
+
logging.info("Challenge handled successfully.")
|
|
126
|
+
# Wait a moment for the challenge to process
|
|
127
|
+
time.sleep(2)
|
|
128
|
+
return True
|
|
129
|
+
|
|
130
|
+
time.sleep(1)
|
|
131
|
+
|
|
132
|
+
logging.warning(f"Failed to handle challenge after {max_retries} attempts.")
|
|
133
|
+
return False
|
|
134
|
+
except Exception as e:
|
|
135
|
+
logging.error(f"Error handling Meta AI challenge: {e}")
|
|
136
|
+
return False
|
|
137
|
+
|
|
138
|
+
|
|
62
139
|
def format_response(response: dict) -> str:
|
|
63
140
|
"""
|
|
64
141
|
Formats the response from Meta AI to remove unnecessary characters.
|
|
@@ -140,8 +217,16 @@ def get_fb_session(email, password, proxies=None):
|
|
|
140
217
|
soup = BeautifulSoup(response.text, "html.parser")
|
|
141
218
|
|
|
142
219
|
# Parse necessary parameters from the login form
|
|
143
|
-
|
|
144
|
-
|
|
220
|
+
lsd_input = soup.find("input", {"name": "lsd"})
|
|
221
|
+
jazoest_input = soup.find("input", {"name": "jazoest"})
|
|
222
|
+
|
|
223
|
+
if not lsd_input or not jazoest_input:
|
|
224
|
+
raise FacebookInvalidCredentialsException(
|
|
225
|
+
"Could not find login form parameters. Facebook may have changed their login page."
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
lsd = lsd_input["value"] # type: ignore
|
|
229
|
+
jazoest = jazoest_input["value"] # type: ignore
|
|
145
230
|
|
|
146
231
|
# Define the URL and body for the POST request to submit the login form
|
|
147
232
|
post_url = "https://www.facebook.com/login/?next"
|
|
@@ -180,7 +265,7 @@ def get_fb_session(email, password, proxies=None):
|
|
|
180
265
|
# Send the POST request
|
|
181
266
|
session = requests.session()
|
|
182
267
|
jar = cookies.RequestsCookieJar()
|
|
183
|
-
session.proxies = proxies
|
|
268
|
+
session.proxies = proxies # type: ignore
|
|
184
269
|
session.cookies = jar
|
|
185
270
|
|
|
186
271
|
result = session.post(post_url, headers=headers, data=data)
|
|
@@ -245,7 +330,7 @@ def get_fb_session(email, password, proxies=None):
|
|
|
245
330
|
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
|
246
331
|
}
|
|
247
332
|
session = requests.session()
|
|
248
|
-
session.proxies = proxies
|
|
333
|
+
session.proxies = proxies # type: ignore
|
|
249
334
|
response = session.get(url, headers=headers, data=payload, allow_redirects=False)
|
|
250
335
|
|
|
251
336
|
next_url = response.headers["Location"]
|
|
@@ -287,7 +372,7 @@ def get_cookies() -> dict:
|
|
|
287
372
|
dict: A dictionary containing essential cookies.
|
|
288
373
|
"""
|
|
289
374
|
session = HTMLSession()
|
|
290
|
-
response = session.get("https://
|
|
375
|
+
response = session.get("https://meta.ai")
|
|
291
376
|
return {
|
|
292
377
|
"_js_datr": extract_value(
|
|
293
378
|
response.text, start_str='_js_datr":{"value":"', end_str='",'
|
metaai_api/video_generation.py
CHANGED
|
@@ -74,7 +74,7 @@ class VideoGenerator:
|
|
|
74
74
|
# Fetch Meta AI page with cookies
|
|
75
75
|
session = HTMLSession()
|
|
76
76
|
headers = {"cookie": cookies_str}
|
|
77
|
-
response = session.get("https://
|
|
77
|
+
response = session.get("https://meta.ai", headers=headers)
|
|
78
78
|
|
|
79
79
|
# Extract lsd and fb_dtsg
|
|
80
80
|
lsd = extract_value(response.text, start_str='"LSD",[],{"token":"', end_str='"')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: metaai-sdk
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.1
|
|
4
4
|
Summary: Feature-rich Python SDK for Meta AI - Chat, Image & Video Generation powered by Llama 3
|
|
5
5
|
Author-email: Ashiq Hussain Mir <imseldrith@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -91,18 +91,18 @@ All in one SDK
|
|
|
91
91
|
|
|
92
92
|
### 🌟 Core Capabilities
|
|
93
93
|
|
|
94
|
-
| Feature
|
|
95
|
-
|
|
|
96
|
-
| 💬 **Intelligent Chat**
|
|
97
|
-
| 📤 **Image Upload**
|
|
98
|
-
| 🎨 **Image Generation**
|
|
99
|
-
| 🎬 **Video Generation**
|
|
100
|
-
| 🔍 **Image Analysis**
|
|
101
|
-
| 🌐 **Real-time Data**
|
|
102
|
-
| 📚 **Source Citations**
|
|
103
|
-
| 🔄 **Streaming Support**
|
|
104
|
-
| 🔐 **
|
|
105
|
-
| 🌍 **Proxy Support**
|
|
94
|
+
| Feature | Description | Status |
|
|
95
|
+
| ------------------------------ | ------------------------------------------------ | -------- |
|
|
96
|
+
| 💬 **Intelligent Chat** | Powered by Llama 3 with internet access | ✅ Ready |
|
|
97
|
+
| 📤 **Image Upload** | Upload & analyze images, generate similar images | ✅ Ready |
|
|
98
|
+
| 🎨 **Image Generation** | Create stunning AI-generated images | ✅ Ready |
|
|
99
|
+
| 🎬 **Video Generation** | Generate videos from text or uploaded images | ✅ Ready |
|
|
100
|
+
| 🔍 **Image Analysis** | Describe, analyze, and extract info from images | ✅ Ready |
|
|
101
|
+
| 🌐 **Real-time Data** | Get current information via Bing integration | ✅ Ready |
|
|
102
|
+
| 📚 **Source Citations** | Responses include verifiable sources | ✅ Ready |
|
|
103
|
+
| 🔄 **Streaming Support** | Real-time response streaming | ✅ Ready |
|
|
104
|
+
| 🔐 **Flexible Authentication** | Auto-fetch or manual token provision | ✅ Ready |
|
|
105
|
+
| 🌍 **Proxy Support** | Route requests through proxies | ✅ Ready |
|
|
106
106
|
|
|
107
107
|
---
|
|
108
108
|
|
|
@@ -217,7 +217,57 @@ This calculation uses the compound interest formula: A = P(1 + r/n)^(nt)
|
|
|
217
217
|
|
|
218
218
|
---
|
|
219
219
|
|
|
220
|
-
##
|
|
220
|
+
## � Authentication Options
|
|
221
|
+
|
|
222
|
+
The SDK supports **flexible authentication** with two modes:
|
|
223
|
+
|
|
224
|
+
### Mode 1: Automatic Token Fetching (Recommended)
|
|
225
|
+
|
|
226
|
+
Provide basic cookies - `lsd` and `fb_dtsg` tokens are automatically fetched from Meta AI:
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
from metaai_api import MetaAI
|
|
230
|
+
|
|
231
|
+
# Provide basic cookies only
|
|
232
|
+
cookies = {
|
|
233
|
+
"datr": "your_datr_value",
|
|
234
|
+
"abra_sess": "your_abra_sess_value",
|
|
235
|
+
"dpr": "1.25",
|
|
236
|
+
"wd": "1920x1080"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
ai = MetaAI(cookies=cookies)
|
|
240
|
+
# SDK automatically fetches lsd and fb_dtsg tokens!
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Mode 2: Manual Token Provision (Fallback)
|
|
244
|
+
|
|
245
|
+
Provide all tokens manually if automatic fetching fails:
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
from metaai_api import MetaAI
|
|
249
|
+
|
|
250
|
+
# Provide cookies + manual tokens
|
|
251
|
+
cookies = {
|
|
252
|
+
"datr": "your_datr_value",
|
|
253
|
+
"abra_sess": "your_abra_sess_value",
|
|
254
|
+
"dpr": "1.25",
|
|
255
|
+
"wd": "1920x1080"
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
ai = MetaAI(
|
|
259
|
+
cookies=cookies,
|
|
260
|
+
lsd="AVq1234567890", # Manual token
|
|
261
|
+
fb_dtsg="ABCD:EFGH:123456789" # Manual token
|
|
262
|
+
)
|
|
263
|
+
# No auto-fetch needed!
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
> **💡 Tip:** Start with **Mode 1** (automatic). Only use **Mode 2** if you encounter token fetching issues.
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## �💬 Chat Features
|
|
221
271
|
|
|
222
272
|
### Streaming Responses
|
|
223
273
|
|
|
@@ -389,6 +439,11 @@ Create AI-generated videos from text descriptions!
|
|
|
389
439
|
4. Click any request → **Headers** → Copy **Cookie** value
|
|
390
440
|
5. Extract these values: `datr`, `abra_sess`, `dpr`, `wd`
|
|
391
441
|
|
|
442
|
+
> **💡 Note:** The SDK supports **two authentication modes**:
|
|
443
|
+
>
|
|
444
|
+
> - **Automatic** (Recommended): Provide basic cookies, `lsd` and `fb_dtsg` tokens are auto-fetched
|
|
445
|
+
> - **Manual**: Optionally provide `lsd` and `fb_dtsg` tokens directly if automatic fetching fails
|
|
446
|
+
|
|
392
447
|
### Example 1: Generate Your First Video
|
|
393
448
|
|
|
394
449
|
```python
|
|
@@ -442,6 +497,44 @@ else:
|
|
|
442
497
|
🆔 Conversation ID: abc123-def456-ghi789
|
|
443
498
|
```
|
|
444
499
|
|
|
500
|
+
### Example 1b: Manual Token Provision (Optional)
|
|
501
|
+
|
|
502
|
+
If automatic token fetching fails or you prefer to provide tokens directly:
|
|
503
|
+
|
|
504
|
+
```python
|
|
505
|
+
from metaai_api import MetaAI
|
|
506
|
+
|
|
507
|
+
# Your browser cookies + manually extracted tokens
|
|
508
|
+
cookies = {
|
|
509
|
+
"datr": "your_datr_value_here",
|
|
510
|
+
"abra_sess": "your_abra_sess_value_here",
|
|
511
|
+
"dpr": "1.25",
|
|
512
|
+
"wd": "1920x1080"
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
# Initialize with manual tokens (no auto-fetch needed)
|
|
516
|
+
ai = MetaAI(
|
|
517
|
+
cookies=cookies,
|
|
518
|
+
lsd="AVq1234567890", # Manually extracted lsd token
|
|
519
|
+
fb_dtsg="ABCD:EFGH:123456789" # Manually extracted fb_dtsg token
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
# Generate a video - tokens are already provided!
|
|
523
|
+
result = ai.generate_video("A peaceful zen garden with koi fish")
|
|
524
|
+
|
|
525
|
+
if result["success"]:
|
|
526
|
+
print("✅ Video generated successfully with manual tokens!")
|
|
527
|
+
print(f"🎬 Video URL: {result['video_urls'][0]}")
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
**How to extract `lsd` and `fb_dtsg` tokens:**
|
|
531
|
+
|
|
532
|
+
1. Open https://meta.ai in your browser (logged in)
|
|
533
|
+
2. Press **F12** → **Console** tab
|
|
534
|
+
3. Run: `document.cookie`
|
|
535
|
+
4. Look for `lsd=...` and `fb_dtsg=...` values
|
|
536
|
+
5. Alternatively, right-click → **View Page Source** → Search for `"LSD",[],{"token":"` and `DTSGInitData",[],{"token":"`
|
|
537
|
+
|
|
445
538
|
### Example 2: Generate Multiple Videos
|
|
446
539
|
|
|
447
540
|
```python
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
metaai_api/__init__.py,sha256=YT4Dn_m1Fm3Hh10D4Z9jtmADjQHnZSsdtwIn8IlCjN4,714
|
|
2
|
+
metaai_api/api_server.py,sha256=Tb5spAef-kKglEfGP96Fzruw8V0hHUKLqgrz04RDH0M,14000
|
|
3
|
+
metaai_api/client.py,sha256=Th46qW1l8OS8Hu5pj0aGFn4iQNz62A3sbXko-LP-SAU,5263
|
|
4
|
+
metaai_api/exceptions.py,sha256=MRRAppZa0OFA0QLSvC0nABgZN_Ll1dUq9JfhECTqV-Q,114
|
|
5
|
+
metaai_api/image_upload.py,sha256=DQ2xqKdM1I_pF1rZBsB7-QTvXLzke2_0XiIOxFhpc70,6563
|
|
6
|
+
metaai_api/main.py,sha256=PjK2aYjZ0FU17pot3p3n2mcyzMREqd2xnz59rsgRRGE,41918
|
|
7
|
+
metaai_api/utils.py,sha256=xdQzu82rQEFqB3yaT0bEEaAg67fYugr2SQth9HdEOJo,15050
|
|
8
|
+
metaai_api/video_generation.py,sha256=ENtyRN9nO49XBtPaAEVRdICchdVyEtnMCYLTha4kz1k,37480
|
|
9
|
+
metaai_sdk-3.0.1.dist-info/licenses/LICENSE,sha256=hRLLSBixyX0tRh2k0iOGoF7nx-l-vBChNffFfVOIEtc,1290
|
|
10
|
+
metaai_sdk-3.0.1.dist-info/METADATA,sha256=q3vaAK3OzrZnZ7g4i1o1g9lI9KxVGDTJ7lV9l4PlBJQ,31597
|
|
11
|
+
metaai_sdk-3.0.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
12
|
+
metaai_sdk-3.0.1.dist-info/top_level.txt,sha256=R6YCiIQLYFKKaqhNZXDwXbpj1u01P_YhcMCVbJiDUJs,11
|
|
13
|
+
metaai_sdk-3.0.1.dist-info/RECORD,,
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
metaai_api/__init__.py,sha256=YT4Dn_m1Fm3Hh10D4Z9jtmADjQHnZSsdtwIn8IlCjN4,714
|
|
2
|
-
metaai_api/api_server.py,sha256=hb1C3rEarPOHF6W-qqENaxrZWwn8A0qUrjSVlRtNV2s,13248
|
|
3
|
-
metaai_api/client.py,sha256=Th46qW1l8OS8Hu5pj0aGFn4iQNz62A3sbXko-LP-SAU,5263
|
|
4
|
-
metaai_api/exceptions.py,sha256=MRRAppZa0OFA0QLSvC0nABgZN_Ll1dUq9JfhECTqV-Q,114
|
|
5
|
-
metaai_api/image_upload.py,sha256=DQ2xqKdM1I_pF1rZBsB7-QTvXLzke2_0XiIOxFhpc70,6563
|
|
6
|
-
metaai_api/main.py,sha256=nskRHsJknxV_wJ25nJAetDodypKtQ_Lz2gpYqtfTyi0,36743
|
|
7
|
-
metaai_api/utils.py,sha256=qzfIO3WkRH-gSV99b8RiECnMOku8lZEY3Jka9lTLExA,11979
|
|
8
|
-
metaai_api/video_generation.py,sha256=JWrSyx7UhHFOHNiyNds7V_hGkwPHB_SiiApe9jQfp0U,37485
|
|
9
|
-
metaai_sdk-2.3.6.dist-info/licenses/LICENSE,sha256=hRLLSBixyX0tRh2k0iOGoF7nx-l-vBChNffFfVOIEtc,1290
|
|
10
|
-
metaai_sdk-2.3.6.dist-info/METADATA,sha256=iBoQvNSnECGFK-T2WKIO7tJjAnAmJ98-9h-ID9dzDgU,28998
|
|
11
|
-
metaai_sdk-2.3.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
12
|
-
metaai_sdk-2.3.6.dist-info/top_level.txt,sha256=R6YCiIQLYFKKaqhNZXDwXbpj1u01P_YhcMCVbJiDUJs,11
|
|
13
|
-
metaai_sdk-2.3.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|