# Google Health API

**URL:** <https://discourse.slicer.org/t/google-health-api/12927>\
**Category:** Support\
**Tags:** dicom\
**Created:** [August 10, 2020, 2:11pm UTC](https://discourse.slicer.org/t/google-health-api/12927 "2020-08-10T14:11:33Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![howardlander](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/howardlander/32/5881_2.png) [@howardlander](https://discourse.slicer.org/u/howardlander)\
**Post date:** [August 10, 2020, 2:11pm UTC](https://discourse.slicer.org/t/google-health-api/12927/1 "2020-08-10T14:11:33Z")

</div>

Has anyone tried to feed DICOM data to the Slicer from the Google Health API? If so, any advice on how to do so?

Thanks  
Howard

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [August 10, 2020, 2:36pm UTC](https://discourse.slicer.org/t/google-health-api/12927/2 "2020-08-10T14:36:06Z")

</div>

Hi @howardlander - I’ve tinkered with this. The [dicomweb-client](https://pypi.org/project/dicomweb-client/) python package bundled with Slicer. To talk with Google’s DICOMweb one needs to include the authentication token, which can be obtained either through the `gcloud auth print-access-token` once you have logged in.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [August 10, 2020, 2:37pm UTC](https://discourse.slicer.org/t/google-health-api/12927/3 "2020-08-10T14:37:18Z")

</div>

It would be good to add an example to the script repository for this. I can work on it with someone if needed.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [August 10, 2020, 2:41pm UTC](https://discourse.slicer.org/t/google-health-api/12927/4 "2020-08-10T14:41:09Z")

</div>

I have added an example here:

[https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#How\_to\_import\_DICOM\_files\_using\_DICOMweb](https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#How_to_import_DICOM_files_using_DICOMweb)

---

<div class="post-metadata">

**Author:** ![howardlander](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/howardlander/32/5881_2.png) [@howardlander](https://discourse.slicer.org/u/howardlander)\
**Post date:** [August 10, 2020, 2:57pm UTC](https://discourse.slicer.org/t/google-health-api/12927/5 "2020-08-10T14:57:07Z")

</div>

Hi Andras: I’ve looked at your example. In the case of Google Health, how would I specify the project, region, dataset that I would like to download? Also, I guess there is nothing in the slicer GUI that would let you login to to Google and get the token without the command line?

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [August 10, 2020, 3:06pm UTC](https://discourse.slicer.org/t/google-health-api/12927/6 "2020-08-10T15:06:37Z")

</div>

Here’s an example that works in a colab notebook. We’d need to port the gcloud syntax to work with Slicer.

```auto
!pip install dicomweb-client

token = !gcloud auth print-access-token
token = token[0]

PROJECT_ID="chc-tcia"
REGION="us-central1"

DATASET_ID="qin-headneck"
DICOM_STORE_ID=DATASET_ID

url = f"https://healthcare.googleapis.com/v1beta1/projects/{PROJECT_ID}/locations/{REGION}/datasets/{DATASET_ID}/dicomStores/{DICOM_STORE_ID}/dicomWeb"
headers = {
    "Authorization" : "Bearer %s" % token
}

import dicomweb_client

client = dicomweb_client.api.DICOMwebClient(url, headers=headers)
studies = client.search_for_studies()

print(f"\n{len(studies)} studies to query\n")

for study in studies:
  studyMetadata = dicomweb_client.api.load_json_dataset(study)
  if hasattr(studyMetadata, "ModalitiesInStudy"):
    print(f"Modalities: {studyMetadata.ModalitiesInStudy}")
  else:
    print("Modalities not defined")
  series = client.search_for_series(studyMetadata.StudyInstanceUID)
  print(f" {len(series)} series")
  for serie in series:
    seriesMetadata = dicomweb_client.api.load_json_dataset(serie)
    instances = client.search_for_instances(
      study_instance_uid=studyMetadata.StudyInstanceUID,
      series_instance_uid=seriesMetadata.SeriesInstanceUID
    )
    print(f" {len(instances)} instances ", end="", flush=True)
  print()

```

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [August 10, 2020, 3:09pm UTC](https://discourse.slicer.org/t/google-health-api/12927/7 "2020-08-10T15:09:18Z")

</div>

> [@howardlander](#):
>
> In the case of Google Health, how would I specify the project, region, dataset that I would like to download?

We developed and tested `importFromDICOMWeb` helper function with Kheops, but it is just a [short Python code snippet](https://github.com/Slicer/Slicer/blob/47c291530bb37f4687eb7a9cfbc7a76f5685bd3e/Modules/Scripted/DICOMLib/DICOMUtils.py#L746-L803), so it should be easy to change the API to work with Google Health API, too. Or, maybe we should add a more generic version of this function (which does not download a complete study but selected series only). @pieper’s example above probably contains all the necessary pieces.

It would be great if you could create this function and contribute it back to Slicer.

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [August 10, 2020, 3:10pm UTC](https://discourse.slicer.org/t/google-health-api/12927/8 "2020-08-10T15:10:06Z")

</div>

The other option for doing the login and getting the token would be to use the browser. We looked at this at the last project week.

> **[ProjectWeek](https://projectweek.na-mic.org/PW33_2020_GranCanaria/Projects/OHIFSlicerBridge/)**
>
> Website for NA-MIC Project Weeks

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [August 10, 2020, 3:16pm UTC](https://discourse.slicer.org/t/google-health-api/12927/9 "2020-08-10T15:16:32Z")

</div>

The qSlicerWebWidget could be used to do the login and then we can uses the python/javascript interoperability to pull pass the token into Slicer to use with dicomweb\_client.

---

<div class="post-metadata">

**Author:** ![howardlander](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/howardlander/32/5881_2.png) [@howardlander](https://discourse.slicer.org/u/howardlander)\
**Post date:** [August 10, 2020, 3:25pm UTC](https://discourse.slicer.org/t/google-health-api/12927/10 "2020-08-10T15:25:21Z")

</div>

This is all interesting and useful to me, though I will have to spend some time with it, as I am a Slicer novice. One thing is that I suppose this would be easier if I had all of the DICOM urls in advance. Since we are planning to build a cohort selection tool, that is a real possibility.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [August 10, 2020, 4:06pm UTC](https://discourse.slicer.org/t/google-health-api/12927/11 "2020-08-10T16:06:40Z")

</div>

Probably the simplest is to just use Slicer’s built-in Pyhon console (Ctrl/Cmd-3). That is a standard Python environment that should already have all the Python packages that you need preinstalled (but you can install more, if needed) and also has all Slicer features available. Let us know if you make progress or get stuck at any point.

---

<div class="post-metadata">

**Author:** ![howardlander](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/howardlander/32/5881_2.png) [@howardlander](https://discourse.slicer.org/u/howardlander)\
**Post date:** [August 10, 2020, 4:57pm UTC](https://discourse.slicer.org/t/google-health-api/12927/12 "2020-08-10T16:57:21Z")

</div>

Steve: how would I try the qSlicerWebWidget?

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [August 10, 2020, 6:48pm UTC](https://discourse.slicer.org/t/google-health-api/12927/13 "2020-08-10T18:48:19Z")

</div>

Hi Howard -

This is something I’ve known was possible for a while but hadn’t had a driving use case to make an example, so thanks for the push to sort out the details. I’ll be needing this soon myself.

First, you can use the web widget (which is basically Chrome) to access an installation of OHIF with the Google API enabled. In my case I have one in firebase, but any https static server on a domain name you control will work for OIDC (unless you explicitly accept it, mine will give a warning about being unverified, so you can choose to try it or not at your peril).

Paste this in the python console:

```auto
ww = slicer.qSlicerWebWidget()
ww.show()
ww.url = "https://idc-sandbox-000.firebaseapp.com/"

```

Then, when you have logged in, use this to get the access token and current page info:

```auto
import json
ww.connect("evalResult(QString,QString)", lambda statement, result: print (json.loads(result)))

ww.evalJS("JSON.stringify([window.store.getState().oidc.user.access_token, window.location.href])")

```

Here’s an example output (with a few characters changed in the token to make it invalid).

```auto
['ya29.a0AfH6SSB_ageiit7LFdkDtzvVpi8fs5-0FJlqFuJnTVWHHU2tnNUzRoEPUTP9F-zMhAMMhHlQQvMxXJj2DVILO2PAPrj0xxKjbP1625rXXgfGWfl4mnRRspuxcCEcuNklu6fu-zW60iZR6rKg69WVTQMYUkHayt8QvaS6yw', 'https://idc-sandbox-000.firebaseapp.com/projects/chc-tcia/locations/us-central1/datasets/ct-lymph-nodes/dicomStores/ct-lymph-nodes/study/61.7.276186995443132562163463641799779941762']

```

This should be all the ingredients needed to use the dicomweb\_client code from within Slicer to read and write via dicomweb.

The Google mirror of TCIA requires approval to access, but you can also access any dicom store, such as one you create under your own account.
