Skip to content

Commit

Permalink
Merge pull request #407 from noharm-ai/develop
Browse files Browse the repository at this point in the history
v4.06-beta
  • Loading branch information
marceloarocha authored Nov 4, 2024
2 parents 9463443 + 1515182 commit a743a33
Show file tree
Hide file tree
Showing 12 changed files with 734 additions and 462 deletions.
4 changes: 2 additions & 2 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@


class Config:
VERSION = "v4.05-beta"
FRONTEND_VERSION = "4.0.4"
VERSION = "v4.06-beta"
FRONTEND_VERSION = "4.0.5"
ENV = getenv("ENV") or NoHarmENV.DEVELOPMENT.value
SECRET_KEY = getenv("SECRET_KEY") or "secret_key"
API_KEY = getenv("API_KEY") or ""
Expand Down
32 changes: 32 additions & 0 deletions decorators/timed_decorator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import time
import logging
from functools import wraps

logging.basicConfig()
logger = logging.getLogger("noharm.performance")


def timed(warn=True):

def log_time_decorator(func):

@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()

duration = round(end - start, 2)

logger.debug("PERF: {} ran in {}s".format(func.__name__, duration))

if warn and duration > 2:
logger.warning(
"PERF_WARNING: {} ran in {}s".format(func.__name__, duration)
)

return result

return wrapper

return log_time_decorator
4 changes: 4 additions & 0 deletions mobile.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@
logging.basicConfig()
logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)
logging.getLogger("noharm.backend").setLevel(logging.DEBUG)
logging.getLogger("noharm.performance").setLevel(logging.DEBUG)

if Config.ENV == NoHarmENV.DEVELOPMENT.value:
logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING)


@app.route("/version", methods=["GET"])
Expand Down
1 change: 1 addition & 0 deletions models/prescription.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ def findByPrescription(
Prescription.date.label("prescription_date"),
MeasureUnitConvert.factor.label("measure_unit_convert_factor"),
func.array(substance_handling).label("substance_handling_types"),
Prescription.idDepartment.label("idDepartment"),
)
.outerjoin(Outlier, Outlier.id == PrescriptionDrug.idOutlier)
.outerjoin(Drug, Drug.id == PrescriptionDrug.idDrug)
Expand Down
14 changes: 12 additions & 2 deletions routes/static.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
from datetime import datetime

from models.main import db, User
from services import prescription_agg_service, prescription_check_service
from services import (
prescription_agg_service,
prescription_check_service,
)
from exception.validation_error import ValidationError
from exception.authorization_error import AuthorizationError
from utils import status, sessionutils
Expand All @@ -21,6 +24,7 @@ def create_aggregated_by_prescription(schema, id_prescription):
force = request.args.get("force", False)

user_context = User()
user_context.schema = schema
user_context.config = {"roles": ["STATIC_USER"]}
g.user_context = user_context
g.is_cpoe = bool(is_cpoe)
Expand All @@ -31,10 +35,13 @@ def create_aggregated_by_prescription(schema, id_prescription):
id_prescription=id_prescription,
out_patient=out_patient,
force=force,
user_context=user_context,
)
except ValidationError as e:
db.session.rollback()
return {"status": "error", "message": str(e), "code": e.code}, e.httpStatus
except AuthorizationError as e:
db.session.rollback()
return {
"status": "error",
"message": "Usuário inválido",
Expand All @@ -57,17 +64,20 @@ def create_aggregated_prescription_by_date(schema, admission_number):
)

user_context = User()
user_context.schema = schema
user_context.config = {"roles": ["STATIC_USER"]}
g.user_context = user_context
g.is_cpoe = bool(is_cpoe)

try:
prescription_agg_service.create_agg_prescription_by_date(
schema, admission_number, p_date
schema, admission_number, p_date, user_context=user_context
)
except ValidationError as e:
db.session.rollback()
return {"status": "error", "message": str(e), "code": e.code}, e.httpStatus
except AuthorizationError as e:
db.session.rollback()
return {
"status": "error",
"message": "Usuário inválido",
Expand Down
18 changes: 18 additions & 0 deletions services/cache_service.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import logging
import time
import json
from redis.exceptions import TimeoutError

from models.main import redis_client
Expand All @@ -14,3 +16,19 @@ def get_by_key(key: str):
f"redis timeout error: {key}",
)
return None


def get_range(key: str, days_ago: int):
now = time.time()
min_date = now - (days_ago * 24 * 60 * 60)

cache_data = redis_client.zrangebyscore(key, min=min_date, max=now)

if cache_data:
result = []
for i in cache_data:
result.append(json.loads(i))

return result

return None
59 changes: 57 additions & 2 deletions services/clinical_notes_queries_service.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from sqlalchemy import func, desc
from sqlalchemy import func, desc, Integer
from datetime import datetime, timedelta

from models.main import db, User
from models.notes import ClinicalNotes
from services import cache_service
from services import cache_service, clinical_notes_service


def get_signs(admission_number: int, user_context: User, cache=True):
Expand Down Expand Up @@ -130,3 +130,58 @@ def get_dialysis(admission_number):
.order_by(desc("date"))
.all()
)


def get_admission_stats(admission_number: int, user_context: User, cache=True):
tags = clinical_notes_service.get_tags()
stats = {}

if cache:
result = cache_service.get_range(
key=f"""{user_context.schema}:{admission_number}:stats""", days_ago=6
)

total_counts = {}
if result != None:
for i in result:
cache_stats = i.get("lista", [])

for count_key, count_value in cache_stats.items():
total_counts[count_key] = (
total_counts.get(count_key, 0) + count_value
)

for tag in tags:
stats[tag["key"]] = total_counts[tag["name"] + "_count"]

return stats

q_stats = db.session.query().select_from(ClinicalNotes)

for tag in tags:
stats[tag["key"]] = 0

q_stats = q_stats.add_columns(
func.sum(
func.cast(
func.coalesce(
ClinicalNotes.annotations[tag["name"] + "_count"].astext, "0"
),
Integer,
)
).label(tag["key"])
)

q_stats = (
q_stats.filter(ClinicalNotes.admissionNumber == admission_number)
.filter(ClinicalNotes.isExam == None)
.filter(ClinicalNotes.date > (datetime.today() - timedelta(days=6)))
)

stats_result = q_stats.first()

if stats_result:
for tag in tags:
stats[tag["key"]] = getattr(stats_result, tag["key"])

return stats
34 changes: 0 additions & 34 deletions services/clinical_notes_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,40 +320,6 @@ def get_user_last_clinical_notes(admission_number: int):
return None


def get_admission_stats(admission_number: int):
tags = get_tags()
stats = {}
q_stats = db.session.query().select_from(ClinicalNotes)

for tag in tags:
stats[tag["key"]] = 0

q_stats = q_stats.add_columns(
func.sum(
func.cast(
func.coalesce(
ClinicalNotes.annotations[tag["name"] + "_count"].astext, "0"
),
Integer,
)
).label(tag["key"])
)

q_stats = (
q_stats.filter(ClinicalNotes.admissionNumber == admission_number)
.filter(ClinicalNotes.isExam == None)
.filter(ClinicalNotes.date > (datetime.today() - timedelta(days=6)))
)

stats_result = q_stats.first()

if stats_result:
for tag in tags:
stats[tag["key"]] = getattr(stats_result, tag["key"])

return stats


def get_count(admission_number: int, admission_date: datetime) -> int:
cutoff_date = (
datetime.today() - timedelta(days=120)
Expand Down
58 changes: 26 additions & 32 deletions services/prescription_agg_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

@has_permission(Permission.READ_STATIC)
def create_agg_prescription_by_prescription(
schema, id_prescription, out_patient, force=False
schema, id_prescription, out_patient, user_context: User, force=False
):
_set_schema(schema)

Expand All @@ -54,10 +54,10 @@ def create_agg_prescription_by_prescription(
if not force and processed_status == "PROCESSED":
return

resultPresc = prescription_view_service.static_get_prescription(
idPrescription=id_prescription
prescription_data = prescription_view_service.static_get_prescription(
id_prescription=id_prescription, user_context=user_context
)
p.features = prescriptionutils.getFeatures(resultPresc)
p.features = prescriptionutils.getFeatures(prescription_data)
p.aggDrugs = p.features["drugIDs"]
p.aggDeps = [p.idDepartment]

Expand Down Expand Up @@ -104,10 +104,16 @@ def create_agg_prescription_by_prescription(
pAgg.update = datetime.today()
db.session.flush()

resultAgg = prescription_view_service.static_get_prescription(
idPrescription=pAgg.id
agg_data = prescription_view_service.static_get_prescription(
id_prescription=pAgg.id, user_context=user_context
)

pAgg.features = prescriptionutils.getFeatures(
result=agg_data, agg_date=pAgg.date, intervals_for_agg_date=True
)
pAgg.aggDrugs = pAgg.features["drugIDs"]
pAgg.aggDeps = pAgg.features["departmentList"]

if p.concilia is None and (pAgg.status == "s" or p.status == "s"):
prescalc_user = User()
prescalc_user.id = 0
Expand Down Expand Up @@ -147,20 +153,13 @@ def create_agg_prescription_by_prescription(
prescription=p, user=prescalc_user, extra={"prescalc": True}
)

if "idPrescription" in resultAgg:
pAgg.features = prescriptionutils.getFeatures(
resultAgg, agg_date=pAgg.date, intervals_for_agg_date=True
)
pAgg.aggDrugs = pAgg.features["drugIDs"]
pAgg.aggDeps = list(
set([resultAgg["headers"][h]["idDepartment"] for h in resultAgg["headers"]])
)

_log_processed_date(id_prescription_array=[id_prescription], schema=schema)


@has_permission(Permission.READ_STATIC)
def create_agg_prescription_by_date(schema, admission_number, p_date):
def create_agg_prescription_by_date(
schema, admission_number, p_date, user_context: User
):
_set_schema(schema)

last_prescription = get_last_prescription(admission_number)
Expand All @@ -176,7 +175,7 @@ def create_agg_prescription_by_date(schema, admission_number, p_date):
admission_number, last_prescription.idSegment, p_date
)

agg_p = db.session.query(Prescription).get(p_id)
agg_p = db.session.query(Prescription).filter(Prescription.id == p_id).first()

if agg_p is None:
agg_p = Prescription()
Expand All @@ -196,25 +195,20 @@ def create_agg_prescription_by_date(schema, admission_number, p_date):
agg_p.update = datetime.today()
db.session.add(agg_p)

resultAgg = prescription_view_service.static_get_prescription(
idPrescription=agg_p.id
agg_data = prescription_view_service.static_get_prescription(
id_prescription=agg_p.id, user_context=user_context
)

if "idPrescription" in resultAgg:
agg_p.update = datetime.today()
agg_p.features = prescriptionutils.getFeatures(resultAgg)
agg_p.aggDrugs = agg_p.features["drugIDs"]
agg_p.aggDeps = list(
set([resultAgg["headers"][h]["idDepartment"] for h in resultAgg["headers"]])
)
agg_p.update = datetime.today()
agg_p.features = prescriptionutils.getFeatures(result=agg_data)
agg_p.aggDrugs = agg_p.features["drugIDs"]
agg_p.aggDeps = agg_p.features["departmentList"]

internal_prescription_ids = []
for h in resultAgg["headers"]:
internal_prescription_ids.append(h)
internal_prescription_ids = internal_prescription_ids = (
prescriptionutils.get_internal_prescription_ids(result=agg_data)
)

_log_processed_date(
id_prescription_array=internal_prescription_ids, schema=schema
)
_log_processed_date(id_prescription_array=internal_prescription_ids, schema=schema)


def _log_processed_date(id_prescription_array, schema):
Expand Down
Loading

0 comments on commit a743a33

Please sign in to comment.