Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
Binary file added .gitignore
Binary file not shown.
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
# Creator Content Posting Optimization System

## Team Information
- **Team Name**: [Team Name]
- **Year**: [Year]
- **All-Female Team**: [Yes/No]
- **Team Name**: [SMK]
- **Year**: [1st year]
- **All-Female Team**: [No]

## Architecture Overview
Our system analyzes creator engagement history, content type, platform activity trends, and time sensitivity to determine the most effective posting strategy. The backend processes historical engagement data together with hourly platform activity patterns to calculate an expected engagement score for each platform and posting window. Based on this score, the system recommends the optimal posting time and platform for maximizing audience reach and engagement.

The platform selection strategy compares creator-specific performance across Instagram and YouTube for different content formats such as SHORT and LONG content. The recommendation engine combines historical creator engagement with real-time platform activity weighting to ensure that decisions are not only globally optimal but also personalized to each creator’s posting behavior and audience interaction history.

To decide between immediate posting and scheduling, the system evaluates the urgency level of the content using time sensitivity categories such as High, Medium, and Low. High sensitivity content is prioritized for immediate publishing during active engagement windows, while lower priority content is intelligently scheduled for peak audience activity periods to improve expected engagement performance.

The overall architecture follows a full-stack workflow where the frontend dashboard communicates with a FastAPI backend through REST APIs. The backend processes CSV-based datasets, performs recommendation scoring, and returns optimized posting strategies, analytics metrics, and dynamic content pipeline data to the frontend. The dashboard visualizes this data through analytics cards, live content pipeline tracking, and an AI-powered platform optimizer, creating a seamless user flow from content analysis to final posting recommendation.

**Instructions**: Describe your approach in 200 words or less. Address the following:

- How does your system determine the optimal posting time for content?
- What strategy do you use to select between Instagram and YouTube platforms?
- How do you balance platform activity patterns with creator-specific engagement history?
- What approach do you take to decide between immediate posting versus scheduling?
Our system determines the optimal posting time by combining creator engagement history with platform activity patterns across different hourly time slots. The recommendation engine calculates an engagement score using historical performance data and platform activity weights to identify the time window with the highest expected audience interaction.

To select between Instagram and YouTube, the system compares creator-specific engagement trends for different content formats such as SHORT and LONG content. Instagram is prioritized for highly engaging short-form content, while YouTube is preferred when long-form content shows stronger historical performance and audience retention.

The system balances platform-wide activity trends with creator-specific engagement by applying weighted scoring. Global platform activity helps identify peak audience windows, while creator history personalizes recommendations according to the creator’s previous engagement performance, ensuring that recommendations are both data-driven and creator-focused.

For deciding between immediate posting and scheduling, the system evaluates the time sensitivity of the content. High-priority or trending content is recommended for immediate posting during active audience windows, while medium and low sensitivity content is scheduled strategically to maximize expected engagement and avoid audience saturation.

---

Expand Down
Binary file added backend/__pycache__/main.cpython-312.pyc
Binary file not shown.
Binary file not shown.
158 changes: 158 additions & 0 deletions backend/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from backend.recommendation_engine import get_best_recommendation
import pandas as pd
import random

app = FastAPI()
# CORS configuration
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)

# ======================================
# HOME ROUTE
# ======================================

@app.get("/")
def home():

return {
"message": "PostPilot AI Backend Running"
}

# ======================================
# RECOMMENDATION API
# ======================================

@app.get("/recommend")
def recommend(
creator_id: int,
content_type: str,
created_timestamp: int,
time_sensitivity: str
):

result = get_best_recommendation(
creator_id=creator_id,
content_type=content_type,
created_timestamp=created_timestamp,
time_sensitivity=time_sensitivity
)

return result

# ======================================
# ANALYTICS API
# ======================================

@app.get("/analytics")
def analytics():

content_df = pd.read_csv("data/raw/content.csv")

total_posts = len(content_df)

high_sensitivity_posts = len(
content_df[
content_df["time_sensitivity"] == "High"
]
)

short_posts = len(
content_df[
content_df["content_type"] == "SHORT"
]
)

long_posts = len(
content_df[
content_df["content_type"] == "LONG"
]
)

return {

"total_posts": total_posts,

"high_sensitivity_posts":
high_sensitivity_posts,

"short_posts":
short_posts,

"long_posts":
long_posts
}

# ======================================
# CONTENT PIPELINE API
# ======================================

@app.get("/content-pipeline")
def content_pipeline():

content_df = pd.read_csv("data/raw/content.csv")

pipeline = []

# First 15 rows
sample_data = content_df.head(15)

for _, row in sample_data.iterrows():

creator_id = int(row["creator_id"])
content_type = row["content_type"]
created_timestamp = int(row["created_timestamp"])

# Convert dataset values
sensitivity_map = {
"High": "HIGH",
"Medium": "MEDIUM",
"Low": "LOW"
}

time_sensitivity = sensitivity_map[
row["time_sensitivity"]
]

# Recommendation engine
recommendation = get_best_recommendation(
creator_id=creator_id,
content_type=content_type,
created_timestamp=created_timestamp,
time_sensitivity=time_sensitivity
)

pipeline.append({

"content_id":
int(row["content_id"]),

"creator_id":
creator_id,

"content_type":
content_type,

"time_sensitivity":
time_sensitivity,

"recommended_platform":
recommendation["recommended_platform"],

"recommended_time":
recommendation["recommended_time"],

"action":
recommendation["action"],

"expected_engagement":
recommendation["expected_engagement"]
})

return pipeline
169 changes: 169 additions & 0 deletions backend/recommendation_engine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import pandas as pd

# =========================
# LOAD DATASETS
# =========================

historical_df = pd.read_csv("data/raw/historical_engagement.csv")

platform_df = pd.read_csv("data/raw/platform_activity.csv")

content_df = pd.read_csv("data/raw/content.csv")

# =========================
# CLEAN DATA
# =========================

historical_df["avg_engagement"] = pd.to_numeric(
historical_df["avg_engagement"],
errors="coerce"
)

historical_df.dropna(inplace=True)

# =========================
# RECOMMENDATION FUNCTION
# =========================

def get_best_recommendation(
creator_id,
content_type,
created_timestamp,
time_sensitivity
):

# Filter creator/content
filtered = historical_df[
(historical_df["creator_id"] == creator_id) &
(historical_df["content_type"] == content_type)
]

best_score = -1
best_platform = None
best_time = None

# =========================
# SCORING ENGINE
# =========================

for _, row in filtered.iterrows():

platform = row["platform"]
time_slot = row["time_slot"]
engagement = row["avg_engagement"]

# Platform activity lookup
activity_row = platform_df[
(platform_df["platform"] == platform) &
(platform_df["time_slot"] == time_slot)
]

if activity_row.empty:
continue

activity_score = activity_row.iloc[0]["activity_score"]

# Base score
final_score = engagement * activity_score

# YouTube bonus for LONG content
if content_type == "LONG" and platform == "YouTube":
final_score *= 1.15

# Instagram bonus for SHORT content
if content_type == "SHORT" and platform == "Instagram":
final_score *= 1.10

# Best scoring result
if final_score > best_score:
best_score = final_score
best_platform = platform
best_time = time_slot

# =========================
# DECISION LOGIC
# =========================

time_difference = abs(best_time - created_timestamp)

# HIGH urgency
if time_sensitivity == "HIGH":

if time_difference <= 4:
action = "POST_NOW"
else:
action = "SCHEDULE"

# MEDIUM urgency
elif time_sensitivity == "MEDIUM":

if time_difference <= 2:
action = "POST_NOW"
else:
action = "SCHEDULE"

# LOW urgency
else:

if time_difference <= 1:
action = "POST_NOW"
else:
action = "SCHEDULE"

# =========================
# REASONING ENGINE
# =========================

reasons = []

if best_platform == "YouTube":
reasons.append(
"YouTube performs better for LONG content."
)

if best_platform == "Instagram":
reasons.append(
"Instagram shows stronger SHORT content engagement."
)

if best_time >= 18:
reasons.append(
"Peak audience activity detected during evening hours."
)

if action == "SCHEDULE":
reasons.append(
"Scheduling at this time improves expected engagement."
)

# =========================
# RETURN RESULT
# =========================

return {
"creator_id": creator_id,
"content_type": content_type,
"uploaded_at": created_timestamp,
"time_sensitivity": time_sensitivity,
"recommended_platform": best_platform,
"recommended_time": int(best_time),
"expected_engagement": round(best_score, 3),
"action": action,
"reasons": reasons
}


# =========================
# TESTING
# =========================

if __name__ == "__main__":

result = get_best_recommendation(
creator_id=1,
content_type="LONG",
created_timestamp=10,
time_sensitivity="HIGH"
)

print(result)
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pip
Loading