Skip to content

Commit 137501e

Browse files
authored
Merge branch '2.0.0' into dependabot/pip/urllib3-1.26.5
2 parents d34ae9a + dfafb8c commit 137501e

File tree

5 files changed

+182
-10
lines changed

5 files changed

+182
-10
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,6 @@ dmypy.json
139139
# The migrations folder.
140140
# bco_api/api/migrations/
141141
.DS_Store*
142+
143+
# JetBrains IDEs
144+
.idea/

bco_api/api/scripts/method_specific/POST_api_objects_drafts_token.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ def POST_api_objects_drafts_token(
164164
# import pdb; pdb.set_trace()
165165

166166
published = bco.objects.filter(state='PUBLISHED').values()
167-
unique_published = []
167+
# unique_published = []
168+
unique_published = set()
168169

169170
# E.g.
170171
# published[0]["contents"]["object_id"] = 'http://127.0.0.1:8000/BCO_000010/1.0'
@@ -202,9 +203,14 @@ def POST_api_objects_drafts_token(
202203
"bco_object": p
203204
}
204205
for key, value in bcos.items():
205-
unique_published.append(value["bco_object"])
206+
# unique_published.append(value["bco_object"])
207+
# import pdb;pdb.set_trace()
208+
unique_published.add(value["bco_object"]["id"])
209+
210+
# result_list = chain(user_objects.intersection(prefix_objects).values(*return_values), unique_published(*return_values))
211+
unique_published = bco.objects.filter(id__in = unique_published)
212+
result_list = chain(user_objects.intersection(unique_published).values(*return_values), prefix_objects.values(*return_values))
206213

207-
result_list = chain(user_objects.intersection(prefix_objects).values(*return_values), unique_published)
208214

209215
return Response(
210216
data=result_list,
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# BCOs
2+
from ...models import bco
3+
4+
# User information
5+
from ..utilities import UserUtils
6+
7+
# Object-level permissions
8+
from guardian.shortcuts import get_objects_for_user
9+
10+
# Concatenating QuerySets
11+
from itertools import chain
12+
13+
# Responses
14+
from rest_framework import status
15+
from rest_framework.response import Response
16+
17+
# Below is helper code to deal with how we are allowing non standard versions (i.e. 1.2 instead of 1.2.0, etc).
18+
import re
19+
import semver
20+
from semver import VersionInfo as Version
21+
from typing import Optional, Tuple
22+
23+
# TODO: This is repeated code, should consolidate
24+
BASEVERSION = re.compile(
25+
r"""[vV]?
26+
(?P<major>0|[1-9]\d*)
27+
(\.
28+
(?P<minor>0|[1-9]\d*)
29+
(\.
30+
(?P<patch>0|[1-9]\d*)
31+
)?
32+
)?
33+
""",
34+
re.VERBOSE,
35+
)
36+
37+
38+
def coerce(version: str) -> Tuple[Version, Optional[str]]:
39+
"""
40+
Convert an incomplete version string into a semver-compatible Version
41+
object
42+
* Tries to detect a "basic" version string (``major.minor.patch``).
43+
* If not enough components can be found, missing components are
44+
set to zero to obtain a valid semver version.
45+
:param str version: the version string to convert
46+
:return: a tuple with a :class:`Version` instance (or ``None``
47+
if it's not a version) and the rest of the string which doesn't
48+
belong to a basic version.
49+
:rtype: tuple(:class:`Version` | None, str)
50+
"""
51+
match = BASEVERSION.search(version)
52+
if not match:
53+
return (None, version)
54+
55+
ver = {
56+
key: 0 if value is None else value for key, value in match.groupdict().items()
57+
}
58+
ver = Version(**ver)
59+
rest = match.string[match.end():] # noqa:E203
60+
return ver, rest
61+
62+
63+
def POST_api_objects_published():
64+
"""
65+
Get All published objects (publicly available)
66+
"""
67+
68+
published = bco.objects.filter(state='PUBLISHED').values()
69+
unique_published = []
70+
71+
# E.g.
72+
# published[0]["contents"]["object_id"] = 'http://127.0.0.1:8000/BCO_000010/1.0'
73+
74+
bcos = { }
75+
for p in published:
76+
# TODO: We should move this out of a try except and try to handle various situations, this is currently
77+
# assuming that the format is http://URL:PORT/BCO NAME/BCO VERSION - this may not always be true
78+
try:
79+
bco_url, bco_id_name, bco_id_version = p["contents"]["object_id"].rsplit("/", 2)
80+
except Exception as e:
81+
print("Biocompute Name, Version, and URL not formatted as expected: {}".format(e))
82+
return Response(status=status.HTTP_400_BAD_REQUEST)
83+
84+
if bco_url in bcos:
85+
# Other version of this BCO object exists
86+
current_version = bcos[bco_url]["bco_version"]
87+
88+
if semver.compare(bco_id_version, current_version, key=coerce):
89+
# New one is newer version, set:
90+
bcos[bco_url] = {
91+
"bco_name" : bco_id_name,
92+
"bco_version": bco_id_version,
93+
"bco_object" : p
94+
}
95+
96+
else:
97+
# Do nothing
98+
pass
99+
else:
100+
# Not in dictionary yet
101+
bcos[bco_url] = {
102+
"bco_name" : bco_id_name,
103+
"bco_version": bco_id_version,
104+
"bco_object" : p
105+
}
106+
for key, value in bcos.items():
107+
unique_published.append(value["bco_object"])
108+
109+
return Response(
110+
data=unique_published,
111+
status=status.HTTP_200_OK
112+
)

bco_api/api/urls.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from .views import ApiAccountsActivateUsernameTempIdentifier, ApiAccountsDescribe, ApiAccountsNew, ApiGroupsCreate, \
33
ApiGroupsDelete, ApiGroupsModify, \
44
ApiObjectsDraftsCreate, ApiObjectsDraftsModify, ApiObjectsDraftsPermissions, ApiObjectsDraftsPermissionsSet, \
5-
ApiObjectsDraftsPublish, ApiObjectsDraftsRead, \
5+
ApiObjectsDraftsPublish, ApiObjectsDraftsRead, ApiObjectsPublished, \
66
ApiObjectsSearch, ApiObjectsToken, ApiPrefixesCreate, ApiPrefixesDelete, ApiPrefixesPermissionsSet, \
77
ApiPrefixesToken, ApiPrefixesTokenFlat, \
88
ApiPrefixesUpdate, ApiObjectsPublish, ApiObjectsDraftsToken, ApiPublicDescribe, DraftObjectId, ObjectIdRootObjectId, \
@@ -141,9 +141,10 @@
141141
re_path(r'^api/doc(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
142142
path('api/docs/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
143143
path('api/redocs/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
144-
path('<str:object_id_root>', ObjectIdRootObjectId.as_view()),
145-
path('<str:object_id_root>/<str:object_id_version>', ObjectIdRootObjectIdVersion.as_view()),
144+
path('bco/<str:object_id_root>', ObjectIdRootObjectId.as_view()),
145+
path('bco/<str:object_id_root>/<str:object_id_version>', ObjectIdRootObjectIdVersion.as_view()),
146146
path('api/objects/publish/', ApiObjectsPublish.as_view()),
147+
path('api/objects/published/', ApiObjectsPublished.as_view()),
147148
path('api/public/describe/', ApiPublicDescribe.as_view())
148149
]
149150

@@ -159,14 +160,13 @@
159160
schema_view.with_ui('redoc', cache_timeout=0),
160161
name='schema-redoc'
161162
),
162-
path('draft/<str:draft_object_id>',
163+
path('<str:draft_object_id>',
163164
DraftObjectId.as_view()
164165
),
165-
166-
path('<str:object_id_root>',
166+
path('bco/<str:object_id_root>',
167167
ObjectIdRootObjectId.as_view()
168168
),
169-
path('<str:object_id_root>/<str:object_id_version>',
169+
path('bco/<str:object_id_root>/<str:object_id_version>',
170170
ObjectIdRootObjectIdVersion.as_view()
171171
),
172172
path('api/accounts/activate/<str:username>/<str:temp_identifier>',
@@ -214,6 +214,9 @@
214214
path('api/objects/token/',
215215
ApiObjectsToken.as_view()
216216
),
217+
path('api/objects/published/',
218+
ApiObjectsPublished.as_view()
219+
),
217220
path('api/prefixes/create/',
218221
ApiPrefixesCreate.as_view()
219222
),

bco_api/api/views.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from .scripts.method_specific.POST_api_objects_drafts_read import POST_api_objects_drafts_read
3535
from .scripts.method_specific.POST_api_objects_drafts_token import POST_api_objects_drafts_token
3636
from .scripts.method_specific.POST_api_objects_publish import POST_api_objects_publish
37+
from .scripts.method_specific.POST_api_objects_published import POST_api_objects_published
3738
from .scripts.method_specific.POST_api_objects_search import POST_api_objects_search
3839
from .scripts.method_specific.POST_api_objects_token import POST_api_objects_token
3940
from .scripts.method_specific.POST_api_prefixes_create import POST_api_prefixes_create
@@ -795,6 +796,53 @@ def post(self, request) -> Response:
795796
return POST_api_objects_token(rqst=request)
796797

797798

799+
class ApiObjectsPublished(APIView):
800+
"""
801+
Get Published BCOs
802+
803+
--------------------
804+
805+
Get all BCOs available for a specific token, including published ones.
806+
"""
807+
808+
# auth = []
809+
# auth.append(
810+
# openapi.Parameter('Token', openapi.IN_HEADER, description="Authorization Token", type=openapi.TYPE_STRING))
811+
812+
# request_body = openapi.Schema(
813+
# type=openapi.TYPE_OBJECT,
814+
# title="Get BCO Schema",
815+
# description="Parameters that are supported when fetching a BCOs.",
816+
# required=['POST_api_objects_token'],
817+
# properties={
818+
# 'POST_api_objects_token': openapi.Schema(
819+
# type=openapi.TYPE_OBJECT,
820+
# required=['fields'],
821+
# properties={
822+
# 'fields': openapi.Schema(
823+
# type=openapi.TYPE_ARRAY,
824+
# items=openapi.Schema(
825+
# type=openapi.TYPE_STRING,
826+
# description="Field to return",
827+
# enum=['contents', 'last_update', 'object_class', 'object_id', 'owner_group', 'owner_user',
828+
# 'prefix', 'schema', 'state']
829+
# ),
830+
# description="Fields to return.")
831+
# })})
832+
833+
# Anyone can view a published object
834+
authentication_classes = []
835+
permission_classes = []
836+
auth = []
837+
838+
@swagger_auto_schema(manual_parameters=auth, responses={
839+
200: "Success.",
840+
400: "Internal Error. BCO Name and Version are not properly formatted.",
841+
}, tags=["BCO Management"])
842+
def get(self, request) -> Response:
843+
return POST_api_objects_published()
844+
# return POST_api_objects_token(rqst=request)
845+
798846
class ApiPrefixesCreate(APIView):
799847
"""
800848
Create a Prefix

0 commit comments

Comments
 (0)