Skip to content

Commit

Permalink
Merge pull request #78 from jjjermiah/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
jjjermiah committed Feb 3, 2024
2 parents 0050eda + 11a0c89 commit 94ae9aa
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 16 deletions.
27 changes: 20 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
# push to any branch
branches: [ main ]
pull_request:
branches: [ main ]
branches: [ main , development]

jobs:
Continuous-Integration:
Expand Down Expand Up @@ -77,7 +77,7 @@ jobs:
# needs: Continuous-Integration

# if pulling to main, deploy to PyPI
if: github.ref == 'refs/heads/main'
# if: github.ref == 'refs/heads/main'

# Set up operating system
runs-on: ubuntu-latest
Expand Down Expand Up @@ -257,12 +257,21 @@ jobs:
Update-README:
needs: Continuous-Deployment
runs-on: ubuntu-latest
# if: github.ref == 'refs/heads/development'
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Pull latest changes
run: git pull
- name: Get Current branch
run: |
echo "Current branch is: ${{ github.ref }}"
echo "Current branch is: ${{ github.head_ref }}"
echo "Current branch is: ${{ github.base_ref }}"
echo "Current branch is: ${{ github.event_name }}"
# fix diverged branch
git fetch origin ${{ github.head_ref }}
git checkout ${{ github.head_ref }}
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
Expand All @@ -271,7 +280,11 @@ jobs:

- name: Install using PyPi
run: |
pip install nbiatoolkit;
# update pip
pip install --upgrade pip
# make sure pypi packages are up to date
pip install --upgrade nbiatoolkit
NBIAToolkit
- name: Update README code block
Expand Down Expand Up @@ -306,10 +319,10 @@ jobs:
git add .
# Commit with a timestamp
git commit -m "Auto commit: $(date)"
git commit -m "Update README with latest version: $LATEST_TAG"
# Push changes to the remote repository
git push origin main
git push origin HEAD:${{ github.head_ref }}
echo "Changes committed and pushed successfully."
else
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ nbia-toolkit also provides a command line interface (CLI) to query the NBIA data
/_/ |_/_____/___/_/ |_/_/ \____/\____/_/_/|_/_/\__/


Version: 0.19.1
Version: 0.19.2

Available CLI tools:

Expand Down
73 changes: 72 additions & 1 deletion docs/Tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -393,6 +393,77 @@
"pprint(patients[0:5])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### getNewPatients In Collection\n",
"\n",
"``` python\n",
"getNewPatients(\n",
" Collection: str, # (required)\n",
" Date: str, # (required) accepted formats:\n",
" # \"%Y-%m-%d\", \"%Y/%m/%d\", \"%Y%m%d\", \n",
" # \"%m/%d/%Y\", \"%d/%m/%Y\", \"%d-%m-%Y\"\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Total new patients in TCGA-BLCA after 2019-01-01: 15\n",
"[{'Collection': 'TCGA-BLCA',\n",
" 'PatientId': 'TCGA-4Z-AA86',\n",
" 'PatientName': 'TCGA-4Z-AA86',\n",
" 'PatientSex': 'M',\n",
" 'Phantom': 'NO',\n",
" 'SpeciesCode': '337915000',\n",
" 'SpeciesDescription': 'Homo sapiens'},\n",
" {'Collection': 'TCGA-BLCA',\n",
" 'PatientId': 'TCGA-G2-A2EC',\n",
" 'PatientName': 'TCGA-G2-A2EC',\n",
" 'PatientSex': 'F',\n",
" 'Phantom': 'NO',\n",
" 'SpeciesCode': '337915000',\n",
" 'SpeciesDescription': 'Homo sapiens'},\n",
" {'Collection': 'TCGA-BLCA',\n",
" 'EthnicGroup': 'W',\n",
" 'PatientId': 'TCGA-G2-A2EF',\n",
" 'PatientName': 'TCGA-G2-A2EF',\n",
" 'PatientSex': 'M',\n",
" 'Phantom': 'NO',\n",
" 'SpeciesCode': '337915000',\n",
" 'SpeciesDescription': 'Homo sapiens'},\n",
" {'Collection': 'TCGA-BLCA',\n",
" 'PatientId': 'TCGA-G2-A2EJ',\n",
" 'PatientName': 'TCGA-G2-A2EJ',\n",
" 'PatientSex': 'F',\n",
" 'Phantom': 'NO',\n",
" 'SpeciesCode': '337915000',\n",
" 'SpeciesDescription': 'Homo sapiens'},\n",
" {'Collection': 'TCGA-BLCA',\n",
" 'EthnicGroup': 'W',\n",
" 'PatientId': 'TCGA-G2-A2EK',\n",
" 'PatientName': 'TCGA-G2-A2EK',\n",
" 'PatientSex': 'M',\n",
" 'Phantom': 'NO',\n",
" 'SpeciesCode': '337915000',\n",
" 'SpeciesDescription': 'Homo sapiens'}]\n"
]
}
],
"source": [
"newPatients = client.getNewPatients(Collection=\"TCGA-BLCA\", Date=\"2019-01-01\")\n",
"print(f\"Total new patients in TCGA-BLCA after 2019-01-01: {len(newPatients)}\")\n",
"pprint(newPatients[0:5])"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
30 changes: 29 additions & 1 deletion src/nbiatoolkit/nbia.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .auth import OAuth2
from .logger.logger import setup_logger
from .utils import NBIA_ENDPOINTS, validateMD5, clean_html, convertMillis
from .utils import NBIA_ENDPOINTS, validateMD5, clean_html, convertMillis, convertDateFormat
from .dicomsort import DICOMSorter

import requests
Expand Down Expand Up @@ -172,6 +172,34 @@ def getPatients(self, Collection: str = "") -> Union[list[dict[str, str]], None]

return patientList

def getNewPatients(self, Collection: str, Date: str) -> Union[list[dict[str, str]], None]:
assert Collection is not None
assert Date is not None

# convert date to %Y/%m/%d format
Date = convertDateFormat(input_date=Date, format="%Y/%m/%d")

PARAMS = self.parsePARAMS(locals())

response = self.query_api(endpoint=NBIA_ENDPOINTS.GET_NEW_PATIENTS_IN_COLLECTION, params=PARAMS)
assert isinstance(response, list), "Expected list, but received: %s" % type(response)

patientList = []
for patient in response:
assert isinstance(patient, dict), "Expected dict, but received: %s" % type(
patient
)
assert "PatientId" in patient, "PatientId not in patient dict"
assert isinstance(
patient["PatientId"], str
), "PatientId must be a string, but received: %s" % type(
patient["PatientId"]
)

patientList.append(patient)

return patientList

def getPatientsByCollectionAndModality(
self, Collection: str, Modality: str
) -> Union[list[str], None]:
Expand Down
4 changes: 2 additions & 2 deletions src/nbiatoolkit/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .nbia_endpoints import NBIA_ENDPOINTS
from .md5 import validateMD5
from .parsers import convertMillis, clean_html
__all__ = ["NBIA_ENDPOINTS", "validateMD5", "convertMillis", "clean_html"]
from .parsers import convertMillis, clean_html, convertDateFormat
__all__ = ["NBIA_ENDPOINTS", "validateMD5", "convertMillis", "clean_html", "convertDateFormat"]
2 changes: 1 addition & 1 deletion src/nbiatoolkit/utils/nbia_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ class NBIA_ENDPOINTS(Enum):
GET_MODALITY_VALUES = "v2/getModalityValues"

GET_PATIENTS = "v2/getPatient"
GET_NEW_PATIENTS_IN_COLLECTION = "v2/NewPatientsInCollection"
GET_PATIENT_BY_COLLECTION_AND_MODALITY = "v2/getPatientByCollectionAndModality"
GET_BODY_PART_PATIENT_COUNT = "getBodyPartValuesAndCounts"
GET_NEW_PATIENTS_IN_COLLECTION = "NewPatientsInCollection"

GET_STUDIES = "v2/getPatientStudy"

Expand Down
31 changes: 30 additions & 1 deletion src/nbiatoolkit/utils/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,33 @@ def convertMillis(millis: int) -> str:
AssertionError: If the input is not an integer.
"""
assert isinstance(millis, int), "The input must be an integer"
return datetime.fromtimestamp(millis / 1000.0).strftime('%Y-%m-%d')
return datetime.fromtimestamp(millis / 1000.0).strftime('%Y-%m-%d')


def convertDateFormat(input_date: str, format: str = "%Y/%m/%d") -> str:
"""
Converts the input date to the desired format.
Args:
input_date (str): The date to be converted.
Returns:
str: The converted date in the format "YYYY/MM/DD".
Raises:
ValueError: If the input date has an invalid format.
"""
# List of possible date formats with only days, months, and years
possible_formats = [
"%Y-%m-%d", "%Y/%m/%d", "%Y%m%d", "%m/%d/%Y", "%d/%m/%Y", "%d-%m-%Y"
]
# Try parsing the input date with each possible format
for date_format in possible_formats:
try:
parsed_date = datetime.strptime(input_date, date_format)
# If parsing is successful, format the date in YYYY/MM/DD and return
return parsed_date.strftime(format)
except ValueError:
pass # If parsing fails, continue with the next format
# If none of the formats match, raise an exception or return a default value
raise ValueError("Invalid date format: {}".format(input_date))
16 changes: 16 additions & 0 deletions tests/test_nbia.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,22 @@ def test_getPatients(nbia_patients):
assert "Collection" in nbia_patients[0]
assert "PatientSex" in nbia_patients[0]

def test_getNewPatients(nbia_client):
patients = nbia_client.getNewPatients('TCGA-BLCA', Date = "2019-01-01")
assert isinstance(patients, list)
assert len(patients) > 0
assert isinstance(patients[0], dict)
assert "PatientId" in patients[0]
assert "PatientName" in patients[0]
assert "Collection" in patients[0]
assert "PatientSex" in patients[0]

def test_failed_getNewPatients(nbia_client):
with pytest.raises(Exception):
patients = nbia_client.getNewPatients('TCGA-BLCA', Date = "bad_date")
with pytest.raises(Exception):
patients = nbia_client.getNewPatients('bad_collection', Date = "2019-01-01")

def test_getPatientsByCollectionAndModality(nbia_patientsByCollectionAndModality):
assert isinstance(nbia_patientsByCollectionAndModality, list)
assert len(nbia_patientsByCollectionAndModality) > 0
Expand Down
26 changes: 24 additions & 2 deletions tests/test_parsers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from src.nbiatoolkit.utils.parsers import clean_html, convertMillis
from src.nbiatoolkit.utils.parsers import clean_html, convertMillis, convertDateFormat
from datetime import datetime
import pytest


def test_clean_html_valid_input():
# Test case for valid input with HTML tags and special characters
html_string = "<p>This is <b>bold</b> text with special characters: &amp; &lt; &gt;</p>"
Expand Down Expand Up @@ -41,4 +43,24 @@ def test_convertMillis_invalid_input():
convertMillis(millis) # type: ignore
assert False, "Expected AssertionError"
except AssertionError as e:
assert str(e) == "The input must be an integer"
assert str(e) == "The input must be an integer"


def test_convertDateFormat_valid_input():
# Test case for valid input date in different formats
input_date = "2021-09-01"
expected_output = "2021/09/01"
assert convertDateFormat(input_date) == expected_output

def test_convertDateFormat_invalid_input():
# Test case for invalid input date format
input_date = "shoulD_fail" # Invalid format: day-month-year
with pytest.raises(ValueError) as e:
convertDateFormat(input_date)
assert str(e.value) == "Invalid date format: {}".format(input_date)

def test_convertDateFormat_default_value():
# Test case for input date with no matching format
input_date = "2021/09/01"
default_value = "N/A"
assert convertDateFormat(input_date, default_value) == default_value

0 comments on commit 94ae9aa

Please sign in to comment.