Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

37: add example script to create or update a form #83

Merged
merged 1 commit into from
May 3, 2024
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
6 changes: 5 additions & 1 deletion docs/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ A script that uses mail merge to create personalized Word documents with data fr

## [October 2022 webinar materials](2022-10-pyodk-webinar.ipynb)

A Jupyter notebook companion to an October 2022 webinar by Hélène Martin introducing `pyodk`. Includes link to the session recording.
A Jupyter notebook companion to an October 2022 webinar by Hélène Martin introducing `pyodk`. Includes link to the session recording.

## [Create or Update Form script](create_or_update_form/create_or_update_form.py)

A script to create or update a form, optionally with attachments.
60 changes: 60 additions & 0 deletions docs/examples/create_or_update_form/create_or_update_form.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import sys
from os import PathLike
from pathlib import Path

from pyodk.client import Client
from pyodk.errors import PyODKError
from requests import Response

"""
A script to create or update a form, optionally with attachments.

Either use as a CLI script, or import create_or_update into another module.

If provided, all files in the [attachments_dir] path will be uploaded with the form.
"""


def create_ignore_duplicate_error(client: Client, definition: PathLike | str | bytes):
"""Create the form; ignore the error raised if it exists (409.3)."""
try:
client.forms.create(definition=definition)
except PyODKError as err:
if len(err.args) >= 2 and isinstance(err.args[1], Response):
err_detail = err.args[1].json()
err_code = err_detail.get("code")
if err_code is not None and str(err_code) == "409.3":
return
raise


def create_or_update(form_id: str, definition: str, attachments: str | None):
"""Create (and publish) the form, optionally with attachments."""
with Client() as client:
create_ignore_duplicate_error(client=client, definition=definition)
attach = None
if attachments is not None:
attach = Path(attachments).iterdir()
client.forms.update(
definition=definition,
form_id=form_id,
attachments=attach,
)


if __name__ == "__main__":
usage = """
Usage:

python create_or_update_form.py form_id definition.xlsx
python create_or_update_form.py form_id definition.xlsx attachments_dir
"""
if len(sys.argv) < 3:
print(usage)
sys.exit(1)
fid = sys.argv[1]
def_path = sys.argv[2]
attach_path = None
if len(sys.argv) == 4:
attach_path = sys.argv[3]
create_or_update(form_id=fid, definition=def_path, attachments=attach_path)
1 change: 1 addition & 0 deletions docs/examples/create_or_update_form/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pyodk==1.0.0
6 changes: 3 additions & 3 deletions tests/resources/forms_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def get_xml__range_draft(

def get_md__pull_data(version: str | None = None) -> str:
if version is None:
version = datetime.now().isoformat()
version = datetime.now(UTC).isoformat()
return f"""
| settings |
| | version |
Expand All @@ -106,7 +106,7 @@ def get_md__pull_data(version: str | None = None) -> str:
| survey | | | | |
| | type | name | label | calculation |
| | calculate | fruit | | pulldata('fruits', 'name', 'name_key', 'mango') |
| | note | note_fruit | The fruit ${{fruit}} pulled from csv | |
| | note | note_fruit | The fruit ${fruit} pulled from csv | |
"""
md__dingbat = """
| settings |
Expand All @@ -115,5 +115,5 @@ def get_md__pull_data(version: str | None = None) -> str:
| survey | | | | |
| | type | name | label | calculation |
| | calculate | fruit | | pulldata('fruits', 'name', 'name_key', 'mango') |
| | note | note_fruit | The fruit ${{fruit}} pulled from csv | |
| | note | note_fruit | The fruit ${fruit} pulled from csv | |
"""
30 changes: 22 additions & 8 deletions tests/utils/forms.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
from os import PathLike

from pyodk.client import Client
from pyodk.errors import PyODKError
from requests import Response

from tests.utils import utils
from tests.utils.md_table import md_table_to_temp_dir


def create_ignore_duplicate_error(
client: Client,
definition: PathLike | str | bytes,
form_id: str,
):
"""Create the form; ignore the error raised if it exists (409.3)."""
try:
client.forms.create(definition=definition, form_id=form_id)
except PyODKError as err:
if len(err.args) >= 2 and isinstance(err.args[1], Response):
err_detail = err.args[1].json()
err_code = err_detail.get("code")
if err_code is not None and str(err_code) == "409.3":
return
raise


def create_new_form__md(client: Client, form_id: str, form_def: str):
"""
Create a new form from a MarkDown string.
Expand All @@ -16,10 +36,7 @@ def create_new_form__md(client: Client, form_id: str, form_def: str):
with (
md_table_to_temp_dir(form_id=form_id, mdstr=form_def) as fp,
):
try:
client.forms.create(definition=fp, form_id=form_id)
except PyODKError:
pass
create_ignore_duplicate_error(client=client, definition=fp, form_id=form_id)


def create_new_form__xml(client: Client, form_id: str, form_def: str):
Expand All @@ -32,10 +49,7 @@ def create_new_form__xml(client: Client, form_id: str, form_def: str):
"""
with utils.get_temp_file(suffix=".xml") as fp:
fp.write_text(form_def)
try:
client.forms.create(definition=fp, form_id=form_id)
except PyODKError:
pass
create_ignore_duplicate_error(client=client, definition=fp, form_id=form_id)


def get_latest_form_version(client: Client, form_id: str) -> str:
Expand Down
Loading