Skip to content

Instantly share code, notes, and snippets.

@lognaturel
Last active January 23, 2023 23:12
Show Gist options
  • Save lognaturel/e1f0e7cc46c7eacada0b8bfa8c0a72d4 to your computer and use it in GitHub Desktop.
Save lognaturel/e1f0e7cc46c7eacada0b8bfa8c0a72d4 to your computer and use it in GitHub Desktop.
Download all latest submission attachments for a given form_id
from pyodk.client import Client
import json
from functools import reduce
import urllib.parse
import os.path
def get_attachment_fields():
schema_r = client.get(f"projects/{client.config.central.default_project_id}/forms/{FORM_ID}/fields?odata=true")
schema = schema_r.json()
return [field for field in schema if field['binary']]
# https://stackoverflow.com/a/52260663/137744
def recursive_get(data_dict, path):
try:
return reduce(dict.get, path, data_dict)
except TypeError:
return None
def save_all_attachments(form_id, path="media"):
attachment_fields = get_attachment_fields()
for submission in data:
submission_id = submission["__id"]
submission_url = f"projects/{client.config.central.default_project_id}/forms/{FORM_ID}/submissions/{submission_id}"
for field in attachment_fields:
attachment_path = field["path"].lstrip("/").split("/")
attachment_filename = recursive_get(submission, attachment_path)
if attachment_filename is not None:
attachment_r = client.get(f"{submission_url}/attachments/{urllib.parse.quote(attachment_filename)}")
if attachment_r.status_code == 200:
attachment_path = os.path.join(path, attachment_filename)
os.makedirs(os.path.dirname(attachment_path), exist_ok=True)
with open(attachment_path, "wb") as f:
f.write(attachment_r.content)
else:
print(f"{attachment_r.status_code} for {attachment_filename} in {submission_id}")
attachment_r.raise_for_status()
FORM_ID = "all-widgets"
client = Client().open()
data = client.submissions.get_table(form_id=FORM_ID)['value']
save_all_attachments(FORM_ID)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment