Introduction to ZapEHR Z3

ZapEHR supports the storage and retrieval of files like insurance cards and medical records using the Z3 Service. The Z3 Service provides functionality similar to AWS S3 and other cloud file-hosting services.

The Z3 Service provides cloud-consolidated file storage so you can manage file permissions with the same Access Policies that define which other resources Actors can access within ZapEHR.

Z3 Design

The storage units of Z3 are Buckets and Objects.

  • Buckets are a container for storing files.
  • Objects are individual files.

Objects are contained inside Buckets.

Here are two Buckets, example-bucket-1 and example-bucket-2, containing a couple of Objects.

Bucket names must be unique, and Object names must be unique within a Bucket.

How to use Z3

This outlines a theoretical list of steps for setting up and using Z3. For an example of an implementation, refer to the next section.

The TypeScript SDK has a function to make these steps easier. Refer to the TypeScript SDK Z3 documentation to learn how it works.

  1. Create a Z3 Bucket (opens in a new tab).
  2. Get a presigned URL to upload your file (opens in a new tab). A presigned URL is what provides the permissions needed to upload a file. Be careful with this URL — anyone with access to it can upload a file to it. By default, presigned URLs will no longer be active after 15 minutes.
  3. Upload a file to this URL.
  4. Get a presigned URL to download your file (opens in a new tab). This will return a presigned URL with the permissions needed to download a file. As with before, this URL gives access to download the file, so be careful sharing it. It is also active for 15 minutes.
  5. Download the file using this URL.

Example implementing Z3 with Python

Let's go through an example of uploading and retrieving a file using Python. We'll upload a CSV (Comma-Separated Values) file from data.gov (opens in a new tab), Fruit and Vegetable Consumption in California Residents, 2012/2013 (opens in a new tab).

This data is formatted like:

Year,Age Group,Category,Type,Five or more servings of fruits and vegetables (%)
2012,Adolescent (12-17),All ,Total,40.2
2012,Adolescent (12-17),Gender,Male,37.3
2012,Adolescent (12-17),Gender,Female,43.3
2012,Adolescent (12-17),Gender by Age- Male,12-13,35.2
2012,Adolescent (12-17),Gender by Age- Male,14-15,42.1

To get a token, refer to our documentation on Authenticating API Requests.

First, we make a Z3 Bucket with the name fruit-vegetables — this is where we'll store the file.

import requests
 
requests.put('https://project-api.zapehr.com/v1/z3/fruit-vegetables',
  headers={
    'Authorization': f"Bearer {token}"
  }
)
 

Now we retrieve an URL which we will use to upload the file.

upload_request = requests.post("https://project-api.zapehr.com/v1/z3/fruit-vegetables/fruit-and-vegetable-consumption-in-california-residents-2012-2013-.csv",
  headers={
    "Authorization": f"Bearer {token}"
  },
  data=json.dumps({
    "action": "upload"
  })
)
 
upload_url = upload_request.json()["signedUrl"]

Next we open the file and upload it.

information = open("fruit-and-vegetable-consumption-in-california-residents-2012-2013-.csv", "rb").read()
requests.put(upload_url, data=information)

Our file has now been uploaded. To download it we get a presigned URL.

download_request = requests.post("https://project-api.zapehr.com/v1/z3/fruit-vegetables/fruit-and-vegetable-consumption-in-california-residents-2012-2013-.csv",
  headers={
    "Authorization": f"Bearer {token}"
  },
  data=json.dumps({
    "action": "download"
  })
)
 
download_url = download_request.json()["signedUrl"]
print(download_url)

Here is the full code.

import requests
import json
 
token = "put_a_token_here"
 
create_request = requests.put("https://project-api.zapehr.com/v1/z3/fruit-vegetables",
  headers={
    "Authorization": f"Bearer {token}"
  }
)
 
print(create_request.json())
 
upload_request = requests.post("https://project-api.zapehr.com/v1/z3/fruit-vegetables/fruit-and-vegetable-consumption-in-california-residents-2012-2013-.csv",
  headers={
    "Authorization": f"Bearer {token}"
  },
  data=json.dumps({
    "action": "upload"
  })
)
print(upload_request.json())
upload_url = upload_request.json()["signedUrl"]
 
information = open("fruit-and-vegetable-consumption-in-california-residents-2012-2013-.csv", "rb").read()
requests.put(upload_url, data=information)
 
download_request = requests.post("https://project-api.zapehr.com/v1/z3/fruit-vegetables/fruit-and-vegetable-consumption-in-california-residents-2012-2013-.csv",
  headers={
    "Authorization": f"Bearer {token}"
  },
  data=json.dumps({
    "action": "download"
  })
)
 
download_url = download_request.json()["signedUrl"]
print(download_url)
 
t = requests.get("https://project-api.zapehr.com/v1/z3/fruit-vegetables",
  headers={
    "Authorization": f"Bearer {token}"
  }
)
print(t.json())