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

Allow uploading attachment files alongside a submission #105

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

spwoodcock
Copy link

@spwoodcock spwoodcock commented Nov 21, 2024

This PR

If easier, #103 and #104 could be closed and this reviewed & merged all in one go.

What has been done to verify that this works as intended?

I added a test to upload 3 attachment files to one submission:

image

Why is this the best possible solution? Were any other approaches considered?

  • It solves a requirement provided from an existing issue.
  • The other approach would be to expect the user to create the submission, then upload attachments separately.
  • I think this is a nice addition though, making life significantly easier to creating a submission+attachment combo.

How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?

  • This shouldn't really impact the existing API.
  • It's additive only changes to the submission create.

Does this change require updates to documentation? If so, please file an issue here and include the link below.

  • Updates to the pyodk docs!
  • Will look into that if this PR is approved.

Before submitting this PR, please make sure you have:

  • included test cases for core behavior and edge cases in tests
  • run python -m unittest and verified all tests pass
  • run ruff format pyodk tests and ruff check pyodk tests to lint code
  • verified that any code or assets from external sources are properly credited in comments

@spwoodcock spwoodcock force-pushed the feat/attachments-with-submissions branch from 6102c67 to 9dc61fe Compare February 11, 2025 20:15
@spwoodcock spwoodcock force-pushed the feat/attachments-with-submissions branch from 9dc61fe to 59963d2 Compare February 11, 2025 20:30
@@ -66,6 +67,11 @@ def __init__(
self.submissions: SubmissionService = SubmissionService(
session=self.session, default_project_id=self.project_id
)
self.submission_attachments: SubmissionAttachmentService = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove from client - the current use case is to upload submission + attachments at the same time, rather than separately.

instance_id = submission.instanceId

# If there are attachments, upload each one
if attachments:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the pattern in form.create e.g. raise an error rather than just log. Conversion to Path is the responsibility of upload - have a look at form_draft_attachments which uses pv.validate_file_path to handle conversion from string (if necessary).

@@ -201,6 +201,8 @@ def create(
project_id: int | None = None,
device_id: str | None = None,
encoding: str = "utf-8",
# Here we must use imported typing.List to avoid conflict with .list method
attachments: builtins.list[str] | None = None,
Copy link
Contributor

@lindsay-stevens lindsay-stevens Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you using an old python version? I think the list annotation is OK for all current versions. The previous equivalent was to using typing.List, not builtins. Anyway that's besides the point - we just need something to feed the for loop i.e. Iterable[PathLike | str] (see forms.create).


def upload(
self,
file_path_or_bytes: PathLike | str | bytes,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the forms.create process where it's assumed file paths are passed in. If using bytes is needed please open a ticket for that so we can think about doing that consistently across endpoints that currently accept file paths.

@lindsay-stevens
Copy link
Contributor

Could you please rebase on the main branch? It seems like #104 has some of these changes here but not all of them so I'm not sure I understand the purpose of that PR. Also it seems like #103 was force pushed so I'll need to review again. Generally it will make it easier to review without all the model changes stuff.

Another thing needed before this can be merged is a real (E2E) test case. I've been putting those in test_client.py - it should be able to create what it needs to run, as long as it's a valid project ID and the user has privileges. Do you have an instance of Central that you can test with? Or do you have access to the ODK dev/staging instances? This is needed to verify that it works with current Central, sanity check against the original requirement (#102), and provide example code that use case. Sometimes the use cases are polished up into a module for docs - if you want to do that as well it would be appreciated.

@spwoodcock
Copy link
Author

spwoodcock commented Feb 12, 2025

You told me the commit history had too many commits referencing formatting. So I squashed them into one commit per PR 😅

Is there a preferred way you would like commits to be made?

(meaning do you intend to squash them on merge, should I minimise the number of commits if they are going directly to main, or something else?)

@spwoodcock
Copy link
Author

Could you please rebase on the main branch? It seems like #104 has some of these changes here but not all of them so I'm not sure I understand the purpose of that PR. Also it seems like #103 was force pushed so I'll need to review again. Generally it will make it easier to review without all the model changes stuff.

Another thing needed before this can be merged is a real (E2E) test case. I've been putting those in test_client.py - it should be able to create what it needs to run, as long as it's a valid project ID and the user has privileges. Do you have an instance of Central that you can test with? Or do you have access to the ODK dev/staging instances? This is needed to verify that it works with current Central, sanity check against the original requirement (#102), and provide example code that use case. Sometimes the use cases are polished up into a module for docs - if you want to do that as well it would be appreciated.

Sure, I can give that a go!

I have multiple ODK instances to test with, no worries. I generally test with a containerised Central.

I am using this code in production now & all seems to be well. Unfortunately I use pytest for all the test cases using this functionality, but I can look at writing some stdlib unittest instead 👍

@spwoodcock
Copy link
Author

spwoodcock commented Feb 12, 2025

Also, as mentioned in each PR, they anticipate the merge of the previous as they rely in code from the previous PR.

(1) Pydantic V2 models --> (2) Submission attachment service --> (3) Using the submission attachment service to upload attachments during submission.

So rebasing with main isn't possible unfortunately 😬

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Extend submission.create to support attachments
2 participants