From 8e4501a872fb3967483bcee83668d5d2fec436e7 Mon Sep 17 00:00:00 2001 From: Rakanhf Date: Tue, 10 Feb 2026 18:02:09 +0300 Subject: [PATCH] feat: add upload_project_thumbnail command to sdk and cli A new endpoint was introduced to upload project thumbnail - Added a new command to sdk and cli to upload project thumbnail --- qfieldcloud_sdk/cli.py | 20 ++++++++++++++++++++ qfieldcloud_sdk/sdk.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/qfieldcloud_sdk/cli.py b/qfieldcloud_sdk/cli.py index 19feda8..f2279e7 100755 --- a/qfieldcloud_sdk/cli.py +++ b/qfieldcloud_sdk/cli.py @@ -365,6 +365,26 @@ def delete_project(ctx: Context, project_id): log(f'Deleted project "{project_id}".') +@cli.command() +@click.argument("project_id") +@click.argument( + "local_filename", + type=click.Path(exists=True, file_okay=True, dir_okay=False, readable=True), +) +@click.pass_context +def upload_project_thumbnail( + ctx: Context, project_id: str, local_filename: str +) -> None: + """Upload a project thumbnail.""" + + response = ctx.obj["client"].upload_project_thumbnail(project_id, local_filename) + + if ctx.obj["format_json"]: + print_json(response) + else: + log(f'Uploaded thumbnail "{local_filename}" to project "{project_id}".') + + @cli.command() @click.argument("project_id") @click.argument("project_path") diff --git a/qfieldcloud_sdk/sdk.py b/qfieldcloud_sdk/sdk.py index 9b10eef..3d99954 100644 --- a/qfieldcloud_sdk/sdk.py +++ b/qfieldcloud_sdk/sdk.py @@ -603,6 +603,41 @@ def patch_project( return resp.json() + def upload_project_thumbnail( + self, + project_id: str, + local_filename: str, + ) -> requests.Response: + """Upload a project thumbnail. + + Args: + project_id: Project ID. + local_filename: Path to the thumbnail image file. + + Raises: + pathvalidate.ValidationError: Raised when the uploaded file does not have a valid filename. + + Returns: + The response object from the upload request. + + Example: + ```python + client.upload_project_thumbnail( + project_id="123e4567-e89b-12d3-a456-426614174000", + local_filename="thumbnail.png" + ) + ``` + """ + # if the filepath is invalid, it will throw a new error `pathvalidate.ValidationError` + is_valid_filepath(local_filename) + + with open(local_filename, "rb") as thumbnail: + return self._request( + "POST", + f"projects/{project_id}/thumbnail", + files={"thumbnail": thumbnail}, + ) + def upload_files( self, project_id: str,