From ea1e3971c510af69addb8f5be4b7893736c5c067 Mon Sep 17 00:00:00 2001 From: spwoodcock Date: Wed, 11 Mar 2026 13:53:54 +0000 Subject: [PATCH] feat: add create_user sdk option, matching update to QFieldCloud API --- qfieldcloud_sdk/sdk.py | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/qfieldcloud_sdk/sdk.py b/qfieldcloud_sdk/sdk.py index 103e4fb..657caa9 100644 --- a/qfieldcloud_sdk/sdk.py +++ b/qfieldcloud_sdk/sdk.py @@ -330,6 +330,51 @@ def logout(self) -> None: return resp.json() + def create_user( + self, + username: str, + password: str, + email: str = "", + exist_ok: bool = False, + ) -> Optional[Dict[str, Any]]: + """Create a new QFieldCloud user account (staff only). + + Requires the authenticated token to belong to a staff user. + + Args: + username: The username for the new account. Must be 3-150 characters + and contain only letters, numbers, ``-`` and ``_``. + password: The password for the new account. + email: Optional email address. When omitted, QFieldCloud defaults to + ``@noreply.local``. + exist_ok: When *True*, return ``None`` silently if the username is + already taken (HTTP 409) instead of raising. Defaults to False. + + Returns: + A dictionary with the public user info of the newly created account, + or ``None`` when *exist_ok* is True and the user already exists. + + Raises: + QfcRequestException: On any HTTP error other than 409, or on 409 + when *exist_ok* is False. + + Example: + ```python + client.create_user("field_mapper_42", "s3cr3t", exist_ok=True) + ``` + """ + try: + resp = self._request( + "POST", + "users", + data={"username": username, "password": password, "email": email}, + ) + return resp.json() + except QfcRequestException as exc: + if exist_ok and exc.response.status_code == 409: + return None + raise + def check_server_status(self) -> Dict[str, Any]: """Checks the status of the QFieldCloud server.