File size: 5,681 Bytes
5c3c401
 
 
 
 
72f4cb5
 
5c3c401
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72f4cb5
 
 
 
 
5c3c401
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
"""Keyword routes for API endpoints."""
import logging
from fastapi import APIRouter
from fastapi.responses import JSONResponse

from collectors.finfast.keyword import collect as run_historical_backfill # pylint: disable=import-error
from models.database import keywords_collection, summary_collection # pylint: disable=import-error

# Configure logger
logger = logging.getLogger(__name__)

# Create FastAPI Router
router = APIRouter(prefix="/keyword", tags=["keyword"])

@router.post('/historical-backfill')
async def historical_backfill():
    """
    Manual trigger endpoint for 60-day historical keyword backfill.
    
    Returns:
        JSON response with status and details
    """
    try:
        logger.info("Received request for historical keyword backfill")

        # Run the historical backfill
        run_historical_backfill()

        logger.info("Historical keyword backfill completed successfully")
        return JSONResponse(content={
            "status": "success",
            "message": "Historical keyword backfill completed successfully",
            "details": {
                "operation": "60-day historical keyword backfill",
                "method": "standard approach (day-by-day processing)"
            }
        }, status_code=200)

    except Exception as e: # pylint: disable=broad-exception-caught
        logger.error("Error during historical keyword backfill: %s", e)
        return JSONResponse(content={
            "status": "error",
            "message": "Failed to complete historical keyword backfill",
            "error": str(e)
        }, status_code=500)

@router.get('/status')
async def keyword_status():
    """
    Get status of keyword processing.
    
    Returns:
        JSON response with keyword processing status
    """
    try:

        # Get basic statistics
        total_documents = keywords_collection.count_documents({})

        # Get date range
        oldest_doc = keywords_collection.find_one(sort=[("_id", 1)])
        newest_doc = keywords_collection.find_one(sort=[("_id", -1)])

        status_info = {
            "status": "operational",
            "total_keyword_documents": total_documents,
            "date_range": {
                "oldest": oldest_doc["_id"] if oldest_doc else None,
                "newest": newest_doc["_id"] if newest_doc else None
            }
        }

        return JSONResponse(content=status_info, status_code=200)

    except Exception as e: # pylint: disable=broad-exception-caught
        logger.error("Error getting keyword status: %s", e)
        return JSONResponse(content={
            "status": "error",
            "message": "Failed to get keyword status",
            "error": str(e)
        }, status_code=500)

@router.get('/summary')
async def get_all_summaries():
    """
    Get all summaries (today, week, month).
    
    Returns:
        JSON response with all summary data
    """
    try:
        logger.info("Received request for all summaries")

        summaries = {}
        periods = ["today", "week", "month"]

        for period in periods:
            summary_doc = summary_collection.find_one({"_id": period})
            if summary_doc:
                summaries[period] = {
                    "keywords": summary_doc.get("keywords", []),
                    "categories": summary_doc.get("categories", [])
                }
            else:
                summaries[period] = {
                    "keywords": [],
                    "categories": [],
                    "message": f"No summary available for {period}"
                }

        return JSONResponse(content={
            "status": "success",
            "summaries": summaries
        }, status_code=200)

    except Exception as e: # pylint: disable=broad-exception-caught
        logger.error("Error getting all summaries: %s", e)
        return JSONResponse(content={
            "status": "error",
            "message": "Failed to get summaries",
            "error": str(e)
        }, status_code=500)

@router.get('/summary/{period}')
async def get_summary_by_period(period: str):
    """
    Get specific summary by period (today/week/month).
    
    Args:
        period: Analysis period (today, week, or month)
    
    Returns:
        JSON response with specific summary data
    """
    try:
        # Validate period parameter
        valid_periods = ["today", "week", "month"]
        if period not in valid_periods:
            return JSONResponse(content={
                "status": "error",
                "message": "Invalid period. Must be one of: today, week, month",
                "valid_periods": valid_periods
            }, status_code=400)

        logger.info("Received request for %s summary", period)

        summary_doc = summary_collection.find_one({"_id": period})

        if summary_doc:
            return JSONResponse(content={
                "status": "success",
                "period": period,
                "summary": {
                    "keywords": summary_doc.get("keywords", []),
                    "categories": summary_doc.get("categories", [])
                }
            }, status_code=200)
        return JSONResponse(content={
            "status": "not_found",
            "message": f"No summary available for {period}",
            "period": period
        }, status_code=404)

    except Exception as e: # pylint: disable=broad-exception-caught
        logger.error("Error getting %s summary: %s", period, e)
        return JSONResponse(content={
            "status": "error",
            "message": f"Failed to get {period} summary",
            "error": str(e)
        }, status_code=500)