Posts tagged with python

I'm working on a Python script that uploads videos directly to a Facebook Page as Reels using the Facebook Graph API. My videos are hosted on a CDN, and I would like to upload them directly to Facebook without downloading them to my local server.

I am currently using Facebook's video_reels endpoint to upload videos as reels. For local files, the process works perfectly by uploading the video in binary form. However, I want to avoid downloading the video locally when it's hosted on a CDN and instead directly upload it from the CDN URL.

Here’s a simplified version of my current code:

import requests # Facebook API parameters page_access_token = 'your_page_access_token' page_id = 'your_page_id' api_version = 'v20.0' video_url = 'https://cdn.example.com/video.mp4'  # CDN URL of the video video_description = "My awesome reel" video_title = "Reel Title" thumbnail_path = 'thumb.jpg' # Step 1: Initialize the upload session for reels def initialize_upload_reel():     url = f"https://graph.facebook.com/{api_version}/{page_id}/video_reels"     payload = {         'upload_phase': 'start',         'access_token': page_access_token     }          response = requests.post(url, data=payload)     if response.status_code == 200:         data = response.json()         video_id = data['video_id']         print(f"Upload session started. Video ID: {video_id}")         return video_id     else:         raise Exception(f"Error initializing reel upload: {response.text}") # Step 2: Upload the reel video file def process_upload_reel(video_id, file_size):     url = f"https://rupload.facebook.com/video-upload/v20.0/{video_id}"     headers = {         'Authorization': f'OAuth {page_access_token}',         'Content-Type': 'application/octet-stream',         'offset': '0',         'file_size': str(file_size)     }     with open(video_url, 'rb') as file_data:         response = requests.post(url, headers=headers, data=file_data)          if response.status_code == 200:         print("Reel Uploaded")     else:         raise Exception(f"Error uploading reel video: {response.text}") def publish_reel(video_id, description, publish_time=None, published=True):     url = f"https://graph.facebook.com/{api_version}/{page_id}/video_reels"     thumb_file = {'thumb': open(thumbnail_url, 'rb')}          payload = {         'access_token': page_access_token,         'video_id': video_id,         'upload_phase': 'finish',         'title': title_entry.get(),  # Ensure title is passed         'description': description_entry.get()  # Ensure description is passed     }     if publish_time:         payload['video_state'] = 'SCHEDULED'         payload['scheduled_publish_time'] = publish_time     else:         payload['video_state'] = 'PUBLISHED' if published else 'DRAFT'     response = requests.post(url, data=payload, files=thumb_file)     thumb_file['thumb'].close()     if response.status_code == 200:         check_video_status(video_id)              else:         raise Exception(f"Error publishing reel: {response.text}") 

The Problem: When I attempt to upload using the CDN URL, I receive the following error message:

{   "error": {     "message": "There was a problem uploading your video file. Please try again with another file.",     "type": "OAuthException",     "code": 6000,     "error_subcode": 1363130,     "error_user_title": "Video Upload Is Missing",     "error_user_msg": "The video was not uploaded.",     "fbtrace_id": "Ai3SicB2QxOVA-ZpIQu7cjT"   } } 

It seems like Facebook's Reels API doesn't support uploading videos directly from a CDN URL using the file_url parameter, or I may be missing something in the implementation.

Question: Is it possible to upload videos directly from a CDN URL to Facebook Reels via the Graph API without downloading the video locally first?

If yes, how should I structure my API request to achieve this?

If no, what is the recommended approach for handling CDN-hosted videos in this scenario (such as avoiding downloading the video to the server)? Any help or guidance would be greatly appreciated!

Wondering can anyone point me in the right direction here. I am trying to access the activity endpoint of the facebook marketing api and keep getting a missing permissions error.

https://developers.facebook.com/docs/marketing-api/reference/ad-activity/

Can anyone help or point me to what I am doing wrong?

I am following this stack so think I am right in graph endpoint:

Using the Activity Log Endpoint in the Facebook Marketing APIs

Endpoint I am creating looks like this in python:

url = f"https://graph.facebook.com/v20.0/act_{account_id}/activities?access_token={access_token}" 

I have tried recreating my token and giving all permissions to it and still getting the same error so not sure what I am missing. Can someone point me to the permissions required for it? This is the error I'm seeing:

Here is the error:

{'error': {'message': '(#100) Missing permissions', 'type': 'OAuthException', 'code': 100, 'fbtrace_id': 'Aa6zg3SUnxRo_rLBI6EQTtA'}} 

I have been working with the Google Ads API to generate keyword ideas using the Keyword Planner. The script works perfectly fine on macOS, and I've tested it on multiple Mac machines without any issues. However, when I try to run the same script on an Ubuntu machine, it fails with the following error:

root@545d9b292810:/app# python3 generate_keyword_ideas.py --customer_id 473727 Traceback (most recent call last):   File "/usr/local/lib/python3.8/dist-packages/google/ads/googleads/client.py", line 203, in _get_api_services_by_version     version_module = import_module(f"google.ads.googleads.{version}")   File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module     return _bootstrap._gcd_import(name[level:], package, level)   File "<frozen importlib._bootstrap>", line 1014, in _gcd_import   File "<frozen importlib._bootstrap>", line 991, in _find_and_load   File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked ModuleNotFoundError: No module named 'google.ads.googleads.v17' During handling of the above exception, another exception occurred: Traceback (most recent call last):   File "generate_keyword_ideas.py", line 176, in <module>     main(   File "generate_keyword_ideas.py", line 38, in main     keyword_plan_idea_service = client.get_service("KeywordPlanIdeaService")   File "/usr/local/lib/python3.8/dist-packages/google/ads/googleads/client.py", line 356, in get_service     api_module = self._get_api_services_by_version(version)   File "/usr/local/lib/python3.8/dist-packages/google/ads/googleads/client.py", line 205, in _get_api_services_by_version     raise ValueError( ValueError: Specified Google Ads API version "v17" does not exist. Valid API versions are: "v11", "v10", "v9" 

What I've Tried: I have confirmed that the Google Ads API library version 17.0.0 is installed on both macOS and Ubuntu. The Python version on Ubuntu is 3.8, and I ensured that all dependencies are correctly installed. I’ve tried reinstalling the google-ads package and even setting up a fresh virtual environment. The script works flawlessly on macOS, so the issue seems to be specific to Ubuntu.

The script should run on Ubuntu just as it does on macOS without throwing the "Specified Google Ads API version 'v17' does not exist" error.

Specifications: Python version: 3.8 on Ubuntu Google Ads API library version: 17.0.0 OS: Ubuntu 20.04

I'm desperately trying to post a post with an image and an image URL via the Facebook Graph API. No matter what I do, I always get error messages.

Does anyone here have any sample code or ideas on how to implement this with Python? I would be very grateful for constructive answers!

import requests from io import BytesIO def post_facebook_photo(message, image_url):     access_token = 'DEIN_ACCESS_TOKEN'     feed_url = "https://graph.facebook.com/v20.0/me/feed"          try:                image_response = requests.get(image_url)         image_response.raise_for_status()     except requests.exceptions.RequestException as e:         print(f"Fehler beim Herunterladen des Bildes: {e}")         return     image_file = BytesIO(image_response.content)             photo_upload_url = "https://graph.facebook.com/v20.0/me/photos"     photo_data = {'access_token': access_token}     photo_files = {'file': ('image.jpg', image_file, 'image/jpeg')}          photo_response = requests.post(photo_upload_url, data=photo_data, files=photo_files)     photo_response_data = photo_response.json()     if 'id' in photo_response_data:         photo_id = photo_response_data['id']         post_data = {             'message': message,             'attached_media': [{'media_fbid': photo_id}],             'access_token': access_token         }                  post_response = requests.post(feed_url, json=post_data)         return post_response.json()     else:         return photo_response_data response = post_facebook_photo("Hier ist ein neues Bild!", "IMAGE-URL") print(response) 

Here's one of the weirdest issue I have ever experienced with an API. Let's see, so I am using the Facebook Business API, and it works fine for most requests I do, however there are some accounts that behave very strange.

Let's see, if I call this:

accounts_general_fields = ['account_id', 'business_name', 'account_status', 'age', 'amount_spent','balance','currency'] print(me.get_ad_accounts(fields=accounts_general_fields)) 

this works fine, there is not issue, however when I want to iterative over it, for example

accounts= list(me.get_ad_accounts(fields=accounts_general_fields)) 
accounts= me.get_ad_accounts(fields=accounts_general_fields) accounts_fixed = [account.api_get(fields=accounts_general_fields) for account in accounts] 
accounts= me.get_ad_accounts(fields=accounts_general_fields) accounts_fixed = [account.export_all_data() for account in accounts] 

or

accounts= me.get_ad_accounts(fields=accounts_general_fields) accounts_fixed = [account for account in accounts] 

it gets this:

facebook_business.exceptions.FacebookRequestError:    Message: Call was not successful   Method:  GET   Path:    https://graph.facebook.com/v20.0/me/adaccounts   Params:  {'fields': 'account_id,business_name,account_status,age,amount_spent,balance,currency', 'summary': 'true', 'after': 'MjM4NDM4NDA2MTg4NjAxMjkZD'}   Status:  400   Response:     {       "error": {         "message": "(#80004) There have been too many calls to this ad-account. Wait a bit and try again. For more info, please refer to https://developers.facebook.com/docs/graph-api/overview/rate-limiting#ads-management.",         "type": "OAuthException",         "code": 80004,         "error_subcode": 2446079,         "fbtrace_id": "ArA51rxNPTHAl7CrHVCaEWG"       }     } 

This behavior happens with other endpoints, for example:

AdAccount(ad_account_id).get_campaigns(fields=fields) 

and

AdAccount(ad_account_id).get_campaigns(fields=fields) 

but just for specific ad accounts, like 3 or 4 accounts of 300 accounts. I don't know what could be happening. Here is my implementation for those endpoints:

 def fetch_adsets_for_account(ad_account_id, fields):     try:         return list(AdAccount(ad_account_id).get_ad_sets(fields=fields))     except Exception as e:         print(f"Failed to fetch ad sets for ad account {ad_account_id}: {e}")         return [] def fetch_adsets_data(ad_account_ids, fields):     all_data = []     # Use ThreadPoolExecutor to fetch data in parallel     with concurrent.futures.ThreadPoolExecutor(max_workers=30) as executor:         # Create a list of futures         futures = {executor.submit(fetch_adsets_for_account, ad_account_id, fields): ad_account_id for ad_account_id in ad_account_ids}         # As each future completes, append the result to all_data         for future in concurrent.futures.as_completed(futures):             try:                 data = future.result()                 all_data.extend(data)             except Exception as e:                 ad_account_id = futures[future]                 print(f"An error occurred for ad account {ad_account_id}: {e}")     # Convert the collected data to a DataFrame     df = pd.DataFrame(all_data)     return df #  Example usage: ad_account_ids = df_accounts["id"].tolist()[:] fields = ['name', 'status', 'start_time', 'lifetime_budget'] start = time.time() df_individual_adsets = fetch_adsets_data(ad_account_ids, fields) df_individual_adsets["date"] = today_data end = time.time() print(end - start) 

Here's one example of the problem for this:

Failed to fetch ad sets for ad account act_400136354038554:    Message: Call was not successful   Method:  GET   Path:    https://graph.facebook.com/v20.0/act_400136354038554/adsets   Params:  {'fields': 'name,status,start_time,lifetime_budget', 'summary': 'true', 'after': 'QVFIUmM2a3VXdG5XRG43OFd3ZAVdLNlV5d1BaR3NlWFlyTk9zQW5yaElIYWZAieVF0b3pFMUphV0tIZAmR4VEE2S3J0LTIZD'}   Status:  400   Response:     {       "error": {         "message": "User request limit reached",         "type": "OAuthException",         "is_transient": false,         "code": 17,         "error_subcode": 2446079,         "error_user_title": "Ad Account Has Too Many API Calls",         "error_user_msg": "There have been too many calls from this ad-account. Please wait a bit and try again.",         "fbtrace_id": "A-LW6ciS_vyN_vkhK5CD0tW"       }     }