File size: 6,575 Bytes
f7db7af |
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 172 173 174 175 176 177 178 179 180 181 |
import requests, re, warnings
from dotenv import load_dotenv
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, StreamingResponse
from bs4 import BeautifulSoup
from huggingface_hub import configure_http_backend
from schemas import *
from classes import *
def backend_factory() -> requests.Session:
session = requests.Session()
session.verify = False
return session
configure_http_backend(backend_factory=backend_factory)
warnings.filterwarnings("ignore")
load_dotenv()
meetings_mapping = {
"SA": [
"TSG_SA",
"WG1_Serv",
"WG2_Arch",
"WG3_Security",
"WG4_CODEC",
"WG5_TM",
"WG6_MissionCritical"
],
"CT": [
"TSG_CT",
"WG1_mm-cc-sm_ex-CN1",
"WG2_capability_ex-T2",
"WG3_interworking_ex-CN3",
"WG4_protocollars_ex-CN4",
"WG5_osa_ex-CN5",
"WG6_Smartcard_Ex-T3"
],
"RAN": [
"TSG_RAN",
"WG1_RL1",
"WG2_RL2",
"WG3_Iu",
"WG4_Radio",
"WG5_Test_ex-T1",
"WG6_legacyRAN"
]
}
tdoc_indexer = TDocIndexer()
spec_3gpp_indexer = Spec3GPPIndexer()
spec_etsi_indexer = SpecETSIIndexer()
app = FastAPI()
app.add_middleware(CORSMiddleware, allow_credentials=True, allow_headers=["*"], allow_origins=["*"])
@app.get('/')
def main():
return FileResponse("index.html")
def get_folder_name(working_group: str):
if working_group.endswith("P"):
if working_group.startswith("S"):
return ("SA", 0)
if working_group.startswith("C"):
return ("CT", 0)
if working_group.startswith("R"):
return ("RAN", 0)
m = re.match(r"([A-Z]+)(\d+)", working_group)
if m:
code, num = m.groups()
return (code, int(num))
else:
raise ValueError("Format inattendu")
@app.get("/get_meetings/{working_group}")
def get_meetings(working_group: str):
category, wg_number = get_folder_name(working_group)
folder = meetings_mapping[category][wg_number]
url = f"https://www.3gpp.org/ftp/{meetings_mapping[category][0]}/{folder}"
response = requests.get(url, verify=False)
responseHTML = response.text
soup = BeautifulSoup(responseHTML, "html.parser")
return {"url": url, "meetings": [item.get_text() for item in soup.select("tr td a") if item.get_text().startswith("TSG") or item.get_text().startswith("CT")]}
@app.post("/index_tdocs/working_group")
def index_tdocs_wg_progress(req: IndexTDoc):
if not req.wg:
raise HTTPException(status_code=400, detail="Working Group not defined !")
category, wg_number = get_folder_name(req.wg)
folder = meetings_mapping[category][wg_number]
url = f"https://www.3gpp.org/ftp/{meetings_mapping[category][0]}"
def generate_events():
tdoc_indexer.processed_count = 0 # Reset progress
tdoc_indexer.total_count = 0
tdoc_indexer.process_workgroup(folder, url)
while tdoc_indexer.processed_count < tdoc_indexer.total_count:
yield f"data: {tdoc_indexer.processed_count}/{tdoc_indexer.total_count}"
import time; time.sleep(0.2)
# Pour afficher la fin de l’indexation
yield f"data: {tdoc_indexer.total_count}/{tdoc_indexer.total_count}"
return StreamingResponse(generate_events(), media_type="text/event-stream")
@app.post("/index_tdocs/meeting")
def index_tdocs_meeting_progress(req: IndexTDoc):
if not req.wg:
raise HTTPException(status_code=400, detail="Working Group not defined !")
if not req.meetings:
raise HTTPException(status_code=400, detail="Meetings not defined !")
category, wg_number = get_folder_name(req.wg)
folder = meetings_mapping[category][wg_number]
url = f"https://www.3gpp.org/ftp/{meetings_mapping[category][0]}/{folder}"
def generate_events():
tdoc_indexer.processed_count = 0
tdoc_indexer.total_count = len(req.meetings)
for i, meet in enumerate(req.meetings):
tdoc_indexer.process_meeting(meet, url)
yield f"data: {i+1}/{tdoc_indexer.total_count}"
tdoc_indexer.save_indexer()
return StreamingResponse(generate_events(), media_type="text/event-stream")
@app.post("/index_tdocs/all")
def index_all_tdocs_progress():
def generate_events():
tdoc_indexer.processed_count = 0
tdoc_indexer.total_count = 0
# On lance l’indexation (la méthode met à jour les compteurs)
tdoc_indexer.index_all_tdocs()
while tdoc_indexer.processed_count < tdoc_indexer.total_count:
yield f"data: {tdoc_indexer.processed_count}/{tdoc_indexer.total_count}"
import time; time.sleep(0.2)
yield f"data: {tdoc_indexer.total_count}/{tdoc_indexer.total_count}"
return StreamingResponse(generate_events(), media_type="text/event-stream")
@app.post("/index_specs/3gpp")
def index_3gpp_specs_progress():
def generate_events():
spec_3gpp_indexer.processed_count = 0
spec_3gpp_indexer.total_count = 0
import threading
def worker():
spec_3gpp_indexer.run()
spec_3gpp_indexer.save()
spec_3gpp_indexer.create_bm25_index()
t = threading.Thread(target=worker)
t.start()
while t.is_alive() or spec_3gpp_indexer.processed_count < spec_3gpp_indexer.total_count:
yield f"data: {spec_3gpp_indexer.processed_count}/{spec_3gpp_indexer.total_count}"
import time; time.sleep(0.5)
yield f"data: {spec_3gpp_indexer.total_count}/{spec_3gpp_indexer.total_count}"
return StreamingResponse(generate_events(), media_type="text/event-stream")
@app.post("/index_specs/etsi")
def index_etsi_specs_progress():
def generate_events():
spec_etsi_indexer.processed_count = 0
spec_etsi_indexer.total_count = 0
import threading
def worker():
spec_etsi_indexer.run()
spec_etsi_indexer.save()
spec_etsi_indexer.create_bm25_index()
t = threading.Thread(target=worker)
t.start()
while t.is_alive() or spec_etsi_indexer.processed_count < spec_etsi_indexer.total_count:
yield f"data: {spec_etsi_indexer.processed_count}/{spec_etsi_indexer.total_count}"
import time; time.sleep(0.5)
yield f"data: {spec_etsi_indexer.total_count}/{spec_etsi_indexer.total_count}"
return StreamingResponse(generate_events(), media_type="text/event-stream") |