Skip to content

Commit

Permalink
add python code
Browse files Browse the repository at this point in the history
Co-authored-by: andrewelamb <[email protected]>
  • Loading branch information
tschaffter and andrewelamb committed Mar 11, 2024
1 parent 90d3a13 commit 9ce7706
Show file tree
Hide file tree
Showing 156 changed files with 8,932 additions and 24 deletions.
29 changes: 6 additions & 23 deletions apps/iatlas/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,25 +1,8 @@
FROM python:3.10.13
# Start with a bare Alpine Linux to keep the container image small
FROM tiangolo/uwsgi-nginx-flask:python3.8

# RUN apt-get -y update && apt-get -y install \
# wget && \
# # Install the GPG key for the Postgres repo
# wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \
# # Add the repo
# echo "deb http://apt.postgresql.org/pub/repos/apt/ bookworm-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list && \
# apt-get -y update && \
# # Install the Postgres 12 client
# apt-get -y install postgresql-client-12
WORKDIR /app
COPY . /app

# COPY requirements.txt requirements.txt
COPY src/ /src

# RUN pip3 install -r requirements.txt

WORKDIR /
COPY docker-entrypoint.sh ./
RUN chmod +x docker-entrypoint.sh

ENTRYPOINT ["/docker-entrypoint.sh"]

# Set up the iAtlas database
# CMD python /src/build_database.py
# Install the PyPI dependencies using pip
RUN pip3 install --no-cache-dir -r requirements.txt
55 changes: 55 additions & 0 deletions apps/iatlas/api/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import logging
from json import loads
from datetime import datetime as dt
from flask import Flask, request
from config import get_config
from .extensions import db, logs


def create_app(test=False):
config = get_config(test=test)
app = Flask(__name__)
app.config.from_object(config)

register_extensions(app)

# Blueprint registration here.
from .main import bp as main_bp
app.register_blueprint(main_bp)

@app.after_request
def after_request(response):
""" Logging after every POST request only if it isn't an introspection query. """
json_data = request.get_json()
is_introspection_query = bool(json_data and json_data.get(
'operationName', False) == 'IntrospectionQuery')
if request.method == 'POST' and not is_introspection_query:
logger = logging.getLogger('api.access')
logger.info(
'%s [%s] %s %s %s %s %s %s %s',
request.remote_addr,
dt.utcnow().strftime('%d/%b/%Y:%H:%M:%S.%f')[:-3],
request.method,
request.path,
request.scheme,
response.status,
response.content_length,
request.referrer,
request.user_agent,
)
return response

@ app.teardown_appcontext
def shutdown_session(exception=None):
db.session.remove()

return app


def register_extensions(app):
db.init_app(app)
logs.init_app(app)
return None


from api import db_models
27 changes: 27 additions & 0 deletions apps/iatlas/api/api/database/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from .cohort_queries import *
from .cohort_to_feature_queries import *
from .cohort_to_gene_queries import *
from .cohort_to_mutation_queries import *
from .cohort_to_sample_queries import *
from .cohort_to_tag_queries import *
from .dataset_queries import *
from .dataset_to_sample_queries import *
from .dataset_to_tag_queries import *
from .edge_queries import *
from .feature_queries import *
from .feature_to_sample_queries import *
from .gene_queries import *
from .gene_to_sample_queries import *
from .gene_to_gene_set_queries import *
from .mutation_queries import *
from .node_queries import *
from .patient_queries import *
from .publication_queries import *
from .publication_to_gene_to_gene_set_queries import *
from .result_queries import *
from .sample_to_mutation_queries import *
from .sample_to_tag_queries import *
from .snp_queries import *
from .tag_queries import *
from .tag_to_publication_queries import *
from .tag_to_tag_queries import *
16 changes: 16 additions & 0 deletions apps/iatlas/api/api/database/cohort_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from sqlalchemy import orm
from api import db
from .database_helpers import build_general_query
from api.db_models import Cohort

cohort_related_fields = ['data_set', 'tag',
'samples', 'features', 'mutations', 'genes']

cohort_core_fields = ['id', 'name', 'dataset_id', 'tag_id']


def return_cohort_query(*args):
return build_general_query(
Cohort, args=args,
accepted_option_args=cohort_related_fields,
accepted_query_args=cohort_core_fields)
16 changes: 16 additions & 0 deletions apps/iatlas/api/api/database/cohort_to_feature_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from sqlalchemy import orm
from api import db
from api.db_models import CohortToFeature
from .database_helpers import build_general_query

accepted_cohort_to_feature_option_args = ['cohort', 'feature']

accepted_cohort_to_feature_query_args = [
'cohort_id', 'feature_id']


def return_cohort_to_feature_query(*args):
return build_general_query(
CohortToFeature, args=args,
accepted_option_args=accepted_cohort_to_feature_option_args,
accepted_query_args=accepted_cohort_to_feature_query_args)
16 changes: 16 additions & 0 deletions apps/iatlas/api/api/database/cohort_to_gene_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from sqlalchemy import orm
from api import db
from api.db_models import CohortToGene
from .database_helpers import build_general_query

accepted_cohort_to_gene_option_args = ['cohort', 'gene']

accepted_cohort_to_gene_query_args = [
'cohort_id', 'gene_id']


def return_cohort_to_gene_query(*args):
return build_general_query(
CohortToGene, args=args,
accepted_option_args=accepted_cohort_to_gene_option_args,
accepted_query_args=accepted_cohort_to_gene_query_args)
16 changes: 16 additions & 0 deletions apps/iatlas/api/api/database/cohort_to_mutation_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from sqlalchemy import orm
from api import db
from api.db_models import CohortToMutation
from .database_helpers import build_general_query

accepted_cohort_to_mutation_option_args = ['cohort', 'mutation']

accepted_cohort_to_mutation_query_args = [
'cohort_id', 'mutation_id']


def return_cohort_to_mutation_query(*args):
return build_general_query(
CohortToMutation, args=args,
accepted_option_args=accepted_cohort_to_mutation_option_args,
accepted_query_args=accepted_cohort_to_mutation_query_args)
16 changes: 16 additions & 0 deletions apps/iatlas/api/api/database/cohort_to_sample_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from sqlalchemy import orm
from api import db
from api.db_models import CohortToSample
from .database_helpers import build_general_query

accepted_cohort_to_sample_option_args = ['cohort', 'sample']

accepted_cohort_to_sample_query_args = [
'cohort_id', 'sample_id' 'tag_id']


def return_cohort_to_sample_query(*args):
return build_general_query(
CohortToSample, args=args,
accepted_option_args=accepted_cohort_to_sample_option_args,
accepted_query_args=accepted_cohort_to_sample_query_args)
16 changes: 16 additions & 0 deletions apps/iatlas/api/api/database/cohort_to_tag_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from sqlalchemy import orm
from api import db
from api.db_models import CohortToTag
from .database_helpers import build_general_query

accepted_cohort_to_tag_option_args = ['cohort', 'tag']

accepted_cohort_to_tag_query_args = [
'cohort_id', 'tag_id']


def return_cohort_to_tag_query(*args):
return build_general_query(
CohortToTag, args=args,
accepted_option_args=accepted_cohort_to_tag_option_args,
accepted_query_args=accepted_cohort_to_tag_query_args)
68 changes: 68 additions & 0 deletions apps/iatlas/api/api/database/database_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from sqlalchemy import orm
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import ClauseElement, Executable
from sqlalchemy.sql import Select
from sqlalchemy.dialects import postgresql

from api import db

general_core_fields = ['id', 'name']


def build_general_query(model, args=[], accepted_option_args=[], accepted_query_args=[]):
option_args = build_option_args(*args, accepted_args=accepted_option_args)
query_args = build_query_args(
model, *args, accepted_args=accepted_query_args)
query = db.session.query(*query_args)
if option_args:
# If option args are found, the whole model must be queried.
return db.session.query(model).options(*option_args)
return db.session.query(*query_args)


def build_option_args(*args, accepted_args=[]):
option_args = []
for arg in args:
if arg in accepted_args:
option_args.append(orm.joinedload(arg))
return option_args


def build_query_args(model, *argv, accepted_args=[]):
query_args = []
for arg in argv:
if arg in accepted_args:
query_args.append(getattr(model, arg))
if not query_args:
return [model]
return query_args

def temp_table(name, query):
e = db.session.get_bind()
c = e.connect()
trans = c.begin()
c.execute(CreateTableAs(name, query))
trans.commit()
return c

class CreateTableAs(Select):
def __init__(self, name, query, *arg, **kw):
super(CreateTableAs, self).__init__(None, *arg, **kw)
self.name = name
self.query = query

@compiles(CreateTableAs)
def _create_table_as(element, compiler, **kw):
text = element.query.statement.compile(dialect=postgresql.dialect(), compile_kwargs={'literal_binds': True})
query = "CREATE TEMP TABLE %s AS %s" % (
element.name,
text
)
return query

def execute_sql(query, conn=None):
if conn:
return conn.execute(query)
engine = db.session.get_bind()
with engine.connect() as conn:
return conn.execute(query)
16 changes: 16 additions & 0 deletions apps/iatlas/api/api/database/dataset_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from sqlalchemy import orm
from api import db
from api.db_models import Dataset
from .database_helpers import general_core_fields, build_general_query

dataset_related_fields = [
'dataset_sample_assoc', 'dataset_tag_assoc', 'samples', 'tags']

dataset_core_fields = ['id', 'name', 'display', 'dataset_type']


def return_dataset_query(*args, model=Dataset):
return build_general_query(
model, args=args,
accepted_option_args=dataset_related_fields,
accepted_query_args=dataset_core_fields)
15 changes: 15 additions & 0 deletions apps/iatlas/api/api/database/dataset_to_sample_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from sqlalchemy import orm
from api import db
from api.db_models import DatasetToSample
from .database_helpers import build_general_query

related_fields = ['data_sets', 'samples']

core_fields = ['dataset_id', 'sample_id']


def return_dataset_to_sample_query(*args):
return build_general_query(
DatasetToSample, args=args,
accepted_option_args=related_fields,
accepted_query_args=core_fields)
15 changes: 15 additions & 0 deletions apps/iatlas/api/api/database/dataset_to_tag_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from sqlalchemy import orm
from api import db
from api.db_models import DatasetToTag
from .database_helpers import build_general_query

related_fields = ['data_sets', 'tags']

core_fields = ['dataset_id', 'tag_id']


def return_dataset_to_tag_query(*args):
return build_general_query(
DatasetToTag, args=args,
accepted_option_args=related_fields,
accepted_query_args=core_fields)
15 changes: 15 additions & 0 deletions apps/iatlas/api/api/database/edge_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from sqlalchemy import orm
from api import db
from api.db_models import Edge
from .database_helpers import build_general_query

accepted_option_args = ['node_1', 'node_2']

accepted_query_args = ['id', 'node_1_id',
'node_2_id', 'name', 'label', 'score']


def return_edge_query(*args):
return build_general_query(
Edge, args=args, accepted_option_args=accepted_option_args,
accepted_query_args=accepted_query_args)
17 changes: 17 additions & 0 deletions apps/iatlas/api/api/database/feature_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from sqlalchemy import orm
from api import db
from api.db_models import Feature
from .database_helpers import general_core_fields, build_general_query

feature_related_fields = [
'copy_number_results', 'driver_results',
'feature_sample_assoc', 'samples']

feature_core_fields = [
'id', 'name', 'display', 'order', 'unit', 'feature_class', 'method_tag', 'germline_category', 'germline_module']

def return_feature_query(*args):
return build_general_query(
Feature, args=args,
accepted_option_args=feature_related_fields,
accepted_query_args=feature_core_fields)
15 changes: 15 additions & 0 deletions apps/iatlas/api/api/database/feature_to_sample_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from sqlalchemy import orm
from api import db
from api.db_models import FeatureToSample
from .database_helpers import build_general_query

related_fields = ['features', 'samples']

core_fields = ['feature_id', 'sample_id', 'value']


def return_feature_to_sample_query(*args):
return build_general_query(
FeatureToSample, args=args,
accepted_option_args=related_fields,
accepted_query_args=core_fields)
Loading

0 comments on commit 9ce7706

Please sign in to comment.