From de1990f9f6dc0cf2aaae3bfb8baa05fd46af4585 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Sat, 11 Jul 2026 02:20:46 +0530 Subject: [PATCH] refactor(instagram): simplify scrape and details capability schemas --- .../capabilities/instagram/details/schemas.py | 31 +++++++------------ .../instagram/scrape/definition.py | 4 +-- .../capabilities/instagram/scrape/schemas.py | 14 ++++----- 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/surfsense_backend/app/capabilities/instagram/details/schemas.py b/surfsense_backend/app/capabilities/instagram/details/schemas.py index 31972b095..1372f881f 100644 --- a/surfsense_backend/app/capabilities/instagram/details/schemas.py +++ b/surfsense_backend/app/capabilities/instagram/details/schemas.py @@ -1,13 +1,14 @@ """``instagram.details`` I/O contracts. A lean surface over ``InstagramScrapeInput`` (``resultsType="details"``). Each -output item is a profile / hashtag / place, discriminated by the synthesized -``detailKind`` field (a SurfSense addition; every other field mirrors the actor). +output item is a profile (``detailKind="profile"``, a SurfSense addition; every +other field mirrors the actor). Hashtag/place details are login-walled and +therefore unsupported. """ from __future__ import annotations -from typing import Annotated, Literal +from typing import Literal from pydantic import BaseModel, Field, model_validator @@ -15,16 +16,9 @@ from app.capabilities.instagram.scrape.schemas import ( MAX_INSTAGRAM_ITEMS, MAX_INSTAGRAM_SOURCES, ) -from app.proprietary.platforms.instagram import ( - InstagramHashtag, - InstagramPlace, - InstagramProfile, -) +from app.proprietary.platforms.instagram import InstagramProfile -InstagramDetailItem = Annotated[ - InstagramProfile | InstagramHashtag | InstagramPlace, - Field(discriminator="detailKind"), -] +InstagramDetailItem = InstagramProfile class DetailsInput(BaseModel): @@ -32,18 +26,17 @@ class DetailsInput(BaseModel): default_factory=list, max_length=MAX_INSTAGRAM_SOURCES, description=( - "Profile / hashtag / place URLs (or bare profile IDs). The URL type " - "determines the detail kind. Provide these OR search_queries." + "Profile URLs or bare profile IDs. Provide these OR search_queries." ), ) search_queries: list[str] = Field( default_factory=list, max_length=MAX_INSTAGRAM_SOURCES, - description="Discovery keywords. Provide these OR urls (never both).", + description="Discovery keywords resolved to profiles. Provide these OR urls.", ) - search_type: Literal["hashtag", "profile", "place"] = Field( - default="hashtag", - description="What to discover from search_queries (no 'user' — use instagram.scrape).", + search_type: Literal["profile", "user"] = Field( + default="profile", + description="Discovery kind (profile-only; hashtag/place are login-walled).", ) search_limit: int = Field( default=10, @@ -78,7 +71,7 @@ class DetailsInput(BaseModel): class DetailsOutput(BaseModel): items: list[InstagramDetailItem] = Field( default_factory=list, - description="One item per profile/hashtag/place, keyed by detailKind.", + description="One profile detail item per resolved profile.", ) @property diff --git a/surfsense_backend/app/capabilities/instagram/scrape/definition.py b/surfsense_backend/app/capabilities/instagram/scrape/definition.py index e84ca4938..7b5d9769f 100644 --- a/surfsense_backend/app/capabilities/instagram/scrape/definition.py +++ b/surfsense_backend/app/capabilities/instagram/scrape/definition.py @@ -10,8 +10,8 @@ from app.capabilities.instagram.scrape.schemas import ScrapeInput, ScrapeOutput INSTAGRAM_SCRAPE = Capability( name="instagram.scrape", description=( - "Scrape public Instagram posts, reels, or mentions from " - "profile/post/hashtag/place URLs, or discover content via search queries." + "Scrape public Instagram posts, reels, or mentions from profile/post/" + "reel URLs, or discover public profiles via search queries." ), input_schema=ScrapeInput, output_schema=ScrapeOutput, diff --git a/surfsense_backend/app/capabilities/instagram/scrape/schemas.py b/surfsense_backend/app/capabilities/instagram/scrape/schemas.py index 0e5646dc7..03e03e55d 100644 --- a/surfsense_backend/app/capabilities/instagram/scrape/schemas.py +++ b/surfsense_backend/app/capabilities/instagram/scrape/schemas.py @@ -26,8 +26,8 @@ class ScrapeInput(BaseModel): default_factory=list, max_length=MAX_INSTAGRAM_SOURCES, description=( - "Instagram URLs or bare profile IDs: profile, post (/p/), reel " - "(/reel/), hashtag (/explore/tags/), or place (/explore/locations/). " + "Instagram URLs or bare profile IDs: profile, post (/p/), or reel " + "(/reel/). Hashtag/place URLs are unsupported (login-walled). " "Provide these OR search_queries (never both)." ), ) @@ -35,13 +35,13 @@ class ScrapeInput(BaseModel): default_factory=list, max_length=MAX_INSTAGRAM_SOURCES, description=( - "Discovery keywords (hashtags as plaintext, no '#'). Provide these " - "OR urls (never both)." + "Discovery keywords resolved to profiles via Google (IG's keyword " + "search is login-walled). Provide these OR urls (never both)." ), ) - search_type: Literal["hashtag", "profile", "place", "user"] = Field( - default="hashtag", - description="What to discover from search_queries. Only used with search_queries.", + search_type: Literal["profile", "user"] = Field( + default="profile", + description="Discovery kind (profile-only; hashtag/place are login-walled).", ) result_type: Literal["posts", "reels", "mentions"] = Field( default="posts",