""" Hook feature views for recommendation system. """ from datetime import timedelta from feast import FeatureView, Field from feast.infra.offline_stores.snowflake_source import SnowflakeSource from feast.types import Float32, Int64, Bool from .entities import hook from .config import get_snowflake_database, get_snowflake_schema # Snowflake data source for hook features hook_features_source = SnowflakeSource( name="hook_features_snowflake", database=get_snowflake_database(), schema=get_snowflake_schema(), table="RECS_HOOKS_RANKER_HOOK_FEATURE_STORE", timestamp_field="EVENT_TIMESTAMP", created_timestamp_column="CREATED_TIMESTAMP", ) # Hook features hook_features = FeatureView( name="hook_features", description="Hook features metrics including average watch time of users who have watched the hook", entities=[hook], ttl=timedelta(days=30), # Keep features for 30 days schema=[ # Note: Don't include hook_id here - it's specified via entities=[hook] Field( name="AVERAGE_WATCH_TIME_30D", dtype=Float32, description="Average watch time in seconds of users who have watched the hook", ), Field( name="MEDIAN_WATCH_TIME_30D", dtype=Float32, description="Median watch time in seconds of users who have watched the hook", ), Field( name="P95_WATCH_TIME_30D", dtype=Float32, description="95th percentile watch time in seconds of users who have watched the hook", ), Field( name="AVERAGE_WATCH_TIME_7D", dtype=Float32, description="Average watch time in seconds of users who have watched the hook in the last 7 days", ), Field( name="MEDIAN_WATCH_TIME_7D", dtype=Float32, description="Median watch time in seconds of users who have watched the hook in the last 7 days", ), Field( name="P95_WATCH_TIME_7D", dtype=Float32, description="95th percentile watch time in seconds of users who have watched the hook in the last 7 days", ), Field(name="FRACTION_OVER_2S_7D", dtype=Float32, description="Fraction of watches that lasted over 2 seconds in the last 7 days"), Field(name="FRACTION_OVER_5S_7D", dtype=Float32, description="Fraction of watches that lasted over 5 seconds in the last 7 days"), Field(name="FRACTION_OVER_2S_30D", dtype=Float32, description="Fraction of watches that lasted over 2 seconds in the last 30 days"), Field(name="FRACTION_OVER_5S_30D", dtype=Float32, description="Fraction of watches that lasted over 5 seconds in the last 30 days"), ], source=hook_features_source, online=True, # Available for online serving tags={"team": "recs"}, ) # Snowflake data source for hook characteristics features hook_characteristics_features_source = SnowflakeSource( name="hook_characteristics_features_snowflake", database=get_snowflake_database(), schema=get_snowflake_schema(), table="RECS_HOOKS_RANKER_HOOK_CHARACTERISTICS_FEATURE_STORE", timestamp_field="EVENT_TIMESTAMP", created_timestamp_column="CREATED_TIMESTAMP", ) hook_characteristics_features = FeatureView( name="hook_characteristics_features", description="Hook characteristics (from Gemini extraction)", entities=[hook], ttl=timedelta(days=30), # Keep features for 30 days schema=[ Field(name="GEMINI_RATING", dtype=Int64, description="Gemini rating of the hook"), Field(name="IS_AI_GENERATED", dtype=Bool, description="Whether the hook is AI generated"), Field(name="IS_UGC", dtype=Bool, description="Whether the hook is UGC (User Generated Content)"), Field(name="HAS_UGC_FACE", dtype=Bool, description="Whether the hook has a UGC face"), Field(name="HAS_UGC_FACE_IN_FIRST_FRAME", dtype=Bool, description="Whether the hook has a UGC face in the first frame"), ], source=hook_characteristics_features_source, online=True, # Available for online serving tags={"team": "recs"}, )