can request and display some data in json format
parent
57529ee595
commit
3e65b9fbdd
@ -0,0 +1,50 @@
|
||||
from flask import (Flask,render_template)
|
||||
import os
|
||||
from .db_interface import get_connection_details, check_connection
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def create_app(test_config=None):
|
||||
# create and configure the app
|
||||
app = Flask(__name__, instance_relative_config=True)
|
||||
app.config.from_mapping(
|
||||
SECRET_KEY='6e674d6e41b733270fd01c6257b3a1b4769eb80f3f773cd0fe8eff25f350fc1f',
|
||||
POSTGRES_DB="aact_db",
|
||||
POSTGRES_USER="root",
|
||||
POSTGRES_HOST="localhost",
|
||||
POSTGRES_PORT=5432,
|
||||
POSTGRES_PASSWORD="root",
|
||||
)
|
||||
|
||||
|
||||
# ensure the instance folder exists
|
||||
try:
|
||||
os.makedirs(app.instance_path)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# a simple page that says hello
|
||||
@app.route('/')
|
||||
def hello():
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
@app.route('/debug')
|
||||
def debug_info():
|
||||
return {
|
||||
"connection": get_connection_details(),
|
||||
}
|
||||
|
||||
|
||||
|
||||
from . import db_interface
|
||||
#db_interface.check_connection(app)
|
||||
|
||||
from . import formularies_matching
|
||||
app.register_blueprint(formularies_matching.bp)
|
||||
|
||||
|
||||
return app
|
||||
@ -0,0 +1,83 @@
|
||||
import psycopg as psyco
|
||||
from datetime import datetime
|
||||
from flask import current_app,g
|
||||
|
||||
|
||||
def get_db(**kwargs):
|
||||
|
||||
if "db" not in g:
|
||||
g.db = psyco.connect(
|
||||
dbname=current_app.config["POSTGRES_DB"]
|
||||
,user=current_app.config["POSTGRES_USER"]
|
||||
,host=current_app.config["POSTGRES_HOST"]
|
||||
,port=current_app.config["POSTGRES_PORT"]
|
||||
,password=current_app.config["POSTGRES_PASSWORD"]
|
||||
,**kwargs
|
||||
)
|
||||
return g.db
|
||||
|
||||
def close_db(e=None):
|
||||
db = g.pop('db', None)
|
||||
|
||||
if db is not None:
|
||||
db.close()
|
||||
|
||||
def get_connection_details():
|
||||
return {
|
||||
"dbname":current_app.config["POSTGRES_DB"]
|
||||
,"user":current_app.config["POSTGRES_USER"]
|
||||
,"host":current_app.config["POSTGRES_HOST"]
|
||||
,"port":current_app.config["POSTGRES_PORT"]
|
||||
,"password":current_app.config["POSTGRES_PASSWORD"]
|
||||
}
|
||||
|
||||
def check_connection(app):
|
||||
db = get_db()
|
||||
with db.cursor() as curse:
|
||||
curse.execute("select count(*) from \"DiseaseBurden\".trial_to_icd10")
|
||||
curse.fetchall()
|
||||
#just checking if everything is going to fail
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def get_trial_summary(db_conn,nct_id):
|
||||
sql_summary ="""
|
||||
select
|
||||
s.nct_id,
|
||||
brief_title ,
|
||||
official_title ,
|
||||
bs.description as brief_description,
|
||||
dd.description as detailed_description
|
||||
from ctgov.studies s
|
||||
left join ctgov.brief_summaries bs
|
||||
on bs.nct_id = s.nct_id
|
||||
left join ctgov.detailed_descriptions dd
|
||||
on dd.nct_id = s.nct_id
|
||||
where s.nct_id = %s
|
||||
;
|
||||
"""
|
||||
sql_conditions="""
|
||||
--conditions mentioned
|
||||
select * from ctgov.conditions c
|
||||
where c.nct_id = %s
|
||||
;
|
||||
"""
|
||||
sql_keywords="""
|
||||
select nct_id ,downcase_name
|
||||
from ctgov.keywords k
|
||||
where k.nct_id = %s
|
||||
;
|
||||
"""
|
||||
with db_conn.cursor() as curse:
|
||||
curse.execute(sql_summary,[nct_id])
|
||||
summary = curse.fetchall()
|
||||
|
||||
curse.execute(sql_keywords,[nct_id])
|
||||
keywords = curse.fetchall()
|
||||
|
||||
curse.execute(sql_conditions,[nct_id])
|
||||
conditions = curse.fetchall()
|
||||
|
||||
return {"summary":summary, "keywords":keywords, "conditions":conditions}
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
import psycopg as psyco
|
||||
from datetime import datetime
|
||||
|
||||
from flask import current_app, g
|
||||
|
||||
|
||||
|
||||
|
||||
def get_all_formulary_groups(db_conn):
|
||||
'''
|
||||
Get the list of active formulary groups
|
||||
TODO: IMplement for the given formulary
|
||||
'''
|
||||
pass
|
||||
|
||||
def get_formulary_groups_per_NCTID(db_conn, nct_id):
|
||||
'''
|
||||
Get the list of formulary groups associated with
|
||||
the drugs found in a trial identified by NCTID
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
def store_trial_to_formulary_group_matches():
|
||||
pass
|
||||
@ -0,0 +1,47 @@
|
||||
import functools
|
||||
from flask import (Blueprint, flash, g, redirect, render_template, request, session, url_for)
|
||||
from datetime import datetime
|
||||
|
||||
from FormulariesMatching.db_interface import (
|
||||
get_db,
|
||||
get_connection_details,
|
||||
get_trial_summary,
|
||||
)
|
||||
|
||||
|
||||
|
||||
#setup blueprint
|
||||
bp = Blueprint("formularies validation", __name__, url_prefix='/link/formularies')
|
||||
|
||||
@bp.route("/", methods=['GET'])
|
||||
def get_remaining():
|
||||
#get db connection
|
||||
#db_conn = get_db()
|
||||
|
||||
#get required data
|
||||
connection_valid = get_connection_details()
|
||||
|
||||
#return html
|
||||
return connection_valid
|
||||
|
||||
|
||||
@bp.route("/<nct_id>", methods=['GET',"POST"])
|
||||
def match_trial_to_formulary_groups(nct_id):
|
||||
#get db connection
|
||||
db_conn = get_db()
|
||||
|
||||
if request.method == "GET":
|
||||
pass
|
||||
#get list of potential matches for each of the formularies
|
||||
#get trial summary
|
||||
summary = get_trial_summary(db_conn,nct_id)
|
||||
|
||||
#render template
|
||||
return summary
|
||||
|
||||
elif request.method == "POST":
|
||||
pass
|
||||
#build array of data to insert
|
||||
|
||||
else:
|
||||
pass
|
||||
@ -0,0 +1,175 @@
|
||||
import psycopg2 as psyco
|
||||
from psycopg2 import extras
|
||||
from datetime import datetime
|
||||
|
||||
import click #used for cli commands. Not needed for what I am doing.
|
||||
from flask import current_app, g
|
||||
|
||||
def get_db(**kwargs):
|
||||
|
||||
if "db" not in g:
|
||||
g.db = psyco.connect(
|
||||
dbname=current_app.config["POSTGRES_DB"]
|
||||
,user=current_app.config["POSTGRES_USER"]
|
||||
,host=current_app.config["POSTGRES_HOST"]
|
||||
,port=current_app.config["POSTGRES_PORT"]
|
||||
,password=current_app.config["POSTGRES_PASSWORD"]
|
||||
,**kwargs
|
||||
)
|
||||
return g.db
|
||||
|
||||
def close_db(e=None):
|
||||
db = g.pop('db', None)
|
||||
|
||||
if db is not None:
|
||||
db.close()
|
||||
|
||||
def check_initialization(app):
|
||||
db = get_db()
|
||||
with db.cursor() as curse:
|
||||
curse.execute("select count(*) from \"DiseaseBurden\".trial_to_icd10")
|
||||
curse.fetchall()
|
||||
#just checking if everything is going to fail
|
||||
|
||||
def init_database(app):
|
||||
#check_initialization(app)
|
||||
app.teardown_appcontext(close_db)
|
||||
|
||||
|
||||
|
||||
|
||||
def select_remaing_trials_to_analyze(db_conn):
|
||||
'''
|
||||
This will get the set of trials that need to be analyzed.
|
||||
'''
|
||||
sql = '''
|
||||
select distinct nct_id
|
||||
from "DiseaseBurden".trial_to_icd10 tti
|
||||
where tti.approved is null
|
||||
order by nct_id
|
||||
;
|
||||
'''
|
||||
with db_conn.cursor() as cursor:
|
||||
cursor.execute(sql)
|
||||
return cursor.fetchall()
|
||||
|
||||
|
||||
def select_analyzed_trials(db_conn):
|
||||
'''
|
||||
This will get the set of trials that have been analyzed.
|
||||
'''
|
||||
sql = '''
|
||||
select distinct nct_id, max(approval_timestamp)
|
||||
from "DiseaseBurden".trial_to_icd10 tti
|
||||
where tti.approved in ('accepted','rejected')
|
||||
group by nct_id
|
||||
order by max(approval_timestamp) desc
|
||||
;
|
||||
'''
|
||||
with db_conn.cursor() as cursor:
|
||||
cursor.execute(sql)
|
||||
return cursor.fetchall()
|
||||
|
||||
def select_unmatched_trials(db_conn):
|
||||
'''
|
||||
This will get the set of trials that have been analyzed.
|
||||
'''
|
||||
sql = '''
|
||||
select distinct nct_id
|
||||
from "DiseaseBurden".trial_to_icd10 tti
|
||||
where tti.approved = 'unmatched'
|
||||
order by nct_id
|
||||
;
|
||||
'''
|
||||
with db_conn.cursor() as cursor:
|
||||
cursor.execute(sql)
|
||||
return cursor.fetchall()
|
||||
|
||||
|
||||
def get_trial_conditions_and_proposed_matches(db_conn, nct_id):
|
||||
sql = '''
|
||||
select *
|
||||
from "DiseaseBurden".trial_to_icd10 tti
|
||||
where nct_id = %s
|
||||
'''
|
||||
with db_conn.cursor() as cursor:
|
||||
cursor.execute(sql,[nct_id])
|
||||
return cursor.fetchall()
|
||||
|
||||
|
||||
def store_validation(db_conn, list_of_insert_data):
|
||||
sql = """
|
||||
update "DiseaseBurden".trial_to_icd10
|
||||
set approved=%s, approval_timestamp=%s
|
||||
where id=%s
|
||||
;
|
||||
"""
|
||||
with db_conn.cursor() as cursor:
|
||||
for l in list_of_insert_data:
|
||||
cursor.execute(sql, l)
|
||||
db_conn.commit()
|
||||
|
||||
def get_trial_summary(db_conn,nct_id):
|
||||
sql_summary ="""
|
||||
select
|
||||
s.nct_id,
|
||||
brief_title ,
|
||||
official_title ,
|
||||
bs.description as brief_description,
|
||||
dd.description as detailed_description
|
||||
from ctgov.studies s
|
||||
left join ctgov.brief_summaries bs
|
||||
on bs.nct_id = s.nct_id
|
||||
left join ctgov.detailed_descriptions dd
|
||||
on dd.nct_id = s.nct_id
|
||||
where s.nct_id = %s
|
||||
;
|
||||
"""
|
||||
sql_conditions="""
|
||||
--conditions mentioned
|
||||
select * from ctgov.conditions c
|
||||
where c.nct_id = %s
|
||||
;
|
||||
"""
|
||||
sql_keywords="""
|
||||
select nct_id ,downcase_name
|
||||
from ctgov.keywords k
|
||||
where k.nct_id = %s
|
||||
;
|
||||
"""
|
||||
with db_conn.cursor() as curse:
|
||||
curse.execute(sql_summary,[nct_id])
|
||||
summary = curse.fetchall()
|
||||
|
||||
curse.execute(sql_keywords,[nct_id])
|
||||
keywords = curse.fetchall()
|
||||
|
||||
curse.execute(sql_conditions,[nct_id])
|
||||
conditions = curse.fetchall()
|
||||
|
||||
return {"summary":summary, "keywords":keywords, "conditions":conditions}
|
||||
|
||||
def get_list_icd10_codes(db_conn):
|
||||
sql = """
|
||||
select distinct code
|
||||
from "DiseaseBurden".icd10_to_cause itc
|
||||
order by code;
|
||||
"""
|
||||
with db_conn.cursor() as curse:
|
||||
curse.execute(sql)
|
||||
codes = curse.fetchall()
|
||||
|
||||
return [ x[0] for x in codes ]
|
||||
|
||||
def record_suggested_matches(db_conn, nct_id,condition,icd10_code):
|
||||
sql1 = """
|
||||
INSERT INTO "DiseaseBurden".trial_to_icd10
|
||||
(nct_id,"condition",ui,"source",approved,approval_timestamp)
|
||||
VALUES (%s,%s,%s,'hand matched','accepted',%s)
|
||||
;
|
||||
"""
|
||||
|
||||
|
||||
with db_conn.cursor() as curse:
|
||||
curse.execute(sql1,[nct_id,condition,icd10_code,datetime.now()])
|
||||
db_conn.commit()
|
||||
Binary file not shown.
@ -0,0 +1,22 @@
|
||||
<!doctype html>
|
||||
<title>{% block title %}{% endblock %} - ClinicalTrialsProject</title>
|
||||
<!--<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">-->
|
||||
|
||||
<nav>
|
||||
<h1>Nav</h1>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ url_for('hello') }}">Linking Home</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ url_for('formularies validation.get_remaining') }}">Linking Formularies</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<section class="content">
|
||||
<header>
|
||||
{% block header %}{% endblock %}
|
||||
</header>
|
||||
{% block content %}{% endblock %}
|
||||
</section>
|
||||
@ -0,0 +1,49 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block header %}
|
||||
<h1>{% block title %} ICD-10 to Trial Conditions Validation {% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h2>Trials to Validate</h2>
|
||||
|
||||
<table>
|
||||
<th>Trials</th>
|
||||
{% for trial in list_to_validate %}
|
||||
<tr><td>
|
||||
<a href="{{ url_for('.validate_trial', nct_id=trial[0] ) }}">
|
||||
{{ trial [0] }}
|
||||
</a>
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<h2>Trials that have been Validated</h2>
|
||||
|
||||
<table>
|
||||
<th>Trials Links</th>
|
||||
{% for trial in validated_list %}
|
||||
<tr><td>
|
||||
<a href="{{ url_for('.validate_trial', nct_id=trial[0] ) }}">
|
||||
{{ trial [0] }}
|
||||
</a>
|
||||
(Most recently updated {{trial[1]}})
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<h2>Trials that don't have a good match</h2>
|
||||
|
||||
<table>
|
||||
<th>Trial Links</th>
|
||||
{% for trial in unmatched_list %}
|
||||
<tr><td>
|
||||
<a href="{{ url_for('.validate_trial', nct_id=trial[0] ) }}">
|
||||
{{ trial [0] }}
|
||||
</a>
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
@ -0,0 +1,49 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block header %}
|
||||
<h1>{% block title %} ICD-10 to Trial Conditions Validation {% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h2>Trials to Validate</h2>
|
||||
|
||||
<table>
|
||||
<th>Trials</th>
|
||||
{% for trial in list_to_validate %}
|
||||
<tr><td>
|
||||
<a href="{{ url_for('.validate_trial', nct_id=trial[0] ) }}">
|
||||
{{ trial [0] }}
|
||||
</a>
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<h2>Trials that have been Validated</h2>
|
||||
|
||||
<table>
|
||||
<th>Trials Links</th>
|
||||
{% for trial in validated_list %}
|
||||
<tr><td>
|
||||
<a href="{{ url_for('.validate_trial', nct_id=trial[0] ) }}">
|
||||
{{ trial [0] }}
|
||||
</a>
|
||||
(Most recently updated {{trial[1]}})
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
<h2>Trials that don't have a good match</h2>
|
||||
|
||||
<table>
|
||||
<th>Trial Links</th>
|
||||
{% for trial in unmatched_list %}
|
||||
<tr><td>
|
||||
<a href="{{ url_for('.validate_trial', nct_id=trial[0] ) }}">
|
||||
{{ trial [0] }}
|
||||
</a>
|
||||
</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
||||
@ -0,0 +1,24 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block header %}
|
||||
<h1>
|
||||
{% block title %}
|
||||
Formulary Matching
|
||||
{% endblock %}
|
||||
</h1>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
This is the home page for matching things to clinical trials
|
||||
|
||||
There are a few major efforts related to matching.
|
||||
|
||||
The first is to match trials to IDC10 codes
|
||||
|
||||
The second is to link trials to formulary groups.
|
||||
|
||||
{% endblock %}
|
||||
@ -0,0 +1,6 @@
|
||||
flask
|
||||
psycopg[binary]
|
||||
datetime
|
||||
watchdog
|
||||
waitress
|
||||
python-dotenv
|
||||
@ -0,0 +1,12 @@
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
name='FormulariesMatching',
|
||||
packages=['FormulariesMatching'],
|
||||
include_package_data=True,
|
||||
install_requires=[
|
||||
'flask',
|
||||
'psycopg[binary]',
|
||||
'datetime',
|
||||
],
|
||||
)
|
||||
@ -0,0 +1 @@
|
||||
waitress-serve --port=5000 --call 'Icd10ConditionsMatching:create_app'
|
||||
Loading…
Reference in New Issue