Skip to content
This repository has been archived by the owner on May 6, 2022. It is now read-only.

Add Challenge Platforms endpoints #127

Closed
wants to merge 13 commits into from
Closed
2 changes: 1 addition & 1 deletion .github/workflows/update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
2. Run the [openapi-generator] using the new ROCC OpenAPI
specification.

`npm run generate:server:version --oas_version=${{
`npm run generate:server:version --oas-version=${{
env.NEW_VERSION }}`

3. Review the updates made to this tool in the [ROCC schemas
Expand Down
2 changes: 1 addition & 1 deletion server/openapi_server/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


def main():
app.run(port=8080, debug=False)
app.run(port=8080, debug=True)


if __name__ == '__main__':
Expand Down
28 changes: 24 additions & 4 deletions server/openapi_server/controllers/challenge_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import traceback

from openapi_server.dbmodels.challenge import Challenge as DbChallenge
from openapi_server.dbmodels.challenge_platform import ChallengePlatform as DbChallengePlatform
# from openapi_server.dbmodels.challenge_results import ChallengeResults as DbChallengeResults # noqa: E501
from openapi_server.dbmodels.grant import Grant as DbGrant
from openapi_server.dbmodels.person import Person as DbPerson
Expand Down Expand Up @@ -61,6 +62,13 @@ def create_challenge():
res = Error(f"The grant {grant_id} was not found", status)
return res, status

try:
DbChallengePlatform.objects.get(id=challenge.platform_id)
except DoesNotExist:
status = 400
res = Error(f"The challenge platform {challenge.platform_id} was not found", status) # noqa: E501
return res, status

try:
db_challenge = DbChallenge(
name=challenge.name,
Expand All @@ -73,7 +81,8 @@ def create_challenge():
tagIds=challenge.tag_ids,
organizerIds=challenge.organizer_ids,
dataProviderIds=challenge.data_provider_ids,
grantIds=challenge.grant_ids
grantIds=challenge.grant_ids,
platformId=challenge.platform_id
# challengeResults=DbChallengeResults(
# nSubmissions=challenge.challenge_results.n_submissions, # noqa: E501
# nFinalSubmissions=challenge.challenge_results.n_final_submissions, # noqa: E501
Expand Down Expand Up @@ -146,15 +155,21 @@ def get_challenge(challenge_id):
return res, status


def list_challenges(limit=None, offset=None, filter_=None):
def list_challenges(limit=None, offset=None, filter_=None, sort=None, direction=None): # noqa: E501
"""List all the challenges

Returns all the challenges
Returns all the challenges # noqa: E501

:param limit: Maximum number of results returned
:type limit: int
:param offset: Index of the first result that must be returned
:type offset: int
:param filter: Object that describes how to filter the results
:type filter: dict | bytes
:param sort: Property used to sort the results that must be returned
:type sort: str
:param direction: Can be either `asc` or `desc`. Ignored without `sort` parameter.
:type direction: str

:rtype: PageOfChallenges
"""
Expand All @@ -170,9 +185,14 @@ def list_challenges(limit=None, offset=None, filter_=None):
if 'organizer' in filter_ else Q()
tag_q = Q(tagIds__contains=filter_['tag']) \
if 'tag' in filter_ else Q()

order_by = 'createdAt' # TODO: what is the best default behavior?
if sort is not None:
order_by = ('-' if direction == 'desc' else '') + sort

db_challenges = DbChallenge.objects(
name_q & status_q & organizer_q & tag_q
).skip(offset).limit(limit)
).skip(offset).limit(limit).order_by(order_by)
challenges = [Challenge.from_dict(d.to_dict()) for d in db_challenges]
next_ = ""
if len(challenges) == limit:
Expand Down
157 changes: 157 additions & 0 deletions server/openapi_server/controllers/challenge_platform_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import connexion
from mongoengine.errors import DoesNotExist, NotUniqueError
from mongoengine.queryset.visitor import Q

from openapi_server.dbmodels.challenge_platform import ChallengePlatform as DbChallengePlatform
from openapi_server.models.challenge_platform import ChallengePlatform # noqa: E501
from openapi_server.models.challenge_platform_create_request import ChallengePlatformCreateRequest # noqa: E501
from openapi_server.models.challenge_platform_create_response import ChallengePlatformCreateResponse # noqa: E501
from openapi_server.models.error import Error # noqa: E501
from openapi_server.models.page_of_challenge_platforms import PageOfChallengePlatforms # noqa: E501
from openapi_server.config import Config

def create_challenge_platform(challenge_platform_id): # noqa: E501
"""Create a challenge platform

Create a challenge platform with the specified ID # noqa: E501

:param challenge_platform_id: The ID of the challenge platform that is being created
:type challenge_platform_id: str

:rtype: ChallengePlatformCreateResponse
"""
res = None
status = None
if connexion.request.is_json:
try:
platform = ChallengePlatform.from_dict(connexion.request.get_json())
DbChallengePlatform(
id=challenge_platform_id,
name=platform.name,
url=platform.url
).save(force_insert=True)
res = ChallengePlatformCreateResponse(id=challenge_platform_id)
status = 201
except NotUniqueError as error:
status = 409
res = Error("Conflict", status, str(error))
except Exception as error:
status = 500
res = Error("Internal error", status, str(error))
else:
status = 400
res = Error("Bad request", status)
return res, status


def delete_all_challenge_platforms(): # noqa: E501
"""Delete all challenge platforms

Delete all challenge platforms # noqa: E501


:rtype: object
"""
res = None
status = None
try:
DbChallengePlatform.objects.delete()
res = {}
status = 200
except Exception as error:
status = 500
res = Error("Internal error", status, str(error))
return res, status


def delete_challenge_platform(challenge_platform_id): # noqa: E501
"""Delete a challenge platform

Deletes the challenge platform specified # noqa: E501

:param challenge_platform_id: The ID of the challenge platform
:type challenge_platform_id: str

:rtype: object
"""
res = None
status = None
try:
DbChallengePlatform.objects.get(id=challenge_platform_id).delete()
res = {}
status = 200
except DoesNotExist:
status = 404
res = Error("The specified resource was not found", status)
except Exception as error:
status = 500
res = Error("Internal error", status, str(error))
return res, status


def get_challenge_platform(challenge_platform_id): # noqa: E501
"""Get a challenge platform

Returns the challenge platform specified # noqa: E501

:param challenge_platform_id: The ID of the challenge platform
:type challenge_platform_id: str

:rtype: ChallengePlatform
"""
res = None
status = None
try:
db_platform = DbChallengePlatform.objects.get(id=challenge_platform_id)
res = ChallengePlatform.from_dict(db_platform.to_dict())
status = 200
except DoesNotExist:
status = 404
res = Error("The specified resource was not found", status)
except Exception as error:
status = 500
res = Error("Internal error", status, str(error))
return res, status


def list_challenge_platforms(limit=None, offset=None): # noqa: E501
"""Get all challenge platforms

Returns the challenge platforms # noqa: E501

:param limit: Maximum number of results returned
:type limit: int
:param offset: Index of the first result that must be returned
:type offset: int

:rtype: PageOfChallengePlatforms
"""
res = None
status = None
try:
db_platforms = DbChallengePlatform.objects().skip(offset).limit(limit)
platforms = [ChallengePlatform.from_dict(d.to_dict()) for d in db_platforms]
next_ = ""
if len(platforms) == limit:
next_ = "%s/challengePlatforms?limit=%s&offset=%s" % \
(Config().server_api_url, limit, offset + limit)

# Get total results count.
total = db_platforms.count()

res = PageOfChallengePlatforms(
offset=offset,
limit=limit,
paging={
"next": next_
},
total_results=total,
challenge_platforms=platforms)
status = 200
except TypeError: # TODO: may need different exception
status = 400
res = Error("Bad request", status)
except Exception as error:
status = 500
res = Error("Internal error", status, str(error))
return res, status
2 changes: 1 addition & 1 deletion server/openapi_server/controllers/grant_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def list_grants(limit=None, offset=None):
(Config().server_api_url, limit, offset + limit)

# Get total results count.
total = DbGrant.objects.count()
total = db_grants.count()

res = PageOfGrants(
offset=offset,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def list_organizations(limit=None, offset=None):
(Config().server_api_url, limit, offset + limit)

# Get total results count.
total = DbOrganization.objects.count()
total = db_orgs.count()

res = PageOfOrganizations(
offset=offset,
Expand Down
2 changes: 1 addition & 1 deletion server/openapi_server/controllers/person_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def list_persons(limit=None, offset=None, filter_=None):
(Config().server_api_url, limit, offset + limit)

# Get total results count.
total = DbPerson.objects.count()
total = db_persons.count()

res = PageOfPersons(
offset=offset,
Expand Down
2 changes: 1 addition & 1 deletion server/openapi_server/controllers/tag_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def list_tags(limit=None, offset=None, filter_=None):
(Config().server_api_url, limit, offset + limit)

# Get total results count.
total = DbTag.objects.count()
total = db_tags.count()

res = PageOfTags(
offset=offset,
Expand Down
2 changes: 1 addition & 1 deletion server/openapi_server/controllers/user_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def list_users(limit=None, offset=None):
(Config().server_api_url, limit, offset + limit)

# Get total results count.
total = DbUser.objects.count()
total = db_users.count()

res = PageOfUsers(
offset=offset,
Expand Down
11 changes: 8 additions & 3 deletions server/openapi_server/dbmodels/challenge.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from bson import ObjectId
import datetime
from mongoengine import Document, DateTimeField, ListField, ReferenceField, StringField, URLField, ObjectIdField # noqa: E501

# from openapi_server.dbmodels.challenge_results import ChallengeResults
from openapi_server.dbmodels.tag import Tag
from openapi_server.dbmodels.person import Person
from openapi_server.dbmodels.organization import Organization
from openapi_server.dbmodels.challenge_platform import ChallengePlatform
from openapi_server.dbmodels.grant import Grant
from openapi_server.dbmodels.organization import Organization
from openapi_server.dbmodels.person import Person
from openapi_server.dbmodels.tag import Tag


class Challenge(Document):
Expand All @@ -24,6 +26,9 @@ class Challenge(Document):
organizerIds = ListField(ReferenceField(Person))
dataProviderIds = ListField(ReferenceField(Organization))
grantIds = ListField(ReferenceField(Grant))
platformId = ReferenceField(ChallengePlatform)
createdAt = DateTimeField(required=True, default=datetime.datetime.now)
updatedAt = DateTimeField(required=True, default=datetime.datetime.now)
# challengeResults = EmbeddedDocumentField(ChallengeResults)

def to_dict(self):
Expand Down
16 changes: 16 additions & 0 deletions server/openapi_server/dbmodels/challenge_platform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import datetime
from mongoengine import DateTimeField, Document, StringField, URLField


class ChallengePlatform(Document):
id = StringField(primary_key=True)
name = StringField(required=True, unique=True)
url = URLField(required=True)
createdAt = DateTimeField(required=True, default=datetime.datetime.now)
updatedAt = DateTimeField(required=True, default=datetime.datetime.now)

def to_dict(self):
doc = self.to_mongo().to_dict()
doc['id'] = str(self.pk)
doc.pop('_id', None)
return doc
7 changes: 7 additions & 0 deletions server/openapi_server/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
from __future__ import absolute_import
# import models into model package
from openapi_server.models.challenge import Challenge
from openapi_server.models.challenge_all_of import ChallengeAllOf
from openapi_server.models.challenge_create_request import ChallengeCreateRequest
from openapi_server.models.challenge_create_response import ChallengeCreateResponse
from openapi_server.models.challenge_filter import ChallengeFilter
from openapi_server.models.challenge_platform import ChallengePlatform
from openapi_server.models.challenge_platform_all_of import ChallengePlatformAllOf
from openapi_server.models.challenge_platform_create_request import ChallengePlatformCreateRequest
from openapi_server.models.challenge_platform_create_response import ChallengePlatformCreateResponse
from openapi_server.models.challenge_status import ChallengeStatus
from openapi_server.models.error import Error
from openapi_server.models.grant import Grant
Expand All @@ -16,6 +21,8 @@
from openapi_server.models.organization import Organization
from openapi_server.models.organization_create_request import OrganizationCreateRequest
from openapi_server.models.organization_create_response import OrganizationCreateResponse
from openapi_server.models.page_of_challenge_platforms import PageOfChallengePlatforms
from openapi_server.models.page_of_challenge_platforms_all_of import PageOfChallengePlatformsAllOf
from openapi_server.models.page_of_challenges import PageOfChallenges
from openapi_server.models.page_of_challenges_all_of import PageOfChallengesAllOf
from openapi_server.models.page_of_grants import PageOfGrants
Expand Down
Loading