Skip to content

Commit 1405ac4

Browse files
committed
Implemented some more Accessions
1 parent 03ef268 commit 1405ac4

File tree

11 files changed

+170
-10
lines changed

11 files changed

+170
-10
lines changed

data/admin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class Media:
2828
admin.site.register(File, FileAdmin)
2929

3030
class ItemAdmin(admin.ModelAdmin):
31-
list_display = ('key', 'id', 'file')
31+
list_display = ('key', 'id', 'file', 'attributes')
3232
search_fields = ('attributes',)
3333
actions_on_top = True
3434
actions_on_bottom = True

data/api.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from rest_framework import renderers
2+
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
3+
from rest_framework.decorators import action, link
4+
from rest_framework.response import Response
5+
from rest_framework.views import APIView
6+
from rest_framework import viewsets
7+
from django.contrib.auth.models import User
8+
from django.http import Http404
9+
from .models import File, FileRelationship, Item, ItemRelationship
10+
from .serializers import FileSerializer, ItemSerializer
11+
12+
class FileViewSet(viewsets.ReadOnlyModelViewSet):
13+
"""
14+
Retrieve organisms.
15+
"""
16+
queryset = File.objects.all()
17+
serializer_class = FileSerializer
18+
lookup_field = 'id'
19+
20+
class ItemViewSet(viewsets.ReadOnlyModelViewSet):
21+
"""
22+
Retrieve sequence types.
23+
"""
24+
queryset = Item.objects.all()
25+
serializer_class = ItemSerializer
26+
lookup_field = 'key'
27+
28+
class AccessionList(APIView):
29+
"""
30+
List all snippets, or create a new snippet.
31+
"""
32+
def get(self, request, format=None):
33+
files = File.objects.all()
34+
serializer = FileSerializer(files, many=True)
35+
return Response(serializer.data)
36+
37+
class AccessionDetail(APIView):
38+
"""
39+
Retrieve, update or delete a snippet instance.
40+
"""
41+
def get_file(self, id):
42+
try:
43+
return File.objects.get(id=id)
44+
except File.DoesNotExist:
45+
raise Http404
46+
47+
def get(self, request, accession, format=None):
48+
ids = accession.split('/')
49+
file = self.get_file(ids[0])
50+
serializer = FileSerializer(file)
51+
return Response(serializer.data)

data/file_types/gff3.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1046,7 +1046,7 @@ def __repr__(self, level=0):
10461046
return sorted(list(root_set), key=lambda x: x.value)
10471047

10481048
try:
1049-
from ordereddict import OrderedDict
1049+
from collections import OrderedDict
10501050
except ImportError:
10511051
# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy.
10521052
# Passes Python2.7's test suite and incorporates all the latest updates.

data/models.py

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
from django.db import models
22
from django.contrib.postgres.fields import HStoreField
33
from filebrowser.fields import FileBrowseField
4-
from file_types.gff3 import Gff3
4+
from file_types.gff3 import Gff3, fasta_file_to_dict
55
import os
6+
import six
7+
import numbers
8+
from collections import OrderedDict
69

710
class File(models.Model):
811
'''A File is a self-contained List, Tree, or Graph of Items.
@@ -13,7 +16,7 @@ class File(models.Model):
1316
hash = models.TextField(blank=True)
1417
processed_hash = models.TextField(blank=True)
1518
processed_date = models.DateTimeField(auto_now_add=True)
16-
attributes = HStoreField()
19+
attributes = HStoreField(blank=True)
1720
related = models.ManyToManyField('self', through='FileRelationship', through_fields=('source', 'target'), symmetrical=False)
1821

1922
def process_file(self):
@@ -22,9 +25,63 @@ def process_file(self):
2225
from sys import platform
2326
from subprocess import Popen, PIPE
2427
if self.type == 'gff3':
25-
gff = Gff3(str(self.name.path_full))
28+
try:
29+
# remove existing items
30+
self.item_set.all().delete()
31+
# parse file
32+
gff = Gff3(str(self.name.path_full))
33+
#seq_count = 0
34+
item_list = []
35+
item_relationship_list = []
36+
37+
# assign every line to an Item
38+
for idx, ld in enumerate(gff.lines):
39+
attributes = {}
40+
for k, v in ld.items():
41+
if v:
42+
if isinstance(v, six.string_types):
43+
attributes[k] = v
44+
elif isinstance(v, numbers.Number):
45+
attributes[k] = str(v)
46+
item_list.append(Item(file=self, id=idx+1, text=ld['line_raw'], attributes=attributes))
47+
48+
# assign Accessions with dfs tranversal
49+
def dfs(root_line, path=OrderedDict()):
50+
pass
51+
# get a list of root nodes
52+
root_lines = [line_data for line_data in gff.lines if line_data['line_type'] == 'feature' and not line_data['parents']]
53+
for idx, root_line in enumerate(root_lines):
54+
pass
55+
56+
# build ItemRelationships
57+
58+
if len(item_list) > 0:
59+
Item.objects.bulk_create(item_list)
60+
if len(item_relationship_list) > 0:
61+
ItemRelationship.objects.bulk_create(item_relationship_list)
62+
return 0, '', '%d items added.' % len(item_list)
63+
except Exception as e:
64+
return 1, str(e), ''
2665
#return p.returncode, error, output
27-
return 1, 'Gff3 lines = {}'.format(len(gff.lines)), ''
66+
#return 1, 'Gff3 lines = {}'.format(len(gff.lines)), ''
67+
elif self.type == 'fasta':
68+
try:
69+
# remove existing items
70+
self.item_set.all().delete()
71+
# parse file
72+
fasta, count = fasta_file_to_dict(str(self.name.path_full))
73+
#seq_count = 0
74+
item_list = []
75+
item_relationship_list = []
76+
for idx, id in enumerate(fasta):
77+
item_list.append(Item(file=self, id=idx+1, text='{}\n{}'.format(fasta[id]['header'], fasta[id]['seq']), attributes={'header': fasta[id]['header'], 'id': fasta[id]['id'], 'seq': fasta[id]['seq']}))
78+
if len(item_list) > 0:
79+
Item.objects.bulk_create(item_list)
80+
if len(item_relationship_list) > 0:
81+
ItemRelationship.objects.bulk_create(item_relationship_list)
82+
return 0, '', '%d items added.' % len(item_list)
83+
except Exception as e:
84+
return 1, str(e), ''
2885
else:
2986
return 1, 'File type not supported', ''
3087

@@ -42,8 +99,9 @@ class Item(models.Model):
4299
'''Accessions are assigned to Items.
43100
'''
44101
key = models.AutoField(primary_key=True) # auto
45-
id = models.PositiveIntegerField() #
102+
accession = models.TextField(blank=True)
46103
file = models.ForeignKey(File)
104+
text = models.TextField(blank=True)
47105
attributes = HStoreField()
48106
related = models.ManyToManyField('self', through='ItemRelationship', through_fields=('source', 'target'), symmetrical=False)
49107

@@ -55,4 +113,13 @@ class ItemRelationship(models.Model):
55113
'''
56114
source = models.ForeignKey(Item, related_name='+')
57115
type = models.CharField(max_length=50, help_text='Relationship Type')
58-
target = models.ForeignKey(Item, related_name='+')
116+
target = models.ForeignKey(Item, related_name='+')
117+
118+
class Accession(models.Model):
119+
'''Accessions are assigned to Items.
120+
'''
121+
accession = models.TextField(blank=True)
122+
item = models.ForeignKey(Item)
123+
124+
def __unicode__(self):
125+
return str(self.accession)

data/serializers.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from rest_framework import serializers
2+
from rest_framework.pagination import PaginationSerializer
3+
from django.contrib.auth.models import User
4+
from .models import File, FileRelationship, Item, ItemRelationship
5+
6+
class FileSerializer(serializers.HyperlinkedModelSerializer):
7+
url = serializers.HyperlinkedIdentityField(view_name='file-detail', lookup_field='id')
8+
9+
class Meta:
10+
model = File
11+
12+
class ItemSerializer(serializers.HyperlinkedModelSerializer):
13+
url = serializers.HyperlinkedIdentityField(view_name='item-detail', lookup_field='key')
14+
file = serializers.HyperlinkedRelatedField(view_name='file-detail', lookup_field='id')
15+
16+
class Meta:
17+
model = Item

data/urls.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from django.conf.urls import patterns, url, include
2+
from blast import views
3+
from .api import FileViewSet, ItemViewSet, AccessionDetail
4+
from rest_framework.routers import DefaultRouter
5+
from rest_framework.urlpatterns import format_suffix_patterns
6+
7+
router = DefaultRouter()
8+
router.register(r'file', FileViewSet)
9+
router.register(r'item', ItemViewSet)
10+
11+
urlpatterns = format_suffix_patterns('',
12+
url(r'^api/', include(router.urls)),
13+
url(r'^api/accessions/(?P<accession>.+)/$', AccessionDetail.as_view()),
14+
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
15+
url(r'^api-docs/', include('rest_framework_swagger.urls')),
16+
)

i5k.pyproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,15 @@
7575
<Compile Include="dashboard\views.py" />
7676
<Compile Include="dashboard\__init__.py" />
7777
<Compile Include="data\admin.py" />
78+
<Compile Include="data\api.py" />
7879
<Compile Include="data\file_types\gff3.py" />
7980
<Compile Include="data\file_types\__init__.py" />
8081
<Compile Include="data\migrations\0001_initial.py" />
8182
<Compile Include="data\migrations\__init__.py" />
8283
<Compile Include="data\models.py" />
84+
<Compile Include="data\serializers.py" />
8385
<Compile Include="data\tests.py" />
86+
<Compile Include="data\urls.py" />
8487
<Compile Include="data\views.py" />
8588
<Compile Include="data\__init__.py" />
8689
<Compile Include="i5k\settings_prod.py" />

i5k/settings.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@
271271
{'model': 'speciespassword', 'label': '[Read Only] Passwords'},
272272
{'model': 'registration', 'label': '[Read Only] Registrations'},
273273
)},
274+
{'app': 'data', 'label': 'Data', 'icon':'icon-leaf', 'models': (
275+
{'model': 'file'},
276+
{'model': 'item'},
277+
)},
274278
# auth and axes
275279
{'label': 'Auth', 'icon':'icon-lock', 'models': (
276280
{'model': 'auth.user'},

i5k/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@
116116

117117
# BLAST
118118
url(r'^blast/', include('blast.urls', namespace='blast')),
119+
# BLAST
120+
url(r'^data/', include('data.urls', namespace='data')),
119121
)
120122
from django.conf import settings
121123
if settings.DEBUG:

web.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
</trace>
1414
</system.diagnostics>
1515
<appSettings>
16-
<add key="WSGI_HANDLER" value="django.core.handlers.wsgi.WSGIHandler()" />
16+
<add key="WSGI_HANDLER" value="django.core.wsgi.get_wsgi_application()" />
1717
<add key="PYTHONPATH" value="%ROOTDIR%" />
1818
<add key="DJANGO_SETTINGS_MODULE" value="i5k.settings" />
1919
</appSettings>

web.debug.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
88
<appSettings>
99
<!-- The following setting is meant to protect the debugging endpoint against inadvertent access, and should be treated as a password. -->
10-
<add key="WSGI_PTVSD_SECRET" value="dkryuwojxpn" xdt:Transform="Insert" />
10+
<add key="WSGI_PTVSD_SECRET" value="gasgkhy43j1" xdt:Transform="Insert" />
1111
</appSettings>
1212
<system.web>
1313
<!-- Required for websockets. -->

0 commit comments

Comments
 (0)