Skip to content

Commit

Permalink
Merge pull request #38 from nleroy917/hotfix-sdk
Browse files Browse the repository at this point in the history
Fix Import Issues For PyPi Package
  • Loading branch information
nleroy917 authored Jul 7, 2022
2 parents 363c39d + 0c49619 commit 98e1aac
Show file tree
Hide file tree
Showing 29 changed files with 894 additions and 533 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/black.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: Lint

on: [pull_request]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: psf/black@stable
11 changes: 6 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
allow_headers=["*"],
)


@app.get("/")
async def root():
return {
'message': "Optipyzer codon optimization server. For more details see https://github.com/nleroy917/optipyzer",
'url': 'https://github.com/nleroy917/optipyzer',
'version': VERSION,
'fastapi_version': fastapi.__version__
}
"message": "Optipyzer codon optimization server. For more details see https://github.com/nleroy917/optipyzer",
"url": "https://github.com/nleroy917/optipyzer",
"version": VERSION,
"fastapi_version": fastapi.__version__,
}
124 changes: 86 additions & 38 deletions optipyzer/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,44 +26,92 @@
}

AMINO_ACID_LOOKUP = {
'ATA':'I', 'ATC':'I', 'ATT':'I', 'ATG':'M',
'ACA':'T', 'ACC':'T', 'ACG':'T', 'ACT':'T',
'AAC':'N', 'AAT':'N', 'AAA':'K', 'AAG':'K',
'AGC':'S', 'AGT':'S', 'AGA':'R', 'AGG':'R',
'CTA':'L', 'CTC':'L', 'CTG':'L', 'CTT':'L',
'CCA':'P', 'CCC':'P', 'CCG':'P', 'CCT':'P',
'CAC':'H', 'CAT':'H', 'CAA':'Q', 'CAG':'Q',
'CGA':'R', 'CGC':'R', 'CGG':'R', 'CGT':'R',
'GTA':'V', 'GTC':'V', 'GTG':'V', 'GTT':'V',
'GCA':'A', 'GCC':'A', 'GCG':'A', 'GCT':'A',
'GAC':'D', 'GAT':'D', 'GAA':'E', 'GAG':'E',
'GGA':'G', 'GGC':'G', 'GGG':'G', 'GGT':'G',
'TCA':'S', 'TCC':'S', 'TCG':'S', 'TCT':'S',
'TTC':'F', 'TTT':'F', 'TTA':'L', 'TTG':'L',
'TAC':'Y', 'TAT':'Y', 'TAA':'_', 'TAG':'_',
'TGC':'C', 'TGT':'C', 'TGA':'_', 'TGG':'W',
"ATA": "I",
"ATC": "I",
"ATT": "I",
"ATG": "M",
"ACA": "T",
"ACC": "T",
"ACG": "T",
"ACT": "T",
"AAC": "N",
"AAT": "N",
"AAA": "K",
"AAG": "K",
"AGC": "S",
"AGT": "S",
"AGA": "R",
"AGG": "R",
"CTA": "L",
"CTC": "L",
"CTG": "L",
"CTT": "L",
"CCA": "P",
"CCC": "P",
"CCG": "P",
"CCT": "P",
"CAC": "H",
"CAT": "H",
"CAA": "Q",
"CAG": "Q",
"CGA": "R",
"CGC": "R",
"CGG": "R",
"CGT": "R",
"GTA": "V",
"GTC": "V",
"GTG": "V",
"GTT": "V",
"GCA": "A",
"GCC": "A",
"GCG": "A",
"GCT": "A",
"GAC": "D",
"GAT": "D",
"GAA": "E",
"GAG": "E",
"GGA": "G",
"GGC": "G",
"GGG": "G",
"GGT": "G",
"TCA": "S",
"TCC": "S",
"TCG": "S",
"TCT": "S",
"TTC": "F",
"TTT": "F",
"TTA": "L",
"TTG": "L",
"TAC": "Y",
"TAT": "Y",
"TAA": "_",
"TAG": "_",
"TGC": "C",
"TGT": "C",
"TGA": "_",
"TGG": "W",
}

AA_CODON_LIBRARY = {
'A': ['GCT','GCC','GCA','GCG'],
'R': ['CGT','CGC','CGA','CGG','AGA','AGG'],
'N': ['AAT','AAC'],
'D': ['GAT','GAC'],
'C': ['TGT','TGC'],
'Q': ['CAA','CAG'],
'E': ['GAA','GAG'],
'G': ['GGT','GGC','GGA','GGG'],
'H': ['CAT','CAC'],
'I': ['ATT','ATC','ATA'],
'L': ['TTA','TTG','CTT','CTC','CTA','CTG'],
'K': ['AAA','AAG'],
'M': ['ATG'],
'F': ['TTT','TTC'],
'P': ['CCT','CCC','CCA','CCG'],
'S': ['TCT','TCC','TCA','TCG','AGT','AGC'],
'T': ['ACT','ACC','ACA','ACG'],
'W': ['TGG'],
'Y': ['TAT','TAC'],
'V': ['GTT','GTC','GTA','GTG'],
'Stop': ['TAA','TAG','TGA']
}
"A": ["GCT", "GCC", "GCA", "GCG"],
"R": ["CGT", "CGC", "CGA", "CGG", "AGA", "AGG"],
"N": ["AAT", "AAC"],
"D": ["GAT", "GAC"],
"C": ["TGT", "TGC"],
"Q": ["CAA", "CAG"],
"E": ["GAA", "GAG"],
"G": ["GGT", "GGC", "GGA", "GGG"],
"H": ["CAT", "CAC"],
"I": ["ATT", "ATC", "ATA"],
"L": ["TTA", "TTG", "CTT", "CTC", "CTA", "CTG"],
"K": ["AAA", "AAG"],
"M": ["ATG"],
"F": ["TTT", "TTC"],
"P": ["CCT", "CCC", "CCA", "CCG"],
"S": ["TCT", "TCC", "TCA", "TCG", "AGT", "AGC"],
"T": ["ACT", "ACC", "ACA", "ACG"],
"W": ["TGG"],
"Y": ["TAT", "TAC"],
"V": ["GTT", "GTC", "GTA", "GTG"],
"Stop": ["TAA", "TAG", "TGA"],
}
2 changes: 1 addition & 1 deletion optipyzer/db/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()
Base = declarative_base()
19 changes: 13 additions & 6 deletions optipyzer/db/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ def _get_db():
finally:
db.close()


def get_autocomplete_organisms():
"""Return list of organisms for the autocomplete component"""

with SessionLocal() as db:
return db.query(AutocompleteOrganism).all()


def calc_codon_usage(organism_id: int):
"""
Function to calculate the codon usage data for a given organism.
Function to calculate the codon usage data for a given organism.
The codon usage data in this context is the percentage that a particular
codon is used when coding for a particular amino acid.
Expand All @@ -48,7 +49,11 @@ def calc_codon_usage(organism_id: int):

# Check for data issues (Sometings codon usage data is low, and must be dealt with)
if sum_codons == 0:
print('Not enough codon data found... Skipping Organism {}'.format(organism_id))
print(
"Not enough codon data found... Skipping Organism {}".format(
organism_id
)
)
break

# define index or and new sub-dictionary
Expand All @@ -69,7 +74,7 @@ def calc_codon_usage(organism_id: int):
for codon in codon_usage[aa]:
codon_usage[aa][codon] /= sum_codons

return counts, codon_usage # Return this dictionary of dictiomaries
return counts, codon_usage # Return this dictionary of dictiomaries


def amino_acid_usage(org_id: int, aa: str):
Expand All @@ -87,12 +92,14 @@ def amino_acid_usage(org_id: int, aa: str):
cols = [getattr(CodonUsage, c) for c in codons]
return db.query(*cols).filter(CodonUsage.org_id == org_id).first()


def search_for_species(name: str) -> list[Organism]:
"""Search for an organism based on a name"""
with SessionLocal() as db:
return db.query(Organism).filter(Organism.species.ilike(f"%{name}%")).all()


def get_species_by_id(org_id: str) -> Organism:
"""return an organism object given an org_id"""
with SessionLocal() as db:
return db.query(Organism).get(org_id)
return db.query(Organism).get(org_id)
7 changes: 5 additions & 2 deletions optipyzer/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from sqlalchemy import Column, Integer, String, Float


class Organism(Base):
__tablename__ = "organisms"

Expand All @@ -21,11 +22,12 @@ class Organism(Base):
GC2_perc = Column(Float)
GC3_perc = Column(Float)


# this is a truncated version of the above table
# to improve browser performance
class AutocompleteOrganism(Base):
__tablename__ = "autocomplete_data"

org_id = Column(Integer, primary_key=True)
division = Column(String)
assembly = Column(String)
Expand All @@ -41,8 +43,9 @@ class AutocompleteOrganism(Base):
GC3_perc = Column(Float)
category = Column(String)


class CodonUsage(Base):

__tablename__ = "codon_usage"

org_id = Column(Integer, primary_key=True)
Expand Down
11 changes: 8 additions & 3 deletions optipyzer/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from .utils import clean_seq
from .request_models import OptimizeQuery


def verify_dna(query: OptimizeQuery) -> OptimizeQuery:
"""
Verify that a DNA sequence complies with the following:
Expand All @@ -19,14 +20,15 @@ def verify_dna(query: OptimizeQuery) -> OptimizeQuery:
# is divisible by 3 (codons)
if len(query.seq) % 3 != 0:
raise HTTPException(400, detail="DNA sequence must be devisible by 3")

# verify all characters are
# ATGC
for base, i in zip(query.seq, range(len(query.seq))):
if base.upper() not in "ATGC":
raise HTTPException(400, f"Invalid base '{base}' in query at position: {i}")
return query


def verify_protein(query: OptimizeQuery) -> OptimizeQuery:
"""
Verify that a protein sequence complies with the following:
Expand All @@ -41,14 +43,17 @@ def verify_protein(query: OptimizeQuery) -> OptimizeQuery:
# verify each residue is valid
for aa, i in zip(query.seq, range(len(query.seq))):
if aa.upper() not in VALID_AMINO_ACIDS:
raise HTTPException(400, f"Invalid residue '{aa}' in query at position: {i}")
raise HTTPException(
400, f"Invalid residue '{aa}' in query at position: {i}"
)
return query


def verify_org_id(org_id: str) -> str:
"""
Verify that an organism id exists in the database.
"""
org = get_species_by_id(org_id)
if org is None:
raise HTTPException(404, f"Organism id '{org_id}' not found in database.")
return org_id
return org_id
Loading

1 comment on commit 98e1aac

@vercel
Copy link

@vercel vercel bot commented on 98e1aac Jul 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.