Skip to content
This repository was archived by the owner on Oct 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ jobs:
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/int.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ jobs:
name: Integration Tests

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install requirements
Expand Down
106 changes: 62 additions & 44 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,68 @@ on:

jobs:
push_to_registry:
name: Push Beacon Docker image to Docker Hub
name: Push beacon python Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Login to DockerHub Registry
run: echo '${{ secrets.DOCKER_PASSWORD }}' | docker login -u '${{ secrets.DOCKER_USERNAME }}' --password-stdin
- name: Get the version
id: vars
run: echo ::set-output name=tag::$(echo ${GITHUB_REF:10})
- name: Build the tagged Docker image
if: ${{ steps.vars.outputs.tag != '/master' }}
run: docker build . --file Dockerfile --tag cscfi/beacon-python:${{steps.vars.outputs.tag}}
- name: Push the tagged Docker image
if: ${{ steps.vars.outputs.tag != '/master' }}
run: docker push cscfi/beacon-python:${{steps.vars.outputs.tag}}
- name: Build the latest Docker image
if: ${{ steps.vars.outputs.tag == '/master' }}
run: docker build . --file Dockerfile --tag cscfi/beacon-python:latest
- name: Push the latest Docker image
if: ${{ steps.vars.outputs.tag == '/master' }}
run: docker push cscfi/beacon-python:latest
push_data_to_registry:
name: Push Dataloader Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Login to DockerHub Registry
run: echo '${{ secrets.DOCKER_PASSWORD }}' | docker login -u '${{ secrets.DOCKER_USERNAME }}' --password-stdin
- name: Get the version
id: vars
run: echo ::set-output name=tag::$(echo ${GITHUB_REF:10})
- name: Build the tagged Docker image
if: ${{ steps.vars.outputs.tag != '/master' }}
run: |
pushd deploy/dataloader
docker build . --file Dockerfile --tag cscfi/beacon-dataloader:${{steps.vars.outputs.tag}}
- name: Push the tagged Docker image
if: ${{ steps.vars.outputs.tag != '/master' }}
run: docker push cscfi/beacon-dataloader:${{steps.vars.outputs.tag}}
- name: Build the latest Docker image
if: ${{ steps.vars.outputs.tag == '/master' }}
- name: Check out the repo
uses: actions/checkout@v2

- name: Prepare
id: prep
run: |
pushd deploy/dataloader
docker build . --file Dockerfile --tag cscfi/beacon-dataloader:latest
- name: Push the latest Docker image
if: ${{ steps.vars.outputs.tag == '/master' }}
run: docker push cscfi/beacon-dataloader:latest
DOCKER_IMAGE=cscfi/beacon-python
DOCKER_IMAGE_DATA=cscfi/beacon-python
VERSION=edge
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
elif [[ $GITHUB_REF == refs/heads/* ]]; then
BRANCH=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
if [[ $BRANCH == master ]]; then
VERSION=latest
fi
fi
TAGS="${DOCKER_IMAGE}:${VERSION}"
TAGS_DATA="${DOCKER_IMAGE_DATA}:${VERSION}"
echo ::set-output name=version::${VERSION}
echo ::set-output name=tags::${TAGS}
echo ::set-output name=tagsData::${TAGS_DATA}
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
cache-from: type=registry,ref=cscfi/beacon-python:latest
cache-to: type=inline
labels: |
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}

- name: Build and push dataloader
uses: docker/build-push-action@v2
with:
context: .
file: ./deploy/dataloader/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tagsData }}
cache-from: type=registry,ref=cscfi/swift-ui:latest
cache-to: type=inline
labels: |
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}

4 changes: 2 additions & 2 deletions .github/workflows/style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ jobs:
max-parallel: 4
matrix:
os: [ubuntu-latest]
python-version: [3.6, 3.7]
python-version: [3.7]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ jobs:
max-parallel: 4
matrix:
os: [ubuntu-latest]
python-version: [3.6, 3.7.7]
python-version: [3.7.7]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
Expand Down
76 changes: 38 additions & 38 deletions beacon_api/api/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,32 @@
from ..conf import CONFIG_INFO


def process_exception_data(request: Dict,
host: str,
error_code: int,
error: str) -> Dict:
def process_exception_data(request: Dict, host: str, error_code: int, error: str) -> Dict:
"""Return request data as dictionary.

Generates custom exception messages based on request parameters.
"""
data = {'beaconId': '.'.join(reversed(host.split('.'))),
"apiVersion": __apiVersion__,
'exists': None,
'error': {'errorCode': error_code,
'errorMessage': error},
'alleleRequest': {'referenceName': request.get("referenceName", None),
'referenceBases': request.get("referenceBases", None),
'includeDatasetResponses': request.get("includeDatasetResponses", "NONE"),
'assemblyId': request.get("assemblyId", None)},
# showing empty datasetsAlleRsponse as no datasets found
# A null/None would represent no data while empty array represents
# none found or error and corresponds with exists null/None
'datasetAlleleResponses': []}
data = {
"beaconId": ".".join(reversed(host.split("."))),
"apiVersion": __apiVersion__,
"exists": None,
"error": {"errorCode": error_code, "errorMessage": error},
"alleleRequest": {
"referenceName": request.get("referenceName", None),
"referenceBases": request.get("referenceBases", None),
"includeDatasetResponses": request.get("includeDatasetResponses", "NONE"),
"assemblyId": request.get("assemblyId", None),
},
# showing empty datasetsAlleRsponse as no datasets found
# A null/None would represent no data while empty array represents
# none found or error and corresponds with exists null/None
"datasetAlleleResponses": [],
}
# include datasetIds only if they are specified
# as per specification if they don't exist all datatsets will be queried
# Only one of `alternateBases` or `variantType` is required, validated by schema
oneof_fields = ["alternateBases", "variantType", "start", "end", "startMin", "startMax",
"endMin", "endMax", "datasetIds"]
data['alleleRequest'].update({k: request.get(k) for k in oneof_fields if k in request})
oneof_fields = ["alternateBases", "variantType", "start", "end", "startMin", "startMax", "endMin", "endMax", "datasetIds"]
data["alleleRequest"].update({k: request.get(k) for k in oneof_fields if k in request})

return data

Expand All @@ -49,12 +48,11 @@ class BeaconBadRequest(web.HTTPBadRequest):
Used in conjunction with JSON Schema validator.
"""

def __init__(self, request: Dict,
host: str, error: str) -> None:
def __init__(self, request: Dict, host: str, error: str) -> None:
"""Return custom bad request exception."""
data = process_exception_data(request, host, 400, error)
super().__init__(text=json.dumps(data), content_type="application/json")
LOG.error(f'401 ERROR MESSAGE: {error}')
LOG.error(f"401 ERROR MESSAGE: {error}")


class BeaconUnauthorised(web.HTTPUnauthorized):
Expand All @@ -64,17 +62,21 @@ class BeaconUnauthorised(web.HTTPUnauthorized):
Used in conjunction with Token authentication aiohttp middleware.
"""

def __init__(self, request: Dict,
host: str, error: str, error_message: str) -> None:
def __init__(self, request: Dict, host: str, error: str, error_message: str) -> None:
"""Return custom unauthorized exception."""
data = process_exception_data(request, host, 401, error)
headers_401 = {"WWW-Authenticate": f"Bearer realm=\"{CONFIG_INFO.url}\"\n\
error=\"{error}\"\n\
error_description=\"{error_message}\""}
super().__init__(content_type="application/json", text=json.dumps(data),
# we use auth scheme Bearer by default
headers=headers_401)
LOG.error(f'401 ERROR MESSAGE: {error}')
headers_401 = {
"WWW-Authenticate": f'Bearer realm="{CONFIG_INFO.url}"\n\
error="{error}"\n\
error_description="{error_message}"'
}
super().__init__(
content_type="application/json",
text=json.dumps(data),
# we use auth scheme Bearer by default
headers=headers_401,
)
LOG.error(f"401 ERROR MESSAGE: {error}")


class BeaconForbidden(web.HTTPForbidden):
Expand All @@ -85,12 +87,11 @@ class BeaconForbidden(web.HTTPForbidden):
but not granted the resource. Used in conjunction with Token authentication aiohttp middleware.
"""

def __init__(self, request: Dict,
host: str, error: str) -> None:
def __init__(self, request: Dict, host: str, error: str) -> None:
"""Return custom forbidden exception."""
data = process_exception_data(request, host, 403, error)
super().__init__(content_type="application/json", text=json.dumps(data))
LOG.error(f'403 ERROR MESSAGE: {error}')
LOG.error(f"403 ERROR MESSAGE: {error}")


class BeaconServerError(web.HTTPInternalServerError):
Expand All @@ -101,7 +102,6 @@ class BeaconServerError(web.HTTPInternalServerError):

def __init__(self, error: str) -> None:
"""Return custom forbidden exception."""
data = {'errorCode': 500,
'errorMessage': error}
data = {"errorCode": 500, "errorMessage": error}
super().__init__(content_type="application/json", text=json.dumps(data))
LOG.error(f'500 ERROR MESSAGE: {error}')
LOG.error(f"500 ERROR MESSAGE: {error}")
Loading