update
This commit is contained in:
parent
e3872cac5f
commit
2b39ba6324
11 changed files with 352 additions and 3 deletions
62
docs/logiche.md
Normal file
62
docs/logiche.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
1)
|
||||
|
||||
dati lista ingrediente:
|
||||
- informazioni anagrafiche
|
||||
- tipo > automatica associazione a esposizione, se non c'è ritorna errore
|
||||
- associazione cas-inci, identificazione AQUA
|
||||
- aggiungere 5 cifre decimali nelle percentuali
|
||||
- CAS multipli vanno spacchettati in mini loop
|
||||
|
||||
va separato input da dict ingredients
|
||||
|
||||
Se informazioni anagrafiche hanno senso (validatore esiste, tipo cosmetico esiste) > aggiungi a Mongo.
|
||||
|
||||
Viene arricchito subito con informazioni da Cosing, aggiunte chiavi:
|
||||
- INCI
|
||||
- Tox : {NOAEL: (val, fonte), LD50, LOAEL}
|
||||
- Tox Resources
|
||||
- CosIng: Restrizioni, Uso : lista, Sostanze identificate
|
||||
- DAP {}
|
||||
- Esposizione
|
||||
- Riassunto, completo si/no
|
||||
- Stato
|
||||
|
||||
Funzione che va a verificare se tutto queste siano complete anche solo parzialmente per ogni ingrediente, viene fatto un riassunto dei dati trovati
|
||||
|
||||
2)
|
||||
|
||||
generazione excel partendo da questo dato
|
||||
|
||||
Processo:
|
||||
1.
|
||||
- Input arriva grezzo
|
||||
- va caricato su mongodb, restituisce _id
|
||||
Trovo ID delle info anagrafiche:
|
||||
- Cliente
|
||||
- Compilatore
|
||||
- Tipo
|
||||
- Creo un file progetto, restituisce _id
|
||||
Inserisco il record su DB
|
||||
|
||||
-- STATO 0 --
|
||||
|
||||
2.
|
||||
Faccio una verifica per vedere quanti dati pronti per essere elaborati
|
||||
prendo il più vecchio
|
||||
|
||||
L'entità ha l'ordine e il progetto, recupero i due file
|
||||
|
||||
1. Va a cercare su CosIng
|
||||
- Match relativo INCI
|
||||
- Prende Restrizioni, Uso, Sostanze identificate
|
||||
4. Calcolo SED
|
||||
2. Va a pescare Dati DAP
|
||||
5. Calcolo DAP
|
||||
3. Va a cercare Echa
|
||||
- orchestrator echa
|
||||
- Pulizia e ricerca dei dati essenziali (NOAEL e link)
|
||||
|
||||
Per ognuno orchestrator > pulizia > identifico NOAEL
|
||||
|
||||
|
||||
|
||||
BIN
main.db
Normal file
BIN
main.db
Normal file
Binary file not shown.
BIN
main.db.wal
Normal file
BIN
main.db.wal
Normal file
Binary file not shown.
158
marimo/database_creation.py
Normal file
158
marimo/database_creation.py
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
import marimo
|
||||
|
||||
__generated_with = "0.16.5"
|
||||
app = marimo.App(width="medium")
|
||||
|
||||
|
||||
@app.cell
|
||||
def _():
|
||||
import marimo as mo
|
||||
import duckdb
|
||||
return duckdb, mo
|
||||
|
||||
|
||||
@app.cell
|
||||
def _(duckdb):
|
||||
con = duckdb.connect('main.db')
|
||||
return (con,)
|
||||
|
||||
|
||||
@app.cell
|
||||
def _(con, mo):
|
||||
_df = mo.sql(
|
||||
f"""
|
||||
--CREATE SEQUENCE seq_clienti START 1;
|
||||
--CREATE SEQUENCE seq_compilatori START 1;
|
||||
--CREATE SEQUENCE seq_tipi_prodotti START 1;
|
||||
--CREATE SEQUENCE seq_stati_ordini START 1;
|
||||
--CREATE SEQUENCE seq_ordini START 1;
|
||||
""",
|
||||
engine=con
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@app.cell
|
||||
def _(con, mo):
|
||||
_df = mo.sql(
|
||||
f"""
|
||||
CREATE OR REPLACE TABLE clienti (
|
||||
nome_cliente VARCHAR UNIQUE,
|
||||
id_cliente INTEGER PRIMARY KEY DEFAULT NEXTVAL('seq_clienti')
|
||||
)
|
||||
""",
|
||||
engine=con
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@app.cell
|
||||
def _(con, mo):
|
||||
_df = mo.sql(
|
||||
f"""
|
||||
CREATE OR REPLACE TABLE compilatori (
|
||||
nome_compilatore VARCHAR UNIQUE,
|
||||
id_compilatore INTEGER PRIMARY KEY DEFAULT NEXTVAL('seq_compilatori')
|
||||
)
|
||||
""",
|
||||
engine=con
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@app.cell
|
||||
def _(con, mo):
|
||||
_df = mo.sql(
|
||||
f"""
|
||||
|
||||
CREATE OR REPLACE TABLE tipi_prodotti (
|
||||
nome_tipo VARCHAR UNIQUE,
|
||||
id_tipo INTEGER PRIMARY KEY DEFAULT NEXTVAL('seq_tipi_prodotti'),
|
||||
luogo_applicazione VARCHAR,
|
||||
espo_primaria VARCHAR,
|
||||
espo_secondaria VARCHAR,
|
||||
espo_nano VARCHAR,
|
||||
supericie_cm2 INT,
|
||||
frequenza INT,
|
||||
qty_daily_stimata INT,
|
||||
qty_daily_relativa INT,
|
||||
ritenzione FLOAT,
|
||||
espo_daily_calcolata INT,
|
||||
espo_daily_relativa_calcolata INT,
|
||||
peso INT,
|
||||
target VARCHAR
|
||||
)
|
||||
""",
|
||||
engine=con
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@app.cell
|
||||
def _(con, mo):
|
||||
_df = mo.sql(
|
||||
f"""
|
||||
|
||||
CREATE OR REPLACE TABLE stati_ordini (
|
||||
id_stato INTEGER PRIMARY KEY DEFAULT NEXTVAL('seq_stati_ordini'),
|
||||
nome_stato VARCHAR
|
||||
)
|
||||
""",
|
||||
engine=con
|
||||
)
|
||||
return (stati_ordini,)
|
||||
|
||||
|
||||
@app.cell
|
||||
def _(con, mo):
|
||||
_df = mo.sql(
|
||||
f"""
|
||||
|
||||
CREATE OR REPLACE TABLE ordini (
|
||||
id_ordine INTEGER PRIMARY KEY DEFAULT NEXTVAL('seq_ordini'),
|
||||
id_cliente INTEGER,
|
||||
id_compilatore INTEGER,
|
||||
id_tipo_prodotto INTEGER,
|
||||
uuid_ordine VARCHAR NOT NULL,
|
||||
uuid_progetto VARCHAR,
|
||||
data_ordine DATETIME NOT NULL,
|
||||
stato_ordine INTEGER DEFAULT 0,
|
||||
note VARCHAR,
|
||||
FOREIGN KEY (id_cliente) REFERENCES clienti(id_cliente),
|
||||
FOREIGN KEY (id_compilatore) REFERENCES compilatori(id_compilatore),
|
||||
FOREIGN KEY (id_tipo_prodotto) REFERENCES tipi_prodotti(id_tipo),
|
||||
FOREIGN KEY (stato_ordine) REFERENCES stati_ordini(id_stato)
|
||||
)
|
||||
""",
|
||||
engine=con
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@app.cell
|
||||
def _(con, mo):
|
||||
_df = mo.sql(
|
||||
f"""
|
||||
|
||||
""",
|
||||
engine=con
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
@app.cell
|
||||
def _(con, mo, stati_ordini):
|
||||
_df = mo.sql(
|
||||
f"""
|
||||
INSERT INTO stati_ordini (nome_stato) VALUES (
|
||||
'Ordine registrato',
|
||||
''
|
||||
)
|
||||
""",
|
||||
engine=con
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
|
|
@ -18,7 +18,7 @@ def _():
|
|||
|
||||
@app.cell
|
||||
def _():
|
||||
cas = '102-71-6'
|
||||
cas = '63148-62-9'
|
||||
return (cas,)
|
||||
|
||||
|
||||
32
marimo/debug_cosing.py
Normal file
32
marimo/debug_cosing.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import marimo
|
||||
|
||||
__generated_with = "0.16.5"
|
||||
app = marimo.App(width="medium")
|
||||
|
||||
|
||||
@app.cell
|
||||
def _():
|
||||
import marimo as mo
|
||||
return
|
||||
|
||||
|
||||
@app.cell
|
||||
def _():
|
||||
from pif_compiler.services.srv_cosing import cosing_search
|
||||
return (cosing_search,)
|
||||
|
||||
|
||||
@app.cell
|
||||
def _():
|
||||
cas = ' 9006-65-9 '
|
||||
return (cas,)
|
||||
|
||||
|
||||
@app.cell
|
||||
def _(cas, cosing_search):
|
||||
cosing_search(cas, mode='cas')
|
||||
return
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
|
|
@ -6,6 +6,7 @@ import os
|
|||
|
||||
from pif_compiler.functions.common_func import generate_pdf
|
||||
from pif_compiler.services.srv_pubchem import pubchem_dap
|
||||
from pif_compiler.services.srv_cir import search_ingredient
|
||||
from pif_compiler.functions.common_log import get_logger
|
||||
|
||||
logger = get_logger()
|
||||
|
|
@ -203,6 +204,71 @@ async def search_pubchem(request: PubchemRequest):
|
|||
)
|
||||
|
||||
|
||||
class CirSearchRequest(BaseModel):
|
||||
text: str = Field(..., description="Text to search for in the CIR database")
|
||||
|
||||
class Config:
|
||||
json_schema_extra = {
|
||||
"example": {
|
||||
"text": "olio di argan"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CirSearchResponse(BaseModel):
|
||||
success: bool
|
||||
text: str
|
||||
results: Optional[list] = None
|
||||
count: Optional[int] = None
|
||||
error: Optional[str] = None
|
||||
|
||||
|
||||
@router.post("/common/cir-search", response_model=CirSearchResponse, tags=["Common"])
|
||||
async def cir_search_endpoint(request: CirSearchRequest):
|
||||
"""
|
||||
Search for ingredients in the CIR (Cosmetic Ingredient Review) database.
|
||||
|
||||
This endpoint searches the CIR NOAEL database for ingredients matching
|
||||
the provided text query.
|
||||
|
||||
Args:
|
||||
request: CirSearchRequest containing the search text
|
||||
|
||||
Returns:
|
||||
CirSearchResponse with the search results or error information
|
||||
"""
|
||||
logger.info(f"API request received for CIR search: text='{request.text}'")
|
||||
|
||||
try:
|
||||
results = search_ingredient(request.text)
|
||||
|
||||
if results is None:
|
||||
logger.error(f"CIR search returned None for text: {request.text}")
|
||||
return CirSearchResponse(
|
||||
success=False,
|
||||
text=request.text,
|
||||
results=None,
|
||||
count=0,
|
||||
error="An error occurred while searching the CIR database. Please check the logs for details."
|
||||
)
|
||||
|
||||
logger.info(f"Successfully retrieved {len(results)} results from CIR database for text: {request.text}")
|
||||
return CirSearchResponse(
|
||||
success=True,
|
||||
text=request.text,
|
||||
results=results,
|
||||
count=len(results),
|
||||
error=None
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing CIR search request for text '{request.text}': {str(e)}", exc_info=True)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Internal error while processing CIR search request: {str(e)}"
|
||||
)
|
||||
|
||||
|
||||
@router.get("/common/health", tags=["Common"])
|
||||
async def common_health_check():
|
||||
"""
|
||||
|
|
@ -217,6 +283,10 @@ async def common_health_check():
|
|||
"api": "operational",
|
||||
"logging": "operational",
|
||||
"utilities": "operational",
|
||||
"pubchem": "operational"
|
||||
"pubchem": "operational",
|
||||
"cir": "operational"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
from playwright.async_api import async_playwright
|
||||
import os
|
||||
|
||||
from pymongo import MongoClient
|
||||
|
||||
from pif_compiler.functions.common_log import get_logger
|
||||
|
||||
|
||||
log = get_logger()
|
||||
|
||||
async def generate_pdf(link: str, name: str):
|
||||
|
|
@ -90,3 +93,7 @@ async def generate_pdf(link: str, name: str):
|
|||
except Exception as e:
|
||||
log.error(f"Error generating PDF for {name}: {str(e)}", exc_info=True)
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
6
src/pif_compiler/functions/orders.py
Normal file
6
src/pif_compiler/functions/orders.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
from pymongo import MongoClient
|
||||
|
||||
from pif_compiler.functions.common_log import get_logger
|
||||
from pif_compiler.functions.db_utils import db_connect
|
||||
|
||||
log = get_logger()
|
||||
14
src/pif_compiler/services/srv_cir.py
Normal file
14
src/pif_compiler/services/srv_cir.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
from pif_compiler.functions.common_log import get_logger
|
||||
from pif_compiler.functions.db_utils import db_connect
|
||||
|
||||
log = get_logger()
|
||||
|
||||
def search_ingredient(text):
|
||||
col = db_connect(db_name="cir", collection_name="noael")
|
||||
col.create_index([("ingrediente", "text")])
|
||||
log.info(f"Searching for ingredient in CIR database: {text}")
|
||||
risultati = col.find({ "$text": { "$search": text } })
|
||||
return list(risultati)
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in a new issue