# app.py from fastapi import FastAPI, HTTPException, Query, Depends, Header from pydantic import BaseModel, HttpUrl, Field from typing import List, Dict, Optional, Any from parser.assembler import parse_law_from_texts from supabase_utils import save_law_to_supabase from helpers.indexer import build_indexed_response from helpers.blocks_all import extract_from_url from parser.extract_tables_by_article import extract_tables_from_url import os app = FastAPI( title="Text Extractor API", description="API لاستخراج النصوص من صفحات الويب مع إمكانية التحكم في النطاقات", version="2.1.0" ) API_TOKEN = os.getenv("API_TOKEN") def verify_api_token(x_api_token: str = Header(None)): # إذا لم يتم إرسال التوكن if not x_api_token: raise HTTPException( status_code=401, detail="API token is required" ) # إذا لم يكن التوكن مضبوط في secrets if not API_TOKEN: raise HTTPException( status_code=500, detail="API token not configured on server" ) # إذا كان التوكن غير مطابق if x_api_token != API_TOKEN: raise HTTPException( status_code=401, detail="Invalid API token" ) class IndexedURLRequest(BaseModel): url: HttpUrl save_to_supabase: bool = False timeout: int = Field(10, ge=1, le=60) title_index: Optional[int] = Field(None, ge=0) preamble_start: Optional[int] = Field(None, ge=0) preamble_end: Optional[int] = Field(None, ge=0) body_start: Optional[int] = Field(None, ge=0) body_end: Optional[int] = Field(None, ge=0) return_parsed: bool = Field(False, description="إرجاع النتيجة محلّلة (parsed) بدلاً من raw texts") ranges: Optional[List[List[int]]] = None from fastapi import Depends @app.post("/extract") async def extract_indexed( request: IndexedURLRequest, _: None = Depends(verify_api_token) ): try: # 1) استخراج النصوص الخام من الرابط raw_texts = await extract_from_url(str(request.url), request.timeout) # 2) بناء قائمة مفهرسة بالخيارات المرسلة (قد تكون None) datalist = build_indexed_response( texts=raw_texts, title_index=request.title_index, preamble_start=request.preamble_start, preamble_end=request.preamble_end, body_start=request.body_start, body_end=request.body_end ) # 3) إذا كان return_parsed = True → نرجّع البيانات بعد التحليل if request.return_parsed: parsed = parse_law_from_texts(datalist, str(request.url)) # 4) حفظ إلى Supabase إذا طُلب if request.save_to_supabase: save_law_to_supabase(parsed["law"]) return parsed # 5) وإلا نرجّع القائمة المفهرسة كما هي return datalist except Exception as e: raise HTTPException( status_code=500, detail=f"خطأ في معالجة المحتوى: {str(e)}" ) # ============================ # نقطة GET بسيطة لإرجاع النصوص بدون فهرسة # ============================ @app.get("/extract_link") async def extract_link_get( url: HttpUrl = Query(..., description="رابط الصفحة المراد استخراج النصوص منها"), timeout: int = Query(10, ge=1, le=60, description="مهلة الطلب بالثواني") ): try: raw_texts = await extract_from_url(str(url), timeout) return raw_texts except Exception as e: raise HTTPException(status_code=500, detail=f"خطأ في معالجة المحتوى: {str(e)}") @app.get("/extract_tables") async def extract_tables_get( url: HttpUrl = Query(..., description="رابط الصفحة المراد استخراج الجداول منها"), timeout: int = Query(10, ge=1, le=60, description="مهلة الطلب بالثواني") ): """ استخراج جميع الجداول المرتبطة بالمواد من صفحة الويب وإرجاعها كهيكل JSON مرتب. """ try: # استخدام الوظيفة المستقلة الجديدة result = await extract_tables_from_url(str(url), timeout) return result except Exception as e: raise HTTPException(status_code=500, detail=f"خطأ في معالجة الجداول: {str(e)}")