Skip to content

Commit

Permalink
only keep blast seq api
Browse files Browse the repository at this point in the history
  • Loading branch information
hsiaoyi0504 committed Aug 13, 2018
1 parent 452174f commit 2a13ec2
Show file tree
Hide file tree
Showing 13 changed files with 376 additions and 409 deletions.
61 changes: 10 additions & 51 deletions blast/api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
from rest_framework import renderers
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
from rest_framework import viewsets
from django.contrib.auth.models import User
from app.models import Organism
from blast.models import SequenceType, BlastDb, Sequence
from blast.serializers import OrganismSerializer, BlastDbSerializer, SequenceSerializer, SequenceTypeSerializer


class FASTARenderer(renderers.BaseRenderer):
media_type = 'text/plain'
Expand All @@ -12,11 +19,6 @@ def render(self, data, media_type=None, renderer_context=None):
else:
return ''

from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
from rest_framework import viewsets
from django.contrib.auth.models import User
from .models import *
from .serializers import *

class OrganismViewSet(viewsets.ReadOnlyModelViewSet):
"""
Expand All @@ -26,6 +28,7 @@ class OrganismViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = OrganismSerializer
lookup_field = 'short_name'


class SequenceTypeViewSet(viewsets.ReadOnlyModelViewSet):
"""
Retrieve sequence types.
Expand All @@ -34,6 +37,7 @@ class SequenceTypeViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = SequenceTypeSerializer
lookup_field = 'dataset_type'


class BlastDbViewSet(viewsets.ReadOnlyModelViewSet):
"""
Retrieve BLAST databases.
Expand All @@ -43,58 +47,13 @@ class BlastDbViewSet(viewsets.ReadOnlyModelViewSet):
lookup_field = 'title'
lookup_value_regex = '[^/]+'

#@link()
#def sequence_set(self, request, title=None):
# empty_error = "Empty list and '%(class_name)s.allow_empty' is False."
# blastdb = self.get_object()
# object_list = self.filter_queryset(blastdb.sequence_set.all())

# # Default is to allow empty querysets. This can be altered by setting
# # `.allow_empty = False`, to raise 404 errors on empty querysets.
# if not self.allow_empty and not object_list:
# warnings.warn(
# 'The `allow_empty` parameter is deprecated. '
# 'To use `allow_empty=False` style behavior, You should override '
# '`get_queryset()` and explicitly raise a 404 on empty querysets.',
# DeprecationWarning
# )
# class_name = self.__class__.__name__
# error_msg = self.empty_error % {'class_name': class_name}
# raise Http404(error_msg)

# # Switch between paginated or standard style responses
# page = self.paginate_queryset(object_list)
# if page is not None:
# serializer = PaginatedSequenceSerializer(instance=page, context={'request': request})
# else:
# serializer = SequenceSerializer(object_list, many=True, context={'request': request})

# return Response(serializer.data)

class SequenceViewSet(viewsets.ReadOnlyModelViewSet):
"""
Retrieve fasta sequences.
"""
queryset = Sequence.objects.all()
serializer_class = SequenceSerializer
renderer_classes = (JSONRenderer, BrowsableAPIRenderer, FASTARenderer)
renderer_classes = [FASTARenderer]
lookup_field = 'id'
lookup_value_regex = '[^/]+'

class BlastQueryRecordViewSet(viewsets.ReadOnlyModelViewSet):
"""
Retrieve tasks.
"""
queryset = BlastQueryRecord.objects.all()
serializer_class = BlastQueryRecordSerializer
lookup_field = 'task_id'

class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
Retrieve users.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
lookup_field = 'pk'


2 changes: 0 additions & 2 deletions blast/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,10 @@ class BlastDb(models.Model):
objects = BlastDbManager()
organism = models.ForeignKey(app.models.Organism)
type = models.ForeignKey(SequenceType)
# fasta_file = models.FileField(upload_to='blastdb') # upload file
fasta_file = FileBrowseField('FASTA file path', max_length=200, directory='blast/db/', extensions='FASTA', format='FASTA')
title = models.CharField(max_length=200, unique=True, help_text='This is passed into makeblast -title') # makeblastdb -title
description = models.TextField(blank=True) # shown in blast db selection ui
is_shown = models.BooleanField(default=None, help_text='Display this database in the BLAST submit form') # to temporarily remove from blast db selection ui
# sequence_count = models.PositiveIntegerField(null=True, blank=True) # number of sequences in this fasta

# properties
def fasta_file_exists(self):
Expand Down
79 changes: 36 additions & 43 deletions blast/serializers.py
Original file line number Diff line number Diff line change
@@ -1,62 +1,55 @@
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer, HyperlinkedModelSerializer, HyperlinkedIdentityField, ReadOnlyField, HyperlinkedRelatedField
from django.contrib.auth.models import User
from app.models import Organism
from blast.models import SequenceType, BlastDb, Sequence, BlastQueryRecord

class OrganismSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='blast:organism-detail', lookup_field='short_name')

class OrganismSerializer(HyperlinkedModelSerializer):
class Meta:
model = Organism
fields = ('display_name', 'short_name', 'description', 'tax_id')


class SequenceTypeSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='blast:sequencetype-detail', lookup_field='dataset_type')

class SequenceTypeSerializer(HyperlinkedModelSerializer):
class Meta:
model = SequenceType


class BlastDbSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='blast:blastdb-detail', lookup_field='title')
organism = serializers.HyperlinkedRelatedField(view_name='blast:organism-detail', lookup_field='short_name', read_only=True)
type = serializers.HyperlinkedRelatedField(view_name='blast:sequencetype-detail', lookup_field='dataset_type', read_only=True)
sequence_set = serializers.HyperlinkedRelatedField(view_name='blast:blastdb-sequence-set', lookup_field='title', read_only=True)
fasta_file_exists = serializers.Field()
blast_db_files_exists = serializers.Field()
sequence_set_exists = serializers.Field()
db_ready = serializers.Field()
fields = ('molecule_type', 'dataset_type')


class BlastDbSerializer(HyperlinkedModelSerializer):
organism = HyperlinkedRelatedField(
view_name='blast:organism-detail',
lookup_field='short_name',
read_only=True)
type = HyperlinkedRelatedField(
view_name='blast:sequencetype-detail',
lookup_field='dataset_type',
read_only=True)
fasta_file_exists = ReadOnlyField()
blast_db_files_exists = ReadOnlyField()
sequence_set_exists = ReadOnlyField()
db_ready = ReadOnlyField()

class Meta:
model = BlastDb
fields = ('url', 'organism', 'type', 'fasta_file', 'title', 'description', 'is_shown', 'fasta_file_exists', 'blast_db_files_exists', 'sequence_set_exists', 'db_ready', 'sequence_set', )
fields = ('organism', 'type', 'fasta_file', 'title', 'description',
'is_shown', 'fasta_file_exists', 'blast_db_files_exists',
'sequence_set_exists', 'db_ready')


class SequenceSerializer(serializers.HyperlinkedModelSerializer):
blast_db = serializers.HyperlinkedRelatedField(view_name='blast:blastdb-detail', lookup_field='title', read_only=True)
fasta_seq = serializers.ReadOnlyField()
class SequenceSerializer(HyperlinkedModelSerializer):
blast_db = HyperlinkedRelatedField(
view_name='blast:blastdb-detail', lookup_field='title', read_only=True)
fasta_seq = ReadOnlyField()

class Meta:
model = Sequence
fields = ('blast_db', 'id', 'length', 'seq_start_pos', 'seq_end_pos', 'modified_date', 'fasta_seq', )


class BlastQueryRecordSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='blast:blastqueryrecord-detail', lookup_field='task_id')

class Meta:
model = BlastQueryRecord


class UserSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='blast:user-detail', lookup_field='pk')

class Meta:
model = User
fields = ('id', 'url',)


class UserBlastQueryRecordSerializer(serializers.ModelSerializer):
class Meta:
model = BlastQueryRecord
fields = ('task_id', 'enqueue_date', 'result_status')
fields = (
'blast_db',
'id',
'length',
'seq_start_pos',
'seq_end_pos',
'modified_date',
'fasta_seq',
)
2 changes: 1 addition & 1 deletion blast/static/blast/scripts/blast-results.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ $(function () { // document ready
var url_root = /(https?:\/\/.*(?:blast)*)\/task\//g.exec(document.URL)[1];
function get_fasta(sseqid) {
// Returns a jqXHR or true if already in cache, for use with $.when
//http://localhost:8000/api/seq/gnl%7CLoxosceles_reclusa_transcript_v0.5.3%7CLREC000002-RA/?format=fasta
// base_url/blast/api/seq/gnl%7CLoxosceles_reclusa_transcript_v0.5.3%7CLREC000002-RA/?format=fasta
if (sseqid in fasta_cache)
return true;
else if (sseqid in fasta_loading)
Expand Down
22 changes: 5 additions & 17 deletions blast/urls.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
from django.conf.urls import url, include
from django.conf import settings
from blast import views
from blast.api import OrganismViewSet, SequenceTypeViewSet, BlastDbViewSet, SequenceViewSet, BlastQueryRecordViewSet, UserViewSet
from rest_framework import routers

router = routers.DefaultRouter()
router.register(r'organism', OrganismViewSet)
router.register(r'seqtype', SequenceTypeViewSet)
router.register(r'blastdb', BlastDbViewSet)
router.register(r'seq', SequenceViewSet)
router.register(r'task', BlastQueryRecordViewSet)
router.register(r'user', UserViewSet)

urlpatterns = [
# ex: /blast/
url(r'^$', views.create, name='create'),
# url(r'^iframe$', views.create, {'iframe': True}, name='iframe'),
# ex: /blast/5/
url(r'^task/(?P<task_id>[0-9a-zA-Z]+)$', views.retrieve, name='retrieve'),
url(r'^task/(?P<task_id>[0-9a-zA-Z]+)/status$', views.status, name='status'),
url(r'^task/(?P<task_id>[0-9a-zA-Z]+)/status$',
views.status,
name='status'),
# url(r'^read_gff3/(?P<task_id>[0-9a-fA-F]*)/*(?P<dbname>[\w\-\|.]*)/*$', views.read_gff3, name='read_gff3'),
url(r'^api/', include(router.urls)),
# url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^user-tasks/(?P<user_id>[0-9]+)$', views.user_tasks),
url(r'^api/seq/(?P<seq_id>[a-zA-Z0-9_-]+)/', views.get_seq, name='seq'),
]

if settings.DEBUG:
from blast import test_views
urlpatterns += [
url(r'^test/$', test_views.test_main)
]
urlpatterns += [url(r'^test/$', test_views.test_main)]
30 changes: 6 additions & 24 deletions blast/views.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from __future__ import absolute_import
from django.shortcuts import render
from django.shortcuts import redirect
from django.shortcuts import redirect, get_object_or_404
from django.http import Http404
from django.http import HttpResponse
from django.conf import settings
from django.core.cache import cache
from uuid import uuid4
from os import path, makedirs, chmod, remove
from blast.models import BlastQueryRecord, BlastDb
from blast.models import BlastQueryRecord, BlastDb, Sequence
from blast.tasks import run_blast_task
from datetime import datetime, timedelta
from django.utils.timezone import localtime, now
Expand All @@ -18,6 +18,7 @@
from itertools import groupby
from multiprocessing import cpu_count
from util.get_bin_name import get_bin_name
from rest_framework.renderers import JSONRenderer

blast_customized_options = {'blastn': ['max_target_seqs', 'evalue', 'word_size', 'reward', 'penalty', 'gapopen', 'gapextend', 'strand', 'low_complexity', 'soft_masking'],
'tblastn': ['max_target_seqs', 'evalue', 'word_size', 'matrix', 'threshold', 'gapopen', 'gapextend', 'low_complexity', 'soft_masking'],
Expand Down Expand Up @@ -248,25 +249,6 @@ def status(request, task_id):
else:
return HttpResponse('Invalid Post')


# to-do: integrate with existing router of restframework
from rest_framework.renderers import JSONRenderer
from .serializers import UserBlastQueryRecordSerializer
class JSONResponse(HttpResponse):
"""
An HttpResponse that renders its content into JSON.
"""
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content_type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs)

def user_tasks(request, user_id):
"""
Return tasks performed by the user.
"""
if request.method == 'GET':
records = BlastQueryRecord.objects.filter(user__id=user_id, is_shown=True, result_date__gt=(localtime(now())+ timedelta(days=-7)))
serializer = UserBlastQueryRecordSerializer(records, many=True)
return JSONResponse(serializer.data)

def get_seq(request, seq_id):
seq = get_object_or_404(Sequence, id=seq_id)
return HttpResponse(seq.fasta_seq(), content_type='text/plain')
14 changes: 0 additions & 14 deletions clustal/serializers.py

This file was deleted.

8 changes: 3 additions & 5 deletions clustal/urls.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
from django.conf.urls import url
from clustal import views
# from .api import *

urlpatterns = [
# ex: /clustal/
url(r'^$', views.create, name='create'),
# ex: /clustal/5/
url(r'^task/(?P<task_id>[0-9a-zA-Z]+)$', views.retrieve, name='retrieve'),
url(r'^task/(?P<task_id>[0-9a-zA-Z]+)/status$', views.status, name='status'),
# url(r'^api/', include(router.urls)),
# url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url('^user-tasks/(?P<user_id>[0-9]+)$', views.user_tasks),
url(r'^task/(?P<task_id>[0-9a-zA-Z]+)/status$',
views.status,
name='status'),
url(r'^manual/$', views.manual, name='manual'),
]
Loading

0 comments on commit 2a13ec2

Please sign in to comment.