Python Examples
Introduction
This guide provides Python examples for integrating Feedframer into your Python applications using the requests library.
Installation
Install the requests library:
pip install requests
Basic Usage
Simple GET Request
import requests
api_key = 'YOUR_API_KEY'
url = f'https://feedframer.com/api/v1/me?api_key={api_key}&page[size]=12'
response = requests.get(url)
data = response.json()
# Display account info
print(f"Account: {data['username']}")
print(f"Followers: {data['followersCount']}")
# Display posts
for post in data['posts']:
print(post['caption'])
print(post['mediaUrl'])
With Parameters
import requests
api_key = 'YOUR_API_KEY'
params = {
'api_key': api_key,
'filter[type]': 'IMAGE',
'page[size]': 12,
'sort': '-published_at'
}
response = requests.get('https://feedframer.com/api/v1/me', params=params)
data = response.json()
for post in data['posts']:
print(f"Caption: {post['caption']}")
print(f"Media URL: {post['mediaUrl']}")
Complete Client Class
import requests
import time
from typing import Optional, Dict, List
class FeedframerClient:
def __init__(self, api_key: str, base_url: str = 'https://feedframer.com'):
self.api_key = api_key
self.base_url = base_url
self.session = requests.Session()
def get_posts(self, params: Optional[Dict] = None) -> Optional[Dict]:
"""Fetch posts from Feedframer API"""
default_params = {
'api_key': self.api_key,
'page[size]': 12
}
if params:
default_params.update(params)
try:
response = self.session.get(
f'{self.base_url}/api/v1/me',
params=default_params,
timeout=10
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Error fetching posts: {e}")
return None
def get_image_posts(self, limit: int = 12) -> Optional[List[Dict]]:
"""Get only image posts"""
data = self.get_posts({
'filter[type]': 'IMAGE',
'page[size]': limit
})
return data['posts'] if data else None
def get_video_posts(self, limit: int = 12) -> Optional[List[Dict]]:
"""Get only video posts"""
data = self.get_posts({
'filter[type]': 'VIDEO',
'page[size]': limit
})
return data['posts'] if data else None
def get_reels(self, limit: int = 12) -> Optional[List[Dict]]:
"""Get only reels"""
data = self.get_posts({
'filter[type]': 'REELS',
'page[size]': limit
})
return data['posts'] if data else None
# Usage
client = FeedframerClient('YOUR_API_KEY')
posts = client.get_image_posts(12)
if posts:
for post in posts:
print(post['caption'])
Error Handling
import requests
from typing import Optional, Dict
class FeedframerClient:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = 'https://feedframer.com'
def get_posts(self, params: Optional[Dict] = None) -> Optional[Dict]:
default_params = {
'api_key': self.api_key,
'page[size]': 12
}
if params:
default_params.update(params)
try:
response = requests.get(
f'{self.base_url}/api/v1/me',
params=default_params,
timeout=10
)
# Check for HTTP errors
if response.status_code == 401:
print("Authentication failed. Check your API key.")
return None
if response.status_code == 429:
print("Rate limit exceeded. Please wait.")
return None
if response.status_code == 422:
error_data = response.json()
print(f"Validation error: {error_data.get('message', 'Unknown error')}")
return None
response.raise_for_status()
data = response.json()
# Check for API errors
if 'error' in data:
print(f"API Error: {data.get('message', data['error'])}")
return None
return data
except requests.exceptions.Timeout:
print("Request timed out")
return None
except requests.exceptions.ConnectionError:
print("Connection error")
return None
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
return None
Caching
File-Based Caching
import requests
import json
import os
import time
from pathlib import Path
class CachedFeedframerClient:
def __init__(self, api_key: str, cache_dir: str = '/tmp/feedframer-cache'):
self.api_key = api_key
self.base_url = 'https://feedframer.com'
self.cache_dir = Path(cache_dir)
self.cache_duration = 3600 # 1 hour
# Create cache directory
self.cache_dir.mkdir(parents=True, exist_ok=True)
def get_posts(self, params: Optional[Dict] = None) -> Optional[Dict]:
# Generate cache key
cache_key = self._get_cache_key(params)
cache_file = self.cache_dir / f'{cache_key}.json'
# Check cache
if cache_file.exists():
cache_age = time.time() - cache_file.stat().st_mtime
if cache_age < self.cache_duration:
with open(cache_file, 'r') as f:
return json.load(f)
# Fetch fresh data
default_params = {
'api_key': self.api_key,
'page[size]': 12
}
if params:
default_params.update(params)
try:
response = requests.get(
f'{self.base_url}/api/v1/me',
params=default_params,
timeout=10
)
response.raise_for_status()
data = response.json()
# Cache the response
with open(cache_file, 'w') as f:
json.dump(data, f)
return data
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
return None
def _get_cache_key(self, params: Optional[Dict]) -> str:
import hashlib
key_str = json.dumps(params or {}, sort_keys=True)
return hashlib.md5(key_str.encode()).hexdigest()
def clear_cache(self):
"""Clear all cached files"""
for cache_file in self.cache_dir.glob('*.json'):
cache_file.unlink()
Redis Caching
import requests
import json
import redis
from typing import Optional, Dict
class RedisCachedFeedframerClient:
def __init__(self, api_key: str, redis_url: str = 'redis://localhost:6379'):
self.api_key = api_key
self.base_url = 'https://feedframer.com'
self.redis = redis.from_url(redis_url)
self.cache_duration = 3600 # 1 hour
def get_posts(self, params: Optional[Dict] = None) -> Optional[Dict]:
# Generate cache key
cache_key = f'feedframer:{self._get_cache_key(params)}'
# Check cache
cached = self.redis.get(cache_key)
if cached:
return json.loads(cached)
# Fetch fresh data
default_params = {
'api_key': self.api_key,
'page[size]': 12
}
if params:
default_params.update(params)
try:
response = requests.get(
f'{self.base_url}/api/v1/me',
params=default_params,
timeout=10
)
response.raise_for_status()
data = response.json()
# Cache the response
self.redis.setex(
cache_key,
self.cache_duration,
json.dumps(data)
)
return data
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
return None
def _get_cache_key(self, params: Optional[Dict]) -> str:
import hashlib
key_str = json.dumps(params or {}, sort_keys=True)
return hashlib.md5(key_str.encode()).hexdigest()
Pagination
Fetch All Pages
def get_all_posts(api_key: str) -> List[Dict]:
"""Fetch all posts using cursor pagination"""
all_posts = []
cursor = None
while True:
params = {
'api_key': api_key,
'page[size]': 50
}
if cursor:
params['page[cursor]'] = cursor
response = requests.get('https://feedframer.com/api/v1/me', params=params)
data = response.json()
all_posts.extend(data['posts'])
cursor = data['pagination'].get('nextCursor')
if not cursor:
break
return all_posts
# Usage
posts = get_all_posts('YOUR_API_KEY')
print(f'Fetched {len(posts)} total posts')
GraphQL
import requests
def fetch_posts_graphql(api_key: str, limit: int = 12) -> Optional[List[Dict]]:
query = """
query GetPosts($first: Int!) {
posts(first: $first) {
data {
id
caption
mediaUrl
timestamp
}
}
}
"""
variables = {
'first': limit
}
response = requests.post(
f'https://feedframer.com/graphql?api_key={api_key}',
json={
'query': query,
'variables': variables
},
headers={'Content-Type': 'application/json'}
)
if response.ok:
data = response.json()
if 'errors' in data:
print(f"GraphQL errors: {data['errors']}")
return None
return data['data']['posts']['data']
return None
Flask Integration
from flask import Flask, render_template, jsonify
import requests
app = Flask(__name__)
API_KEY = 'YOUR_API_KEY'
def get_instagram_posts(limit=12):
response = requests.get(
'https://feedframer.com/api/v1/me',
params={
'api_key': API_KEY,
'page[size]': limit
}
)
if response.ok:
return response.json()['posts']
return []
@app.route('/')
def index():
posts = get_instagram_posts(12)
return render_template('instagram.html', posts=posts)
@app.route('/api/posts')
def api_posts():
posts = get_instagram_posts(12)
return jsonify({'posts': posts})
if __name__ == '__main__':
app.run(debug=True)
Django Integration
# views.py
from django.shortcuts import render
from django.http import JsonResponse
from django.conf import settings
import requests
def instagram_feed(request):
response = requests.get(
'https://feedframer.com/api/v1/me',
params={
'api_key': settings.FEEDFRAMER_API_KEY,
'page[size]': 12
}
)
posts = response.json()['posts'] if response.ok else []
return render(request, 'instagram/feed.html', {
'posts': posts
})
def api_posts(request):
response = requests.get(
'https://feedframer.com/api/v1/me',
params={
'api_key': settings.FEEDFRAMER_API_KEY,
'page[size]': 12,
'filter[type]': request.GET.get('type', '')
}
)
if response.ok:
return JsonResponse(response.json())
return JsonResponse({'error': 'Failed to fetch posts'}, status=500)
Async with aiohttp
import aiohttp
import asyncio
async def fetch_posts_async(api_key: str) -> Optional[Dict]:
params = {
'api_key': api_key,
'page[size]': 12
}
async with aiohttp.ClientSession() as session:
async with session.get(
'https://feedframer.com/api/v1/me',
params=params
) as response:
if response.status == 200:
return await response.json()
return None
# Usage
async def main():
posts = await fetch_posts_async('YOUR_API_KEY')
print(posts)
asyncio.run(main())