Spaces:
Sleeping
Sleeping
| # 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 | |
| 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 بسيطة لإرجاع النصوص بدون فهرسة | |
| # ============================ | |
| 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)}") | |
| 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)}") | |