diff --git a/dropbox/base.py b/dropbox/base.py index e95b8a6..74148b3 100644 --- a/dropbox/base.py +++ b/dropbox/base.py @@ -4505,6 +4505,79 @@ def paper_folders_create(self, name, parent_folder_id=None, is_team_folder=None) # ------------------------------------------ # Routes in riviera namespace + def riviera_download_transform_output(self, output_handle): + """ + Download the output of a completed `get_transform_async` job. Pass the + `output_handle` from the job's `complete` result. The body is the + produced file, and the `Dropbox-API-Result` header describes it. A + handle can only be redeemed by the user who requested the transform, and + only until its `expires_ts`; after that this route fails with + `expired_handle_error`, and the transform has to be requested again. A + handle that was never valid, or that belongs to another user, fails with + `user_error`. + + Route attributes: + scope: files.content.read + + :param output_handle: The `output_handle` from a `complete` + `get_transform_async/check` result. + :type output_handle: str + :rtype: (:class:`dropbox.riviera.DownloadTransformOutputResult`, + :class:`requests.models.Response`) + :raises: :class:`.exceptions.ApiError` + + If this raises, ApiError will contain: + :class:`dropbox.riviera.TransformApiV2Error` + + If you do not consume the entire response body, then you must call close + on the response object, otherwise you will max out your available + connections. We recommend using the `contextlib.closing + `_ + context manager to ensure this. + """ + arg = riviera.DownloadTransformOutputArgs(output_handle) + r = self.request( + riviera.download_transform_output, + "riviera", + arg, + None, + ) + return r + + def riviera_download_transform_output_to_file(self, download_path, output_handle): + """ + Download the output of a completed `get_transform_async` job. Pass the + `output_handle` from the job's `complete` result. The body is the + produced file, and the `Dropbox-API-Result` header describes it. A + handle can only be redeemed by the user who requested the transform, and + only until its `expires_ts`; after that this route fails with + `expired_handle_error`, and the transform has to be requested again. A + handle that was never valid, or that belongs to another user, fails with + `user_error`. + + Route attributes: + scope: files.content.read + + :param str download_path: Path on local machine to save file. + :param output_handle: The `output_handle` from a `complete` + `get_transform_async/check` result. + :type output_handle: str + :rtype: :class:`dropbox.riviera.DownloadTransformOutputResult` + :raises: :class:`.exceptions.ApiError` + + If this raises, ApiError will contain: + :class:`dropbox.riviera.TransformApiV2Error` + """ + arg = riviera.DownloadTransformOutputArgs(output_handle) + r = self.request( + riviera.download_transform_output, + "riviera", + arg, + None, + ) + self._save_body_to_file(download_path, r[1]) + return r[0] + def riviera_get_keyframes_async( self, file_id_or_url=None, scene_change_threshold=0.0, include_images=False ): @@ -4927,6 +5000,105 @@ def riviera_get_transcript_async_check(self, async_job_id): ) return r + def riviera_get_transform_async( + self, transform_type, file_id_or_url=None, thumbnail=None, image=None, video_frame=None + ): + """ + Asynchronous file transformation: produces a new file from an existing + one. One route covers many conversions. Name the source file in + `file_id_or_url`, say what you want back in `transform_type`, and supply + that type's options message if it needs one: - `pdf`: documents and + images, to PDF. - `html`: spreadsheets, to HTML, preserving the sheet + layout. - `image`: images and single document pages, to JPEG or PNG. - + `thumbnail`: any thumbnailable source, resized to a named size bucket. - + `image_pdf`: documents, to a page image rendered by way of PDF. - + `video_frame`: one still frame from a video, at a requested offset. The + accepted input formats differ per transform -- they are not one shared + list -- and each is the intersection of the source format with the + pipeline that transform uses: - `pdf` and `image_pdf`: word-processing, + presentation and spreadsheet documents (.doc, .docx, .ppt, .pptx, .xls, + .xlsx, .odt, .odp, .ods, .rtf, .epub, .gdoc, .gslides, .hwp, .ai, .eps, + .dwg among others). Images are not accepted. - `html`: spreadsheets only + -- .xls, .xlsm, .xlsx, .ods, .gsheet. This is the complete list. Note + that .csv and .txt are *not* accepted here. - `image`: the documents + above, plus .pdf and .html, plus the iWork and design formats .pages, + .key, .numbers, .sketch, .xd, .indd and .psd, plus .avif, .heic, .svg + and camera RAW, plus fonts (.otf, .ttf), plus video. Formats a browser + can already display (.bmp, .gif, .ico, .jpeg, .png, .tif, .tiff, .webp) + are not accepted; use `thumbnail` for those. - `thumbnail`: everything + `image` accepts, plus .bmp, .gif, .ico, .jpeg, .png, .tif, .tiff, .webp + and JPEG 2000. - `video_frame`: .3g2, .3gp, .3gpp, .3gpp2, .asf, .avi, + .dv, .flv, .m2t, .m2ts, .m4v, .mkv, .mov, .mp4, .mpeg, .mpg, .mts, .mxf, + .ogv, .rm, .ts, .vob, .webm, .wmv. This is the complete list. These + lists track Riviera's capability registry + (`dropbox/riviera/supported_types/previews_supported_types.yaml`), which + is generated and authoritative; treat it rather than this comment as the + final word. Formats the requested transform does not support fail with + `unsupported_format_error`. Options belonging to a different transform + type than the one requested fail with `invalid_options_error`. The + produced bytes are not returned by this route, and not by its `/check` + poll either. Poll `get_transform_async/check` with the returned async + job ID until it reports `complete` or `failed`; a `complete` result + carries a `TransformOutput` whose `output_handle` + `download_transform_output` exchanges for the bytes. Splitting retrieval + out this way is what lets the route return outputs larger than an async + result can carry. + + Route attributes: + scope: files.content.read + + :param file_id_or_url: Identifier of the source file to transform. + Callers must set exactly one of the `FileIdOrUrl` variants. The + referenced file must be in a format the requested `transform_type` + supports; see the route description for the per-transform format + lists. Requests against unsupported formats fail with + `unsupported_format_error`. + :type file_id_or_url: Nullable[:class:`dropbox.riviera.FileIdOrUrl`] + :param transform_type: What to produce from the source file. Required. + :type transform_type: :class:`dropbox.riviera.TransformType` + :param thumbnail: Options for `TransformType.thumbnail`. + :type thumbnail: Nullable[:class:`dropbox.riviera.ThumbnailOptions`] + :param image: Options for `TransformType.image` and + `TransformType.image_pdf`. + :type image: Nullable[:class:`dropbox.riviera.ImageOptions`] + :param video_frame: Options for `TransformType.video_frame`. + :type video_frame: Nullable[:class:`dropbox.riviera.VideoFrameOptions`] + :rtype: :class:`dropbox.async_.LaunchResultBase` + """ + arg = riviera.TransformArgs(transform_type, file_id_or_url, thumbnail, image, video_frame) + r = self.request( + riviera.get_transform_async, + "riviera", + arg, + None, + ) + return r + + def riviera_get_transform_async_check(self, async_job_id): + """ + Returns the status or result of specified get_transform_async task. + + Route attributes: + scope: files.content.read + + :param async_job_id: Id of the asynchronous job. This is the value of a + response returned from the method that launched the job. + :type async_job_id: str + :rtype: :class:`dropbox.riviera.GetTransformAsyncCheckResult` + :raises: :class:`.exceptions.ApiError` + + If this raises, ApiError will contain: + :class:`dropbox.async_.PollError` + """ + arg = async_.PollArg(async_job_id) + r = self.request( + riviera.get_transform_async_check, + "riviera", + arg, + None, + ) + return r + # ------------------------------------------ # Routes in sharing namespace diff --git a/dropbox/base_team.py b/dropbox/base_team.py index 08e0137..4259962 100644 --- a/dropbox/base_team.py +++ b/dropbox/base_team.py @@ -2264,6 +2264,58 @@ def team_members_suspend(self, user, wipe_data=True): ) return None + def team_members_suspend_batch(self, members): + """ + Launch a member suspension batch. The server enforces a maximum of 500 + members. + + Route attributes: + scope: members.write + + :param members: Must contain between 1 and 500 targets. The launch + handler also rejects duplicate client item IDs and duplicate member + selectors. + :type members: List[:class:`dropbox.team.MembersSuspendBatchTarget`] + :rtype: :class:`dropbox.async_.LaunchResultBase` + :raises: :class:`.exceptions.ApiError` + + If this raises, ApiError will contain: + :class:`dropbox.team.MembersSuspendBatchError` + """ + arg = team.MembersSuspendBatchArg(members) + r = self.request( + team.members_suspend_batch, + "team", + arg, + None, + ) + return r + + def team_members_suspend_batch_job_status_check(self, async_job_id): + """ + Poll a previously launched member suspension batch job. + + Route attributes: + scope: members.write + + :param async_job_id: Id of the asynchronous job. This is the value of a + response returned from the method that launched the job. + :type async_job_id: str + :rtype: :class:`dropbox.team.MembersSuspendBatchJobStatus` + :raises: :class:`.exceptions.ApiError` + + If this raises, ApiError will contain: + :class:`dropbox.async_.PollError` + """ + arg = async_.PollArg(async_job_id) + r = self.request( + team.members_suspend_batch_job_status_check, + "team", + arg, + None, + ) + return r + def team_members_unsuspend(self, user): """ Unsuspend a member from a team. Permission : Team member management diff --git a/dropbox/riviera.py b/dropbox/riviera.py index a962464..57f67bf 100644 --- a/dropbox/riviera.py +++ b/dropbox/riviera.py @@ -1063,6 +1063,89 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): ContentApiV2Error_validator = bv.Union(ContentApiV2Error) +class DownloadTransformOutputArgs(bb.Struct): + """ + Arguments for `download_transform_output`. + + :ivar DownloadTransformOutputArgs.output_handle: + The `output_handle` from a `complete` `get_transform_async/check` + result. + """ + + __slots__ = [ + "_output_handle_value", + ] + + _has_required_fields = True + + def __init__(self, output_handle=None): + self._output_handle_value = bb.NOT_SET + if output_handle is not None: + self.output_handle = output_handle + + # Instance attribute type: str (validator is set below) + output_handle = bb.Attribute("output_handle") + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(DownloadTransformOutputArgs, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +DownloadTransformOutputArgs_validator = bv.Struct(DownloadTransformOutputArgs) + + +class DownloadTransformOutputResult(bb.Struct): + """ + Describes the bytes in the response body. Returned in the + `Dropbox-API-Result` header. + + :ivar DownloadTransformOutputResult.size: + Size of the output in bytes. + :ivar DownloadTransformOutputResult.format: + Format of the output, as a short lowercase format name such as "pdf", + "html", "jpeg", or "png". + :ivar DownloadTransformOutputResult.mime_type: + MIME type corresponding to `format`. + """ + + __slots__ = [ + "_size_value", + "_format_value", + "_mime_type_value", + ] + + _has_required_fields = False + + def __init__(self, size=None, format=None, mime_type=None): + self._size_value = bb.NOT_SET + self._format_value = bb.NOT_SET + self._mime_type_value = bb.NOT_SET + if size is not None: + self.size = size + if format is not None: + self.format = format + if mime_type is not None: + self.mime_type = mime_type + + # Instance attribute type: int (validator is set below) + size = bb.Attribute("size") + + # Instance attribute type: str (validator is set below) + format = bb.Attribute("format") + + # Instance attribute type: str (validator is set below) + mime_type = bb.Attribute("mime_type") + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(DownloadTransformOutputResult, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +DownloadTransformOutputResult_validator = bv.Struct(DownloadTransformOutputResult) + + class FileIdOrUrl(bb.Union): """ This class acts as a tagged union. Only one of the ``is_*`` methods will @@ -2373,6 +2456,165 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): GetTranscriptResult_validator = bv.Struct(GetTranscriptResult) +class GetTransformAsyncCheckResult(bb.Union): + """ + Result type for EventBus async check - must end in "CheckResult" + + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + + :ivar GetTransformAsyncCheckResult.in_progress: + The job has not finished yet. Poll again. + :ivar GetTransformAsyncCheckResult.complete: + The job finished successfully. + :vartype GetTransformAsyncCheckResult.complete: TransformOutput + :ivar GetTransformAsyncCheckResult.failed: + The job finished unsuccessfully. + :vartype GetTransformAsyncCheckResult.failed: TransformApiV2Error + """ + + _catch_all = "other" + # Attribute is overwritten below the class definition + in_progress = None + # Attribute is overwritten below the class definition + other = None + + @classmethod + def complete(cls, val): + """ + Create an instance of this class set to the ``complete`` tag with value + ``val``. + + :param TransformOutput val: + :rtype: GetTransformAsyncCheckResult + """ + return cls("complete", val) + + @classmethod + def failed(cls, val): + """ + Create an instance of this class set to the ``failed`` tag with value + ``val``. + + :param TransformApiV2Error val: + :rtype: GetTransformAsyncCheckResult + """ + return cls("failed", val) + + def is_in_progress(self): + """ + Check if the union tag is ``in_progress``. + + :rtype: bool + """ + return self._tag == "in_progress" + + def is_complete(self): + """ + Check if the union tag is ``complete``. + + :rtype: bool + """ + return self._tag == "complete" + + def is_failed(self): + """ + Check if the union tag is ``failed``. + + :rtype: bool + """ + return self._tag == "failed" + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == "other" + + def get_complete(self): + """ + The job finished successfully. + + Only call this if :meth:`is_complete` is true. + + :rtype: TransformOutput + """ + if not self.is_complete(): + raise AttributeError("tag 'complete' not set") + return self._value + + def get_failed(self): + """ + The job finished unsuccessfully. + + Only call this if :meth:`is_failed` is true. + + :rtype: TransformApiV2Error + """ + if not self.is_failed(): + raise AttributeError("tag 'failed' not set") + return self._value + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(GetTransformAsyncCheckResult, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +GetTransformAsyncCheckResult_validator = bv.Union(GetTransformAsyncCheckResult) + + +class ImageOptions(bb.Struct): + """ + Options for `TransformType.image` and `TransformType.image_pdf`. Supplying + this message with any other transform type fails with + `invalid_options_error`. + + :ivar ImageOptions.page_number: + For multi-page sources (PDFs, presentations, documents), the 1-based + page to render. Each request renders one page; to render a whole + document, issue one request per page. Defaults to the first page when + omitted. + :ivar ImageOptions.scale_percent: + Scale the rendered image to this percentage of its natural size. Must be + in (0, 100] -- the pipeline does not upscale, so values above 100 are + rejected with `invalid_options_error`. Defaults to 100 (no scaling) when + omitted. + """ + + __slots__ = [ + "_page_number_value", + "_scale_percent_value", + ] + + _has_required_fields = False + + def __init__(self, page_number=None, scale_percent=None): + self._page_number_value = bb.NOT_SET + self._scale_percent_value = bb.NOT_SET + if page_number is not None: + self.page_number = page_number + if scale_percent is not None: + self.scale_percent = scale_percent + + # Instance attribute type: int (validator is set below) + page_number = bb.Attribute("page_number") + + # Instance attribute type: int (validator is set below) + scale_percent = bb.Attribute("scale_percent") + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(ImageOptions, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +ImageOptions_validator = bv.Struct(ImageOptions) + + class KeyframesExtractionApiV2Error(bb.Union): """ Reason a keyframe extraction job failed. Returned in the `failed` variant of @@ -3560,45 +3802,58 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): TextExtractionApiV2Error_validator = bv.Union(TextExtractionApiV2Error) -class TimestampLevel(bb.Union): +class ThumbnailFormat(bb.Union): """ - Granularity of the time offsets returned for each transcript segment. + The encoding of the produced image. These match `files/get_thumbnail`'s + formats: JPEG is the better choice for photographs, PNG for screenshots, + line art, and anything with sharp text edges or transparency. This class acts as a tagged union. Only one of the ``is_*`` methods will return true. To get the associated value of a tag (if one exists), use the corresponding ``get_*`` method. - :ivar TimestampLevel.sentence: - One segment per spoken sentence (recommended). This is the default when - ``GetTranscriptArgs.timestamp_level`` is omitted. - :ivar TimestampLevel.word: - One segment per word, useful for fine-grained alignment such as - captioning or highlight-as-you-listen experiences. + :ivar ThumbnailFormat.jpeg: + Lossy JPEG. The default, and the right choice for photographic sources. + :ivar ThumbnailFormat.png: + Lossless PNG, with alpha preserved. + :ivar ThumbnailFormat.webp: + WebP, which compresses better than either JPEG or PNG at comparable + quality but is not readable by every consumer. """ _catch_all = "other" # Attribute is overwritten below the class definition - sentence = None + jpeg = None # Attribute is overwritten below the class definition - word = None + png = None + # Attribute is overwritten below the class definition + webp = None # Attribute is overwritten below the class definition other = None - def is_sentence(self): + def is_jpeg(self): """ - Check if the union tag is ``sentence``. + Check if the union tag is ``jpeg``. :rtype: bool """ - return self._tag == "sentence" + return self._tag == "jpeg" - def is_word(self): + def is_png(self): """ - Check if the union tag is ``word``. + Check if the union tag is ``png``. :rtype: bool """ - return self._tag == "word" + return self._tag == "png" + + def is_webp(self): + """ + Check if the union tag is ``webp``. + + :rtype: bool + """ + return self._tag == "webp" def is_other(self): """ @@ -3609,116 +3864,1008 @@ def is_other(self): return self._tag == "other" def _process_custom_annotations(self, annotation_type, field_path, processor): - super(TimestampLevel, self)._process_custom_annotations( + super(ThumbnailFormat, self)._process_custom_annotations( annotation_type, field_path, processor ) -TimestampLevel_validator = bv.Union(TimestampLevel) +ThumbnailFormat_validator = bv.Union(ThumbnailFormat) -class MetadataUnion(bb.Union): +class ThumbnailMode(bb.Union): """ - The extracted metadata. Exactly one variant is populated, corresponding to - ``GetMetadataResult.metadata_type``. + How to resize and crop the source to reach the requested `ThumbnailSize`. + These match `files/get_thumbnail`'s modes. This class acts as a tagged union. Only one of the ``is_*`` methods will return true. To get the associated value of a tag (if one exists), use the corresponding ``get_*`` method. - :ivar MetadataUnion.exif: - EXIF metadata, for image files. - :vartype MetadataUnion.exif: ApiExifMetadata - :ivar MetadataUnion.media: - Container and per-stream metadata, for audio and video files. - :vartype MetadataUnion.media: ApiMediaMetadata - :ivar MetadataUnion.pdf: - Document metadata, for PDFs. - :vartype MetadataUnion.pdf: ApiPdfMetadata - :ivar MetadataUnion.office: - Document metadata, for MS Office files. - :vartype MetadataUnion.office: ApiOfficeMetadata + :ivar ThumbnailMode.strict: + Scale down the image to fit within the given size. + :ivar ThumbnailMode.bestfit: + Scale down the image to fit within the given size or its transpose. + :ivar ThumbnailMode.fitone_bestfit: + Scale down the image to completely cover the given size or its + transpose. + :ivar ThumbnailMode.original: + Don't resize the image at all. """ _catch_all = "other" # Attribute is overwritten below the class definition + strict = None + # Attribute is overwritten below the class definition + bestfit = None + # Attribute is overwritten below the class definition + fitone_bestfit = None + # Attribute is overwritten below the class definition + original = None + # Attribute is overwritten below the class definition other = None - @classmethod - def exif(cls, val): - """ - Create an instance of this class set to the ``exif`` tag with value - ``val``. - - :param ApiExifMetadata val: - :rtype: MetadataUnion - """ - return cls("exif", val) - - @classmethod - def media(cls, val): - """ - Create an instance of this class set to the ``media`` tag with value - ``val``. - - :param ApiMediaMetadata val: - :rtype: MetadataUnion - """ - return cls("media", val) - - @classmethod - def pdf(cls, val): - """ - Create an instance of this class set to the ``pdf`` tag with value - ``val``. - - :param ApiPdfMetadata val: - :rtype: MetadataUnion - """ - return cls("pdf", val) - - @classmethod - def office(cls, val): - """ - Create an instance of this class set to the ``office`` tag with value - ``val``. - - :param ApiOfficeMetadata val: - :rtype: MetadataUnion - """ - return cls("office", val) - - def is_exif(self): + def is_strict(self): """ - Check if the union tag is ``exif``. + Check if the union tag is ``strict``. :rtype: bool """ - return self._tag == "exif" + return self._tag == "strict" - def is_media(self): + def is_bestfit(self): """ - Check if the union tag is ``media``. + Check if the union tag is ``bestfit``. :rtype: bool """ - return self._tag == "media" + return self._tag == "bestfit" - def is_pdf(self): + def is_fitone_bestfit(self): """ - Check if the union tag is ``pdf``. + Check if the union tag is ``fitone_bestfit``. :rtype: bool """ - return self._tag == "pdf" + return self._tag == "fitone_bestfit" - def is_office(self): + def is_original(self): """ - Check if the union tag is ``office``. + Check if the union tag is ``original``. :rtype: bool """ - return self._tag == "office" + return self._tag == "original" + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == "other" + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(ThumbnailMode, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +ThumbnailMode_validator = bv.Union(ThumbnailMode) + + +class ThumbnailOptions(bb.Struct): + """ + Options for `TransformType.thumbnail`. Supplying this message with any other + transform type fails with `invalid_options_error`. + + :ivar ThumbnailOptions.size: + The size bucket to produce. Defaults to `w64h64` when omitted. + :ivar ThumbnailOptions.mode: + How to fit the source into `size`. Defaults to `strict` when omitted. + :ivar ThumbnailOptions.format: + The output encoding. Defaults to `jpeg` when omitted. + """ + + __slots__ = [ + "_size_value", + "_mode_value", + "_format_value", + ] + + _has_required_fields = False + + def __init__(self, size=None, mode=None, format=None): + self._size_value = bb.NOT_SET + self._mode_value = bb.NOT_SET + self._format_value = bb.NOT_SET + if size is not None: + self.size = size + if mode is not None: + self.mode = mode + if format is not None: + self.format = format + + # Instance attribute type: ThumbnailSize (validator is set below) + size = bb.Attribute("size", user_defined=True) + + # Instance attribute type: ThumbnailMode (validator is set below) + mode = bb.Attribute("mode", user_defined=True) + + # Instance attribute type: ThumbnailFormat (validator is set below) + format = bb.Attribute("format", user_defined=True) + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(ThumbnailOptions, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +ThumbnailOptions_validator = bv.Struct(ThumbnailOptions) + + +class ThumbnailSize(bb.Union): + """ + The size of the thumbnail to produce. These are the same named size buckets + `files/get_thumbnail` supports, with the same meanings; arbitrary pixel + dimensions are not accepted. + + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + + :ivar ThumbnailSize.w32h32: + 32 by 32 px. + :ivar ThumbnailSize.w64h64: + 64 by 64 px. + :ivar ThumbnailSize.w128h128: + 128 by 128 px. + :ivar ThumbnailSize.w256h256: + 256 by 256 px. + :ivar ThumbnailSize.w480h320: + 480 by 320 px. + :ivar ThumbnailSize.w640h480: + 640 by 480 px. + :ivar ThumbnailSize.w960h640: + 960 by 640 px. + :ivar ThumbnailSize.w1024h768: + 1024 by 768 px. + :ivar ThumbnailSize.w2048h1536: + 2048 by 1536 px. + """ + + _catch_all = "other" + # Attribute is overwritten below the class definition + w32h32 = None + # Attribute is overwritten below the class definition + w64h64 = None + # Attribute is overwritten below the class definition + w128h128 = None + # Attribute is overwritten below the class definition + w256h256 = None + # Attribute is overwritten below the class definition + w480h320 = None + # Attribute is overwritten below the class definition + w640h480 = None + # Attribute is overwritten below the class definition + w960h640 = None + # Attribute is overwritten below the class definition + w1024h768 = None + # Attribute is overwritten below the class definition + w2048h1536 = None + # Attribute is overwritten below the class definition + other = None + + def is_w32h32(self): + """ + Check if the union tag is ``w32h32``. + + :rtype: bool + """ + return self._tag == "w32h32" + + def is_w64h64(self): + """ + Check if the union tag is ``w64h64``. + + :rtype: bool + """ + return self._tag == "w64h64" + + def is_w128h128(self): + """ + Check if the union tag is ``w128h128``. + + :rtype: bool + """ + return self._tag == "w128h128" + + def is_w256h256(self): + """ + Check if the union tag is ``w256h256``. + + :rtype: bool + """ + return self._tag == "w256h256" + + def is_w480h320(self): + """ + Check if the union tag is ``w480h320``. + + :rtype: bool + """ + return self._tag == "w480h320" + + def is_w640h480(self): + """ + Check if the union tag is ``w640h480``. + + :rtype: bool + """ + return self._tag == "w640h480" + + def is_w960h640(self): + """ + Check if the union tag is ``w960h640``. + + :rtype: bool + """ + return self._tag == "w960h640" + + def is_w1024h768(self): + """ + Check if the union tag is ``w1024h768``. + + :rtype: bool + """ + return self._tag == "w1024h768" + + def is_w2048h1536(self): + """ + Check if the union tag is ``w2048h1536``. + + :rtype: bool + """ + return self._tag == "w2048h1536" + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == "other" + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(ThumbnailSize, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +ThumbnailSize_validator = bv.Union(ThumbnailSize) + + +class TimestampLevel(bb.Union): + """ + Granularity of the time offsets returned for each transcript segment. + + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + + :ivar TimestampLevel.sentence: + One segment per spoken sentence (recommended). This is the default when + ``GetTranscriptArgs.timestamp_level`` is omitted. + :ivar TimestampLevel.word: + One segment per word, useful for fine-grained alignment such as + captioning or highlight-as-you-listen experiences. + """ + + _catch_all = "other" + # Attribute is overwritten below the class definition + sentence = None + # Attribute is overwritten below the class definition + word = None + # Attribute is overwritten below the class definition + other = None + + def is_sentence(self): + """ + Check if the union tag is ``sentence``. + + :rtype: bool + """ + return self._tag == "sentence" + + def is_word(self): + """ + Check if the union tag is ``word``. + + :rtype: bool + """ + return self._tag == "word" + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == "other" + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(TimestampLevel, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +TimestampLevel_validator = bv.Union(TimestampLevel) + + +class TransformApiV2Error(bb.Union): + """ + Reason a transform job failed. Returned in the `failed` variant of + `GetTransformAsyncCheckResult`, and by `download_transform_output`. This is + a semantic error union: the HTTP status of the poll request itself is + unaffected (a poll that surfaces a failed job is still a normal successful + poll response). Callers should branch on the variant. + + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + + :ivar TransformApiV2Error.server_error: + An unexpected, typically transient, server-side failure. The string is a + human-readable message; retrying with backoff may succeed. + :vartype TransformApiV2Error.server_error: str + :ivar TransformApiV2Error.user_error: + The request could not be processed as supplied (a problem with the + caller's input). The string is a human-readable message; retrying the + same request will not help. + :vartype TransformApiV2Error.user_error: str + :ivar TransformApiV2Error.unsupported_format_error: + The source file is not in a format the requested `transform_type` can + convert. + :ivar TransformApiV2Error.link_download_disabled_error: + `FileIdOrUrl.url` referenced a Dropbox shared link whose owner has + disabled downloads. + :ivar TransformApiV2Error.shared_link_password_protected: + `FileIdOrUrl.url` referenced a password-protected Dropbox shared link. + Riviera cannot supply the password, so such links cannot be transformed. + :ivar TransformApiV2Error.limit_exceeded_error: + A resource limit was exceeded while producing the result -- for example + the source file is larger than the requested transform accepts. + :ivar TransformApiV2Error.conversion_failure_error: + The source file was readable but could not be converted, for example + because it is corrupt. + :ivar TransformApiV2Error.not_found_error: + The referenced file does not exist or is not accessible. + :ivar TransformApiV2Error.is_a_folder_error: + The target is a folder, not a file. + :ivar TransformApiV2Error.invalid_options_error: + `transform_type` was missing, or the supplied options did not match the + requested transform type, or an option was out of range. The request is + malformed; fix it rather than retrying it. + :ivar TransformApiV2Error.expired_handle_error: + The `output_handle` presented to `download_transform_output` has passed + its `TransformOutput.expires_ts`. Request the transform again to get a + fresh handle. Only `download_transform_output` produces this; a poll + never does. + """ + + _catch_all = "other" + # Attribute is overwritten below the class definition + unsupported_format_error = None + # Attribute is overwritten below the class definition + link_download_disabled_error = None + # Attribute is overwritten below the class definition + shared_link_password_protected = None + # Attribute is overwritten below the class definition + limit_exceeded_error = None + # Attribute is overwritten below the class definition + conversion_failure_error = None + # Attribute is overwritten below the class definition + not_found_error = None + # Attribute is overwritten below the class definition + is_a_folder_error = None + # Attribute is overwritten below the class definition + invalid_options_error = None + # Attribute is overwritten below the class definition + expired_handle_error = None + # Attribute is overwritten below the class definition + other = None + + @classmethod + def server_error(cls, val): + """ + Create an instance of this class set to the ``server_error`` tag with + value ``val``. + + :param str val: + :rtype: TransformApiV2Error + """ + return cls("server_error", val) + + @classmethod + def user_error(cls, val): + """ + Create an instance of this class set to the ``user_error`` tag with + value ``val``. + + :param str val: + :rtype: TransformApiV2Error + """ + return cls("user_error", val) + + def is_server_error(self): + """ + Check if the union tag is ``server_error``. + + :rtype: bool + """ + return self._tag == "server_error" + + def is_user_error(self): + """ + Check if the union tag is ``user_error``. + + :rtype: bool + """ + return self._tag == "user_error" + + def is_unsupported_format_error(self): + """ + Check if the union tag is ``unsupported_format_error``. + + :rtype: bool + """ + return self._tag == "unsupported_format_error" + + def is_link_download_disabled_error(self): + """ + Check if the union tag is ``link_download_disabled_error``. + + :rtype: bool + """ + return self._tag == "link_download_disabled_error" + + def is_shared_link_password_protected(self): + """ + Check if the union tag is ``shared_link_password_protected``. + + :rtype: bool + """ + return self._tag == "shared_link_password_protected" + + def is_limit_exceeded_error(self): + """ + Check if the union tag is ``limit_exceeded_error``. + + :rtype: bool + """ + return self._tag == "limit_exceeded_error" + + def is_conversion_failure_error(self): + """ + Check if the union tag is ``conversion_failure_error``. + + :rtype: bool + """ + return self._tag == "conversion_failure_error" + + def is_not_found_error(self): + """ + Check if the union tag is ``not_found_error``. + + :rtype: bool + """ + return self._tag == "not_found_error" + + def is_is_a_folder_error(self): + """ + Check if the union tag is ``is_a_folder_error``. + + :rtype: bool + """ + return self._tag == "is_a_folder_error" + + def is_invalid_options_error(self): + """ + Check if the union tag is ``invalid_options_error``. + + :rtype: bool + """ + return self._tag == "invalid_options_error" + + def is_expired_handle_error(self): + """ + Check if the union tag is ``expired_handle_error``. + + :rtype: bool + """ + return self._tag == "expired_handle_error" + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == "other" + + def get_server_error(self): + """ + An unexpected, typically transient, server-side failure. The string is a + human-readable message; retrying with backoff may succeed. + + Only call this if :meth:`is_server_error` is true. + + :rtype: str + """ + if not self.is_server_error(): + raise AttributeError("tag 'server_error' not set") + return self._value + + def get_user_error(self): + """ + The request could not be processed as supplied (a problem with the + caller's input). The string is a human-readable message; retrying the + same request will not help. + + Only call this if :meth:`is_user_error` is true. + + :rtype: str + """ + if not self.is_user_error(): + raise AttributeError("tag 'user_error' not set") + return self._value + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(TransformApiV2Error, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +TransformApiV2Error_validator = bv.Union(TransformApiV2Error) + + +class TransformArgs(bb.Struct): + """ + Arguments for the asynchronous `get_transform_async` route. Exactly one of + `file_id`, `path`, or `url` must be supplied via `file_id_or_url` to + identify the source file, and exactly one variant of `transform_type` must + be set to say what to produce from it. At most one options message may be + set, and it must be the one belonging to the requested `transform_type`. + Options that belong to a different transform type are rejected with + `invalid_options_error` rather than ignored, so that a request whose + parameters were misassembled fails visibly instead of quietly producing the + wrong output. + + :ivar TransformArgs.file_id_or_url: + Identifier of the source file to transform. Callers must set exactly one + of the `FileIdOrUrl` variants. The referenced file must be in a format + the requested `transform_type` supports; see the route description for + the per-transform format lists. Requests against unsupported formats + fail with `unsupported_format_error`. + :ivar TransformArgs.transform_type: + What to produce from the source file. Required. + :ivar TransformArgs.thumbnail: + Options for `TransformType.thumbnail`. + :ivar TransformArgs.image: + Options for `TransformType.image` and `TransformType.image_pdf`. + :ivar TransformArgs.video_frame: + Options for `TransformType.video_frame`. + """ + + __slots__ = [ + "_file_id_or_url_value", + "_transform_type_value", + "_thumbnail_value", + "_image_value", + "_video_frame_value", + ] + + _has_required_fields = True + + def __init__( + self, transform_type=None, file_id_or_url=None, thumbnail=None, image=None, video_frame=None + ): + self._file_id_or_url_value = bb.NOT_SET + self._transform_type_value = bb.NOT_SET + self._thumbnail_value = bb.NOT_SET + self._image_value = bb.NOT_SET + self._video_frame_value = bb.NOT_SET + if file_id_or_url is not None: + self.file_id_or_url = file_id_or_url + if transform_type is not None: + self.transform_type = transform_type + if thumbnail is not None: + self.thumbnail = thumbnail + if image is not None: + self.image = image + if video_frame is not None: + self.video_frame = video_frame + + # Instance attribute type: FileIdOrUrl (validator is set below) + file_id_or_url = bb.Attribute("file_id_or_url", nullable=True, user_defined=True) + + # Instance attribute type: TransformType (validator is set below) + transform_type = bb.Attribute("transform_type", user_defined=True) + + # Instance attribute type: ThumbnailOptions (validator is set below) + thumbnail = bb.Attribute("thumbnail", nullable=True, user_defined=True) + + # Instance attribute type: ImageOptions (validator is set below) + image = bb.Attribute("image", nullable=True, user_defined=True) + + # Instance attribute type: VideoFrameOptions (validator is set below) + video_frame = bb.Attribute("video_frame", nullable=True, user_defined=True) + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(TransformArgs, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +TransformArgs_validator = bv.Struct(TransformArgs) + + +class TransformOutput(bb.Struct): + """ + A completed transform: a handle for retrieving the produced bytes, plus + enough metadata to decide whether to retrieve them. The bytes themselves are + deliberately not carried here. A completed async result is persisted, so it + is bounded by a row-size limit well below the size of a typical converted + document -- an inline payload would fail for exactly the large documents + this route exists to convert. The transform therefore completes by caching + its output and handing back `output_handle`, which + `download_transform_output` exchanges for the bytes. + + :ivar TransformOutput.output_handle: + Opaque, single-purpose handle for the produced bytes. Pass it to + `download_transform_output` to retrieve them. The handle is scoped to + the account that created it and cannot be used to read anything other + than the output of this transform. It is not a URL and carries no + meaning for callers beyond being passed back verbatim. + :ivar TransformOutput.size: + Size of the produced output in bytes. + :ivar TransformOutput.format: + Format of the produced output, as a short lowercase format name such as + "pdf", "html", "jpeg", or "png". This reflects what was actually + produced, which for some sources differs from what was requested. + :ivar TransformOutput.mime_type: + MIME type corresponding to `format`, for callers that need a + Content-Type to hand to a downstream consumer. + :ivar TransformOutput.expires_ts: + Unix timestamp, in seconds, after which `output_handle` is no longer + accepted. Retrieve the bytes before this point; after it, + `download_transform_output` reports `expired_handle_error` and the + transform has to be requested again. + """ + + __slots__ = [ + "_output_handle_value", + "_size_value", + "_format_value", + "_mime_type_value", + "_expires_ts_value", + ] + + _has_required_fields = False + + def __init__(self, output_handle=None, size=None, format=None, mime_type=None, expires_ts=None): + self._output_handle_value = bb.NOT_SET + self._size_value = bb.NOT_SET + self._format_value = bb.NOT_SET + self._mime_type_value = bb.NOT_SET + self._expires_ts_value = bb.NOT_SET + if output_handle is not None: + self.output_handle = output_handle + if size is not None: + self.size = size + if format is not None: + self.format = format + if mime_type is not None: + self.mime_type = mime_type + if expires_ts is not None: + self.expires_ts = expires_ts + + # Instance attribute type: str (validator is set below) + output_handle = bb.Attribute("output_handle") + + # Instance attribute type: int (validator is set below) + size = bb.Attribute("size") + + # Instance attribute type: str (validator is set below) + format = bb.Attribute("format") + + # Instance attribute type: str (validator is set below) + mime_type = bb.Attribute("mime_type") + + # Instance attribute type: int (validator is set below) + expires_ts = bb.Attribute("expires_ts") + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(TransformOutput, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +TransformOutput_validator = bv.Struct(TransformOutput) + + +class TransformType(bb.Union): + """ + Which derived file to produce from the source file. Unlike the other Riviera + content routes, which each expose one capability, `get_transform_async` is a + single route over many conversions: the caller names the source file and the + output it wants, and the service picks the conversion pipeline. Exactly one + variant must be set; a request with none set fails with + `invalid_options_error`. + + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + + :ivar TransformType.pdf: + Convert the source document to PDF. Supported for word-processing, + presentation, and spreadsheet documents; images are not accepted. + :ivar TransformType.html: + Convert the source document to HTML. Supported for spreadsheets only, + where HTML preserves the sheet layout that a PDF rendering flattens. + :ivar TransformType.image: + Re-encode the source as a web-safe raster image (JPEG or PNG). This is + the transform to use to normalize formats a browser cannot display + directly -- HEIC, camera RAW, PSD, SVG -- and to render a single page of + a document as an image. Formats a browser can already display, such as + JPEG and PNG, are not accepted; use `thumbnail` to resize or re-encode + those. Configured by `TransformArgs.image`. + :ivar TransformType.thumbnail: + Produce a resized thumbnail of the source at one of the supported sizes. + Configured by `TransformArgs.thumbnail`. + :ivar TransformType.image_pdf: + Render the source as a page image by way of a PDF conversion, rather + than by whichever image pipeline the source format would otherwise use. + Prefer `image` unless you specifically need the PDF-rendered result; the + two differ for formats that have a native image pipeline of their own + (ebooks, for example). Configured by `TransformArgs.image`. + :ivar TransformType.video_frame: + Extract a single frame from a video as a still image. Configured by + `TransformArgs.video_frame`. This produces one frame at one requested + offset. To get the set of scene-change keyframes across a whole video, + use `get_keyframes_async`, which returns every detected frame with its + timestamp and scene score. + """ + + _catch_all = "other" + # Attribute is overwritten below the class definition + pdf = None + # Attribute is overwritten below the class definition + html = None + # Attribute is overwritten below the class definition + image = None + # Attribute is overwritten below the class definition + thumbnail = None + # Attribute is overwritten below the class definition + image_pdf = None + # Attribute is overwritten below the class definition + video_frame = None + # Attribute is overwritten below the class definition + other = None + + def is_pdf(self): + """ + Check if the union tag is ``pdf``. + + :rtype: bool + """ + return self._tag == "pdf" + + def is_html(self): + """ + Check if the union tag is ``html``. + + :rtype: bool + """ + return self._tag == "html" + + def is_image(self): + """ + Check if the union tag is ``image``. + + :rtype: bool + """ + return self._tag == "image" + + def is_thumbnail(self): + """ + Check if the union tag is ``thumbnail``. + + :rtype: bool + """ + return self._tag == "thumbnail" + + def is_image_pdf(self): + """ + Check if the union tag is ``image_pdf``. + + :rtype: bool + """ + return self._tag == "image_pdf" + + def is_video_frame(self): + """ + Check if the union tag is ``video_frame``. + + :rtype: bool + """ + return self._tag == "video_frame" + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == "other" + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(TransformType, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +TransformType_validator = bv.Union(TransformType) + + +class VideoFrameOptions(bb.Struct): + """ + Options for `TransformType.video_frame`. Supplying this message with any + other transform type fails with `invalid_options_error`. + + :ivar VideoFrameOptions.offset_in_seconds: + Offset into the video, in seconds, of the frame to extract. Should be + within the video's duration. Defaults to 0 (the first frame) when + omitted. Only the lower bound is enforced, because the upper bound is + the source's duration, which is not known until the video is opened. An + offset past the end is not rejected. + :ivar VideoFrameOptions.scale_percent: + Scale the extracted frame to this percentage of the video's natural + frame size. Must be in (0, 100]; the pipeline does not upscale. Defaults + to 100 (no scaling) when omitted. + """ + + __slots__ = [ + "_offset_in_seconds_value", + "_scale_percent_value", + ] + + _has_required_fields = False + + def __init__(self, offset_in_seconds=None, scale_percent=None): + self._offset_in_seconds_value = bb.NOT_SET + self._scale_percent_value = bb.NOT_SET + if offset_in_seconds is not None: + self.offset_in_seconds = offset_in_seconds + if scale_percent is not None: + self.scale_percent = scale_percent + + # Instance attribute type: float (validator is set below) + offset_in_seconds = bb.Attribute("offset_in_seconds") + + # Instance attribute type: int (validator is set below) + scale_percent = bb.Attribute("scale_percent") + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(VideoFrameOptions, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +VideoFrameOptions_validator = bv.Struct(VideoFrameOptions) + + +class MetadataUnion(bb.Union): + """ + The extracted metadata. Exactly one variant is populated, corresponding to + ``GetMetadataResult.metadata_type``. + + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + + :ivar MetadataUnion.exif: + EXIF metadata, for image files. + :vartype MetadataUnion.exif: ApiExifMetadata + :ivar MetadataUnion.media: + Container and per-stream metadata, for audio and video files. + :vartype MetadataUnion.media: ApiMediaMetadata + :ivar MetadataUnion.pdf: + Document metadata, for PDFs. + :vartype MetadataUnion.pdf: ApiPdfMetadata + :ivar MetadataUnion.office: + Document metadata, for MS Office files. + :vartype MetadataUnion.office: ApiOfficeMetadata + """ + + _catch_all = "other" + # Attribute is overwritten below the class definition + other = None + + @classmethod + def exif(cls, val): + """ + Create an instance of this class set to the ``exif`` tag with value + ``val``. + + :param ApiExifMetadata val: + :rtype: MetadataUnion + """ + return cls("exif", val) + + @classmethod + def media(cls, val): + """ + Create an instance of this class set to the ``media`` tag with value + ``val``. + + :param ApiMediaMetadata val: + :rtype: MetadataUnion + """ + return cls("media", val) + + @classmethod + def pdf(cls, val): + """ + Create an instance of this class set to the ``pdf`` tag with value + ``val``. + + :param ApiPdfMetadata val: + :rtype: MetadataUnion + """ + return cls("pdf", val) + + @classmethod + def office(cls, val): + """ + Create an instance of this class set to the ``office`` tag with value + ``val``. + + :param ApiOfficeMetadata val: + :rtype: MetadataUnion + """ + return cls("office", val) + + def is_exif(self): + """ + Check if the union tag is ``exif``. + + :rtype: bool + """ + return self._tag == "exif" + + def is_media(self): + """ + Check if the union tag is ``media``. + + :rtype: bool + """ + return self._tag == "media" + + def is_pdf(self): + """ + Check if the union tag is ``pdf``. + + :rtype: bool + """ + return self._tag == "pdf" + + def is_office(self): + """ + Check if the union tag is ``office``. + + :rtype: bool + """ + return self._tag == "office" def is_other(self): """ @@ -4066,6 +5213,28 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): ContentApiV2Error.is_a_folder_error = ContentApiV2Error("is_a_folder_error") ContentApiV2Error.other = ContentApiV2Error("other") +DownloadTransformOutputArgs.output_handle.validator = bv.String() +DownloadTransformOutputArgs._all_field_names_ = set(["output_handle"]) +DownloadTransformOutputArgs._all_fields_ = [ + ("output_handle", DownloadTransformOutputArgs.output_handle.validator) +] + +DownloadTransformOutputResult.size.validator = bv.UInt64() +DownloadTransformOutputResult.format.validator = bv.String() +DownloadTransformOutputResult.mime_type.validator = bv.String() +DownloadTransformOutputResult._all_field_names_ = set( + [ + "size", + "format", + "mime_type", + ] +) +DownloadTransformOutputResult._all_fields_ = [ + ("size", DownloadTransformOutputResult.size.validator), + ("format", DownloadTransformOutputResult.format.validator), + ("mime_type", DownloadTransformOutputResult.mime_type.validator), +] + FileIdOrUrl._file_id_validator = bv.String() FileIdOrUrl._url_validator = bv.String() FileIdOrUrl._path_validator = bv.String() @@ -4270,6 +5439,33 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): ("structured_transcript", GetTranscriptResult.structured_transcript.validator) ] +GetTransformAsyncCheckResult._in_progress_validator = bv.Void() +GetTransformAsyncCheckResult._complete_validator = TransformOutput_validator +GetTransformAsyncCheckResult._failed_validator = TransformApiV2Error_validator +GetTransformAsyncCheckResult._other_validator = bv.Void() +GetTransformAsyncCheckResult._tagmap = { + "in_progress": GetTransformAsyncCheckResult._in_progress_validator, + "complete": GetTransformAsyncCheckResult._complete_validator, + "failed": GetTransformAsyncCheckResult._failed_validator, + "other": GetTransformAsyncCheckResult._other_validator, +} + +GetTransformAsyncCheckResult.in_progress = GetTransformAsyncCheckResult("in_progress") +GetTransformAsyncCheckResult.other = GetTransformAsyncCheckResult("other") + +ImageOptions.page_number.validator = bv.UInt32(min_value=1) +ImageOptions.scale_percent.validator = bv.UInt32(min_value=1, max_value=100) +ImageOptions._all_field_names_ = set( + [ + "page_number", + "scale_percent", + ] +) +ImageOptions._all_fields_ = [ + ("page_number", ImageOptions.page_number.validator), + ("scale_percent", ImageOptions.scale_percent.validator), +] + KeyframesExtractionApiV2Error._server_error_validator = bv.String() KeyframesExtractionApiV2Error._user_error_validator = bv.String() KeyframesExtractionApiV2Error._unsupported_format_error_validator = bv.Void() @@ -4521,6 +5717,91 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): TextExtractionApiV2Error.is_a_folder_error = TextExtractionApiV2Error("is_a_folder_error") TextExtractionApiV2Error.other = TextExtractionApiV2Error("other") +ThumbnailFormat._jpeg_validator = bv.Void() +ThumbnailFormat._png_validator = bv.Void() +ThumbnailFormat._webp_validator = bv.Void() +ThumbnailFormat._other_validator = bv.Void() +ThumbnailFormat._tagmap = { + "jpeg": ThumbnailFormat._jpeg_validator, + "png": ThumbnailFormat._png_validator, + "webp": ThumbnailFormat._webp_validator, + "other": ThumbnailFormat._other_validator, +} + +ThumbnailFormat.jpeg = ThumbnailFormat("jpeg") +ThumbnailFormat.png = ThumbnailFormat("png") +ThumbnailFormat.webp = ThumbnailFormat("webp") +ThumbnailFormat.other = ThumbnailFormat("other") + +ThumbnailMode._strict_validator = bv.Void() +ThumbnailMode._bestfit_validator = bv.Void() +ThumbnailMode._fitone_bestfit_validator = bv.Void() +ThumbnailMode._original_validator = bv.Void() +ThumbnailMode._other_validator = bv.Void() +ThumbnailMode._tagmap = { + "strict": ThumbnailMode._strict_validator, + "bestfit": ThumbnailMode._bestfit_validator, + "fitone_bestfit": ThumbnailMode._fitone_bestfit_validator, + "original": ThumbnailMode._original_validator, + "other": ThumbnailMode._other_validator, +} + +ThumbnailMode.strict = ThumbnailMode("strict") +ThumbnailMode.bestfit = ThumbnailMode("bestfit") +ThumbnailMode.fitone_bestfit = ThumbnailMode("fitone_bestfit") +ThumbnailMode.original = ThumbnailMode("original") +ThumbnailMode.other = ThumbnailMode("other") + +ThumbnailOptions.size.validator = ThumbnailSize_validator +ThumbnailOptions.mode.validator = ThumbnailMode_validator +ThumbnailOptions.format.validator = ThumbnailFormat_validator +ThumbnailOptions._all_field_names_ = set( + [ + "size", + "mode", + "format", + ] +) +ThumbnailOptions._all_fields_ = [ + ("size", ThumbnailOptions.size.validator), + ("mode", ThumbnailOptions.mode.validator), + ("format", ThumbnailOptions.format.validator), +] + +ThumbnailSize._w32h32_validator = bv.Void() +ThumbnailSize._w64h64_validator = bv.Void() +ThumbnailSize._w128h128_validator = bv.Void() +ThumbnailSize._w256h256_validator = bv.Void() +ThumbnailSize._w480h320_validator = bv.Void() +ThumbnailSize._w640h480_validator = bv.Void() +ThumbnailSize._w960h640_validator = bv.Void() +ThumbnailSize._w1024h768_validator = bv.Void() +ThumbnailSize._w2048h1536_validator = bv.Void() +ThumbnailSize._other_validator = bv.Void() +ThumbnailSize._tagmap = { + "w32h32": ThumbnailSize._w32h32_validator, + "w64h64": ThumbnailSize._w64h64_validator, + "w128h128": ThumbnailSize._w128h128_validator, + "w256h256": ThumbnailSize._w256h256_validator, + "w480h320": ThumbnailSize._w480h320_validator, + "w640h480": ThumbnailSize._w640h480_validator, + "w960h640": ThumbnailSize._w960h640_validator, + "w1024h768": ThumbnailSize._w1024h768_validator, + "w2048h1536": ThumbnailSize._w2048h1536_validator, + "other": ThumbnailSize._other_validator, +} + +ThumbnailSize.w32h32 = ThumbnailSize("w32h32") +ThumbnailSize.w64h64 = ThumbnailSize("w64h64") +ThumbnailSize.w128h128 = ThumbnailSize("w128h128") +ThumbnailSize.w256h256 = ThumbnailSize("w256h256") +ThumbnailSize.w480h320 = ThumbnailSize("w480h320") +ThumbnailSize.w640h480 = ThumbnailSize("w640h480") +ThumbnailSize.w960h640 = ThumbnailSize("w960h640") +ThumbnailSize.w1024h768 = ThumbnailSize("w1024h768") +ThumbnailSize.w2048h1536 = ThumbnailSize("w2048h1536") +ThumbnailSize.other = ThumbnailSize("other") + TimestampLevel._sentence_validator = bv.Void() TimestampLevel._word_validator = bv.Void() TimestampLevel._other_validator = bv.Void() @@ -4534,6 +5815,130 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): TimestampLevel.word = TimestampLevel("word") TimestampLevel.other = TimestampLevel("other") +TransformApiV2Error._server_error_validator = bv.String() +TransformApiV2Error._user_error_validator = bv.String() +TransformApiV2Error._unsupported_format_error_validator = bv.Void() +TransformApiV2Error._link_download_disabled_error_validator = bv.Void() +TransformApiV2Error._shared_link_password_protected_validator = bv.Void() +TransformApiV2Error._limit_exceeded_error_validator = bv.Void() +TransformApiV2Error._conversion_failure_error_validator = bv.Void() +TransformApiV2Error._not_found_error_validator = bv.Void() +TransformApiV2Error._is_a_folder_error_validator = bv.Void() +TransformApiV2Error._invalid_options_error_validator = bv.Void() +TransformApiV2Error._expired_handle_error_validator = bv.Void() +TransformApiV2Error._other_validator = bv.Void() +TransformApiV2Error._tagmap = { + "server_error": TransformApiV2Error._server_error_validator, + "user_error": TransformApiV2Error._user_error_validator, + "unsupported_format_error": TransformApiV2Error._unsupported_format_error_validator, + "link_download_disabled_error": TransformApiV2Error._link_download_disabled_error_validator, + "shared_link_password_protected": TransformApiV2Error._shared_link_password_protected_validator, + "limit_exceeded_error": TransformApiV2Error._limit_exceeded_error_validator, + "conversion_failure_error": TransformApiV2Error._conversion_failure_error_validator, + "not_found_error": TransformApiV2Error._not_found_error_validator, + "is_a_folder_error": TransformApiV2Error._is_a_folder_error_validator, + "invalid_options_error": TransformApiV2Error._invalid_options_error_validator, + "expired_handle_error": TransformApiV2Error._expired_handle_error_validator, + "other": TransformApiV2Error._other_validator, +} + +TransformApiV2Error.unsupported_format_error = TransformApiV2Error("unsupported_format_error") +TransformApiV2Error.link_download_disabled_error = TransformApiV2Error( + "link_download_disabled_error" +) +TransformApiV2Error.shared_link_password_protected = TransformApiV2Error( + "shared_link_password_protected" +) +TransformApiV2Error.limit_exceeded_error = TransformApiV2Error("limit_exceeded_error") +TransformApiV2Error.conversion_failure_error = TransformApiV2Error("conversion_failure_error") +TransformApiV2Error.not_found_error = TransformApiV2Error("not_found_error") +TransformApiV2Error.is_a_folder_error = TransformApiV2Error("is_a_folder_error") +TransformApiV2Error.invalid_options_error = TransformApiV2Error("invalid_options_error") +TransformApiV2Error.expired_handle_error = TransformApiV2Error("expired_handle_error") +TransformApiV2Error.other = TransformApiV2Error("other") + +TransformArgs.file_id_or_url.validator = bv.Nullable(FileIdOrUrl_validator) +TransformArgs.transform_type.validator = TransformType_validator +TransformArgs.thumbnail.validator = bv.Nullable(ThumbnailOptions_validator) +TransformArgs.image.validator = bv.Nullable(ImageOptions_validator) +TransformArgs.video_frame.validator = bv.Nullable(VideoFrameOptions_validator) +TransformArgs._all_field_names_ = set( + [ + "file_id_or_url", + "transform_type", + "thumbnail", + "image", + "video_frame", + ] +) +TransformArgs._all_fields_ = [ + ("file_id_or_url", TransformArgs.file_id_or_url.validator), + ("transform_type", TransformArgs.transform_type.validator), + ("thumbnail", TransformArgs.thumbnail.validator), + ("image", TransformArgs.image.validator), + ("video_frame", TransformArgs.video_frame.validator), +] + +TransformOutput.output_handle.validator = bv.String() +TransformOutput.size.validator = bv.UInt64() +TransformOutput.format.validator = bv.String() +TransformOutput.mime_type.validator = bv.String() +TransformOutput.expires_ts.validator = bv.UInt64() +TransformOutput._all_field_names_ = set( + [ + "output_handle", + "size", + "format", + "mime_type", + "expires_ts", + ] +) +TransformOutput._all_fields_ = [ + ("output_handle", TransformOutput.output_handle.validator), + ("size", TransformOutput.size.validator), + ("format", TransformOutput.format.validator), + ("mime_type", TransformOutput.mime_type.validator), + ("expires_ts", TransformOutput.expires_ts.validator), +] + +TransformType._pdf_validator = bv.Void() +TransformType._html_validator = bv.Void() +TransformType._image_validator = bv.Void() +TransformType._thumbnail_validator = bv.Void() +TransformType._image_pdf_validator = bv.Void() +TransformType._video_frame_validator = bv.Void() +TransformType._other_validator = bv.Void() +TransformType._tagmap = { + "pdf": TransformType._pdf_validator, + "html": TransformType._html_validator, + "image": TransformType._image_validator, + "thumbnail": TransformType._thumbnail_validator, + "image_pdf": TransformType._image_pdf_validator, + "video_frame": TransformType._video_frame_validator, + "other": TransformType._other_validator, +} + +TransformType.pdf = TransformType("pdf") +TransformType.html = TransformType("html") +TransformType.image = TransformType("image") +TransformType.thumbnail = TransformType("thumbnail") +TransformType.image_pdf = TransformType("image_pdf") +TransformType.video_frame = TransformType("video_frame") +TransformType.other = TransformType("other") + +VideoFrameOptions.offset_in_seconds.validator = bv.Float64(min_value=0.0) +VideoFrameOptions.scale_percent.validator = bv.UInt32(min_value=1, max_value=100) +VideoFrameOptions._all_field_names_ = set( + [ + "offset_in_seconds", + "scale_percent", + ] +) +VideoFrameOptions._all_fields_ = [ + ("offset_in_seconds", VideoFrameOptions.offset_in_seconds.validator), + ("scale_percent", VideoFrameOptions.scale_percent.validator), +] + MetadataUnion._exif_validator = ApiExifMetadata_validator MetadataUnion._media_validator = ApiMediaMetadata_validator MetadataUnion._pdf_validator = ApiPdfMetadata_validator @@ -4608,6 +6013,9 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): ApiTranscriptSegment.text.default = "" ApiTranscriptSegment.start_time.default = 0.0 ApiTranscriptSegment.end_time.default = 0.0 +DownloadTransformOutputResult.size.default = 0 +DownloadTransformOutputResult.format.default = "" +DownloadTransformOutputResult.mime_type.default = "" GetKeyframesArgs.scene_change_threshold.default = 0.0 GetKeyframesArgs.include_images.default = False GetMarkdownArgs.enable_ocr.default = False @@ -4620,7 +6028,28 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): GetTranscriptArgs.timestamp_level.default = TimestampLevel.sentence GetTranscriptArgs.included_special_words.default = "" GetTranscriptArgs.audio_language.default = "" +ImageOptions.page_number.default = 1 +ImageOptions.scale_percent.default = 100 MediaDurationError.limit.default = 0 +ThumbnailOptions.size.default = ThumbnailSize.w64h64 +ThumbnailOptions.mode.default = ThumbnailMode.strict +ThumbnailOptions.format.default = ThumbnailFormat.jpeg +TransformOutput.output_handle.default = "" +TransformOutput.size.default = 0 +TransformOutput.format.default = "" +TransformOutput.mime_type.default = "" +TransformOutput.expires_ts.default = 0 +VideoFrameOptions.offset_in_seconds.default = 0.0 +VideoFrameOptions.scale_percent.default = 100 +download_transform_output = bb.Route( + "download_transform_output", + 1, + False, + DownloadTransformOutputArgs_validator, + DownloadTransformOutputResult_validator, + TransformApiV2Error_validator, + {"auth": "app, user", "host": "content", "style": "download"}, +) get_keyframes_async = bb.Route( "get_keyframes_async", 1, @@ -4729,8 +6158,27 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): async_.PollError_validator, {"auth": "app, user", "host": "api", "style": "rpc"}, ) +get_transform_async = bb.Route( + "get_transform_async", + 1, + False, + TransformArgs_validator, + async_.LaunchResultBase_validator, + bv.Void(), + {"auth": "app, user", "host": "api", "style": "rpc"}, +) +get_transform_async_check = bb.Route( + "get_transform_async/check", + 1, + False, + async_.PollArg_validator, + GetTransformAsyncCheckResult_validator, + async_.PollError_validator, + {"auth": "app, user", "host": "api", "style": "rpc"}, +) ROUTES = { + "download_transform_output": download_transform_output, "get_keyframes_async": get_keyframes_async, "get_keyframes_async/check": get_keyframes_async_check, "get_markdown_async": get_markdown_async, @@ -4743,4 +6191,6 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): "get_text_async/check": get_text_async_check, "get_transcript_async": get_transcript_async, "get_transcript_async/check": get_transcript_async_check, + "get_transform_async": get_transform_async, + "get_transform_async/check": get_transform_async_check, } diff --git a/dropbox/sharing.py b/dropbox/sharing.py index 41c21e3..e143542 100644 --- a/dropbox/sharing.py +++ b/dropbox/sharing.py @@ -4596,6 +4596,10 @@ class LinkAudience(bb.Union): password is required to access the link. Login is not required. :ivar LinkAudience.members: Field is deprecated. Link is accessible only by members of the content. + :ivar LinkAudience.public_logged_in_only: + Link is accessible only by signed-in Dropbox users. This audience is + currently read-only through API v2: API v2 write methods reject requests + that set it. """ _catch_all = "other" @@ -4610,6 +4614,8 @@ class LinkAudience(bb.Union): # Attribute is overwritten below the class definition members = None # Attribute is overwritten below the class definition + public_logged_in_only = None + # Attribute is overwritten below the class definition other = None def is_public(self): @@ -4652,6 +4658,14 @@ def is_members(self): """ return self._tag == "members" + def is_public_logged_in_only(self): + """ + Check if the union tag is ``public_logged_in_only``. + + :rtype: bool + """ + return self._tag == "public_logged_in_only" + def is_other(self): """ Check if the union tag is ``other``. @@ -13747,6 +13761,7 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): LinkAudience._no_one_validator = bv.Void() LinkAudience._password_validator = bv.Void() LinkAudience._members_validator = bv.Void() +LinkAudience._public_logged_in_only_validator = bv.Void() LinkAudience._other_validator = bv.Void() LinkAudience._tagmap = { "public": LinkAudience._public_validator, @@ -13754,6 +13769,7 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): "no_one": LinkAudience._no_one_validator, "password": LinkAudience._password_validator, "members": LinkAudience._members_validator, + "public_logged_in_only": LinkAudience._public_logged_in_only_validator, "other": LinkAudience._other_validator, } @@ -13762,6 +13778,7 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): LinkAudience.no_one = LinkAudience("no_one") LinkAudience.password = LinkAudience("password") LinkAudience.members = LinkAudience("members") +LinkAudience.public_logged_in_only = LinkAudience("public_logged_in_only") LinkAudience.other = LinkAudience("other") VisibilityPolicyDisallowedReason._delete_and_recreate_validator = bv.Void() diff --git a/dropbox/team.py b/dropbox/team.py index bf6ea13..8c81f79 100644 --- a/dropbox/team.py +++ b/dropbox/team.py @@ -11005,6 +11005,548 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): MembersSetProfilePhotoError_validator = bv.Union(MembersSetProfilePhotoError) +class MembersSuspendBatchArg(bb.Struct): + """ + Launches one action-specific member suspension batch job. + + :ivar MembersSuspendBatchArg.members: + Must contain between 1 and 500 targets. The launch handler also rejects + duplicate client item IDs and duplicate member selectors. + """ + + __slots__ = [ + "_members_value", + ] + + _has_required_fields = True + + def __init__(self, members=None): + self._members_value = bb.NOT_SET + if members is not None: + self.members = members + + # Instance attribute type: list of [MembersSuspendBatchTarget] (validator is set below) + members = bb.Attribute("members") + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(MembersSuspendBatchArg, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +MembersSuspendBatchArg_validator = bv.Struct(MembersSuspendBatchArg) + + +class MembersSuspendBatchComplete(bb.Struct): + __slots__ = [ + "_requested_value", + "_suspended_value", + "_failed_value", + "_unknown_value", + "_report_delivery_value", + ] + + _has_required_fields = True + + def __init__( + self, requested=None, suspended=None, failed=None, unknown=None, report_delivery=None + ): + self._requested_value = bb.NOT_SET + self._suspended_value = bb.NOT_SET + self._failed_value = bb.NOT_SET + self._unknown_value = bb.NOT_SET + self._report_delivery_value = bb.NOT_SET + if requested is not None: + self.requested = requested + if suspended is not None: + self.suspended = suspended + if failed is not None: + self.failed = failed + if unknown is not None: + self.unknown = unknown + if report_delivery is not None: + self.report_delivery = report_delivery + + # Instance attribute type: int (validator is set below) + requested = bb.Attribute("requested") + + # Instance attribute type: int (validator is set below) + suspended = bb.Attribute("suspended") + + # Instance attribute type: int (validator is set below) + failed = bb.Attribute("failed") + + # Instance attribute type: int (validator is set below) + unknown = bb.Attribute("unknown") + + # Instance attribute type: MembersSuspendBatchReportDeliveryStatus (validator is set below) + report_delivery = bb.Attribute("report_delivery", user_defined=True) + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(MembersSuspendBatchComplete, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +MembersSuspendBatchComplete_validator = bv.Struct(MembersSuspendBatchComplete) + + +class MembersSuspendBatchError(bb.Union): + """ + A typed launch rejection. Authorization failures continue to use the API v2 + authentication/permission error surface. + + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + + :ivar MembersSuspendBatchError.too_many_members: + The request contains more than 500 members. + :ivar MembersSuspendBatchError.duplicate_client_item_id: + More than one target uses the same client item ID. + :ivar MembersSuspendBatchError.duplicate_team_member_id: + More than one target selects the same team member. + :ivar MembersSuspendBatchError.acting_admin: + The acting administrator cannot suspend their own account. + :ivar MembersSuspendBatchError.last_admin: + Suspending the selected members would leave the team without an active + admin. + """ + + _catch_all = "other" + # Attribute is overwritten below the class definition + too_many_members = None + # Attribute is overwritten below the class definition + duplicate_client_item_id = None + # Attribute is overwritten below the class definition + duplicate_team_member_id = None + # Attribute is overwritten below the class definition + acting_admin = None + # Attribute is overwritten below the class definition + last_admin = None + # Attribute is overwritten below the class definition + other = None + + def is_too_many_members(self): + """ + Check if the union tag is ``too_many_members``. + + :rtype: bool + """ + return self._tag == "too_many_members" + + def is_duplicate_client_item_id(self): + """ + Check if the union tag is ``duplicate_client_item_id``. + + :rtype: bool + """ + return self._tag == "duplicate_client_item_id" + + def is_duplicate_team_member_id(self): + """ + Check if the union tag is ``duplicate_team_member_id``. + + :rtype: bool + """ + return self._tag == "duplicate_team_member_id" + + def is_acting_admin(self): + """ + Check if the union tag is ``acting_admin``. + + :rtype: bool + """ + return self._tag == "acting_admin" + + def is_last_admin(self): + """ + Check if the union tag is ``last_admin``. + + :rtype: bool + """ + return self._tag == "last_admin" + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == "other" + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(MembersSuspendBatchError, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +MembersSuspendBatchError_validator = bv.Union(MembersSuspendBatchError) + + +class MembersSuspendBatchJobStatus(async_.PollResultBase): + """ + Coarse job state. Live row progress and report contents are intentionally + omitted; the authorized team admin who initiated the batch receives row + details in the terminal email report. + + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + """ + + _catch_all = "other" + # Attribute is overwritten below the class definition + other = None + + @classmethod + def complete(cls, val): + """ + Create an instance of this class set to the ``complete`` tag with value + ``val``. + + :param MembersSuspendBatchComplete val: + :rtype: MembersSuspendBatchJobStatus + """ + return cls("complete", val) + + @classmethod + def failed(cls, val): + """ + Create an instance of this class set to the ``failed`` tag with value + ``val``. + + :param MembersSuspendBatchTaskFailure val: + :rtype: MembersSuspendBatchJobStatus + """ + return cls("failed", val) + + def is_complete(self): + """ + Check if the union tag is ``complete``. + + :rtype: bool + """ + return self._tag == "complete" + + def is_failed(self): + """ + Check if the union tag is ``failed``. + + :rtype: bool + """ + return self._tag == "failed" + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == "other" + + def get_complete(self): + """ + Only call this if :meth:`is_complete` is true. + + :rtype: MembersSuspendBatchComplete + """ + if not self.is_complete(): + raise AttributeError("tag 'complete' not set") + return self._value + + def get_failed(self): + """ + Only call this if :meth:`is_failed` is true. + + :rtype: MembersSuspendBatchTaskFailure + """ + if not self.is_failed(): + raise AttributeError("tag 'failed' not set") + return self._value + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(MembersSuspendBatchJobStatus, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +MembersSuspendBatchJobStatus_validator = bv.Union(MembersSuspendBatchJobStatus) + + +class MembersSuspendBatchReportDeliveryStatus(bb.Union): + """ + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + """ + + _catch_all = "other" + # Attribute is overwritten below the class definition + members_suspend_batch_report_delivery_status_unspecified = None + # Attribute is overwritten below the class definition + members_suspend_batch_report_delivery_status_pending = None + # Attribute is overwritten below the class definition + members_suspend_batch_report_delivery_status_delivered = None + # Attribute is overwritten below the class definition + members_suspend_batch_report_delivery_status_failed = None + # Attribute is overwritten below the class definition + other = None + + def is_members_suspend_batch_report_delivery_status_unspecified(self): + """ + Check if the union tag is ``members_suspend_batch_report_delivery_status_unspecified``. + + :rtype: bool + """ + return self._tag == "members_suspend_batch_report_delivery_status_unspecified" + + def is_members_suspend_batch_report_delivery_status_pending(self): + """ + Check if the union tag is ``members_suspend_batch_report_delivery_status_pending``. + + :rtype: bool + """ + return self._tag == "members_suspend_batch_report_delivery_status_pending" + + def is_members_suspend_batch_report_delivery_status_delivered(self): + """ + Check if the union tag is ``members_suspend_batch_report_delivery_status_delivered``. + + :rtype: bool + """ + return self._tag == "members_suspend_batch_report_delivery_status_delivered" + + def is_members_suspend_batch_report_delivery_status_failed(self): + """ + Check if the union tag is ``members_suspend_batch_report_delivery_status_failed``. + + :rtype: bool + """ + return self._tag == "members_suspend_batch_report_delivery_status_failed" + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == "other" + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(MembersSuspendBatchReportDeliveryStatus, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +MembersSuspendBatchReportDeliveryStatus_validator = bv.Union( + MembersSuspendBatchReportDeliveryStatus +) + + +class MembersSuspendBatchRowFailure(MembersSuspendError): + """ + Stable machine-readable reasons used by the terminal row report. + + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + """ + + # Attribute is overwritten below the class definition + protected_acting_admin = None + # Attribute is overwritten below the class definition + permission_changed = None + # Attribute is overwritten below the class definition + suspend_failed = None + + def is_protected_acting_admin(self): + """ + Check if the union tag is ``protected_acting_admin``. + + :rtype: bool + """ + return self._tag == "protected_acting_admin" + + def is_permission_changed(self): + """ + Check if the union tag is ``permission_changed``. + + :rtype: bool + """ + return self._tag == "permission_changed" + + def is_suspend_failed(self): + """ + Check if the union tag is ``suspend_failed``. + + :rtype: bool + """ + return self._tag == "suspend_failed" + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(MembersSuspendBatchRowFailure, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +MembersSuspendBatchRowFailure_validator = bv.Union(MembersSuspendBatchRowFailure) + + +class MembersSuspendBatchRowOutcome(bb.Union): + """ + The terminal outcome for one requested member. Row outcomes are delivered in + the report rather than embedded in the status response. + + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + """ + + _catch_all = "other" + # Attribute is overwritten below the class definition + suspended = None + # Attribute is overwritten below the class definition + unknown = None + # Attribute is overwritten below the class definition + other = None + + @classmethod + def failed(cls, val): + """ + Create an instance of this class set to the ``failed`` tag with value + ``val``. + + :param MembersSuspendBatchRowFailure val: + :rtype: MembersSuspendBatchRowOutcome + """ + return cls("failed", val) + + def is_suspended(self): + """ + Check if the union tag is ``suspended``. + + :rtype: bool + """ + return self._tag == "suspended" + + def is_failed(self): + """ + Check if the union tag is ``failed``. + + :rtype: bool + """ + return self._tag == "failed" + + def is_unknown(self): + """ + Check if the union tag is ``unknown``. + + :rtype: bool + """ + return self._tag == "unknown" + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == "other" + + def get_failed(self): + """ + Only call this if :meth:`is_failed` is true. + + :rtype: MembersSuspendBatchRowFailure + """ + if not self.is_failed(): + raise AttributeError("tag 'failed' not set") + return self._value + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(MembersSuspendBatchRowOutcome, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +MembersSuspendBatchRowOutcome_validator = bv.Union(MembersSuspendBatchRowOutcome) + + +class MembersSuspendBatchTarget(bb.Struct): + """ + One member selected for suspension. The opaque client item ID correlates the + eventual report row with the caller's input without sending CSV data. + """ + + __slots__ = [ + "_client_item_id_value", + "_suspend_arg_value", + ] + + _has_required_fields = True + + def __init__(self, client_item_id=None, suspend_arg=None): + self._client_item_id_value = bb.NOT_SET + self._suspend_arg_value = bb.NOT_SET + if client_item_id is not None: + self.client_item_id = client_item_id + if suspend_arg is not None: + self.suspend_arg = suspend_arg + + # Instance attribute type: str (validator is set below) + client_item_id = bb.Attribute("client_item_id") + + # Instance attribute type: MembersDeactivateArg (validator is set below) + suspend_arg = bb.Attribute("suspend_arg", user_defined=True) + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(MembersSuspendBatchTarget, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +MembersSuspendBatchTarget_validator = bv.Struct(MembersSuspendBatchTarget) + + +class MembersSuspendBatchTaskFailure(bb.Union): + """ + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + """ + + _catch_all = "other" + # Attribute is overwritten below the class definition + unusable_result = None + # Attribute is overwritten below the class definition + other = None + + def is_unusable_result(self): + """ + Check if the union tag is ``unusable_result``. + + :rtype: bool + """ + return self._tag == "unusable_result" + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == "other" + + def _process_custom_annotations(self, annotation_type, field_path, processor): + super(MembersSuspendBatchTaskFailure, self)._process_custom_annotations( + annotation_type, field_path, processor + ) + + +MembersSuspendBatchTaskFailure_validator = bv.Union(MembersSuspendBatchTaskFailure) + + class MembersTransferFormerMembersFilesError(MembersTransferFilesError): """ This class acts as a tagged union. Only one of the ``is_*`` methods will @@ -18596,6 +19138,161 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): ) MembersSetProfilePhotoError.other = MembersSetProfilePhotoError("other") +MembersSuspendBatchArg.members.validator = bv.List( + MembersSuspendBatchTarget_validator, min_items=1, max_items=500 +) +MembersSuspendBatchArg._all_field_names_ = set(["members"]) +MembersSuspendBatchArg._all_fields_ = [("members", MembersSuspendBatchArg.members.validator)] + +MembersSuspendBatchComplete.requested.validator = bv.Int64() +MembersSuspendBatchComplete.suspended.validator = bv.Int64() +MembersSuspendBatchComplete.failed.validator = bv.Int64() +MembersSuspendBatchComplete.unknown.validator = bv.Int64() +MembersSuspendBatchComplete.report_delivery.validator = ( + MembersSuspendBatchReportDeliveryStatus_validator +) +MembersSuspendBatchComplete._all_field_names_ = set( + [ + "requested", + "suspended", + "failed", + "unknown", + "report_delivery", + ] +) +MembersSuspendBatchComplete._all_fields_ = [ + ("requested", MembersSuspendBatchComplete.requested.validator), + ("suspended", MembersSuspendBatchComplete.suspended.validator), + ("failed", MembersSuspendBatchComplete.failed.validator), + ("unknown", MembersSuspendBatchComplete.unknown.validator), + ("report_delivery", MembersSuspendBatchComplete.report_delivery.validator), +] + +MembersSuspendBatchError._too_many_members_validator = bv.Void() +MembersSuspendBatchError._duplicate_client_item_id_validator = bv.Void() +MembersSuspendBatchError._duplicate_team_member_id_validator = bv.Void() +MembersSuspendBatchError._acting_admin_validator = bv.Void() +MembersSuspendBatchError._last_admin_validator = bv.Void() +MembersSuspendBatchError._other_validator = bv.Void() +MembersSuspendBatchError._tagmap = { + "too_many_members": MembersSuspendBatchError._too_many_members_validator, + "duplicate_client_item_id": MembersSuspendBatchError._duplicate_client_item_id_validator, + "duplicate_team_member_id": MembersSuspendBatchError._duplicate_team_member_id_validator, + "acting_admin": MembersSuspendBatchError._acting_admin_validator, + "last_admin": MembersSuspendBatchError._last_admin_validator, + "other": MembersSuspendBatchError._other_validator, +} + +MembersSuspendBatchError.too_many_members = MembersSuspendBatchError("too_many_members") +MembersSuspendBatchError.duplicate_client_item_id = MembersSuspendBatchError( + "duplicate_client_item_id" +) +MembersSuspendBatchError.duplicate_team_member_id = MembersSuspendBatchError( + "duplicate_team_member_id" +) +MembersSuspendBatchError.acting_admin = MembersSuspendBatchError("acting_admin") +MembersSuspendBatchError.last_admin = MembersSuspendBatchError("last_admin") +MembersSuspendBatchError.other = MembersSuspendBatchError("other") + +MembersSuspendBatchJobStatus._complete_validator = MembersSuspendBatchComplete_validator +MembersSuspendBatchJobStatus._failed_validator = MembersSuspendBatchTaskFailure_validator +MembersSuspendBatchJobStatus._other_validator = bv.Void() +MembersSuspendBatchJobStatus._tagmap = { + "complete": MembersSuspendBatchJobStatus._complete_validator, + "failed": MembersSuspendBatchJobStatus._failed_validator, + "other": MembersSuspendBatchJobStatus._other_validator, +} +MembersSuspendBatchJobStatus._tagmap.update(async_.PollResultBase._tagmap) + +MembersSuspendBatchJobStatus.other = MembersSuspendBatchJobStatus("other") + +MembersSuspendBatchReportDeliveryStatus._members_suspend_batch_report_delivery_status_unspecified_validator = bv.Void() +MembersSuspendBatchReportDeliveryStatus._members_suspend_batch_report_delivery_status_pending_validator = bv.Void() +MembersSuspendBatchReportDeliveryStatus._members_suspend_batch_report_delivery_status_delivered_validator = bv.Void() +MembersSuspendBatchReportDeliveryStatus._members_suspend_batch_report_delivery_status_failed_validator = bv.Void() +MembersSuspendBatchReportDeliveryStatus._other_validator = bv.Void() +MembersSuspendBatchReportDeliveryStatus._tagmap = { + "members_suspend_batch_report_delivery_status_unspecified": MembersSuspendBatchReportDeliveryStatus._members_suspend_batch_report_delivery_status_unspecified_validator, + "members_suspend_batch_report_delivery_status_pending": MembersSuspendBatchReportDeliveryStatus._members_suspend_batch_report_delivery_status_pending_validator, + "members_suspend_batch_report_delivery_status_delivered": MembersSuspendBatchReportDeliveryStatus._members_suspend_batch_report_delivery_status_delivered_validator, + "members_suspend_batch_report_delivery_status_failed": MembersSuspendBatchReportDeliveryStatus._members_suspend_batch_report_delivery_status_failed_validator, + "other": MembersSuspendBatchReportDeliveryStatus._other_validator, +} + +MembersSuspendBatchReportDeliveryStatus.members_suspend_batch_report_delivery_status_unspecified = ( + MembersSuspendBatchReportDeliveryStatus( + "members_suspend_batch_report_delivery_status_unspecified" + ) +) +MembersSuspendBatchReportDeliveryStatus.members_suspend_batch_report_delivery_status_pending = ( + MembersSuspendBatchReportDeliveryStatus("members_suspend_batch_report_delivery_status_pending") +) +MembersSuspendBatchReportDeliveryStatus.members_suspend_batch_report_delivery_status_delivered = ( + MembersSuspendBatchReportDeliveryStatus( + "members_suspend_batch_report_delivery_status_delivered" + ) +) +MembersSuspendBatchReportDeliveryStatus.members_suspend_batch_report_delivery_status_failed = ( + MembersSuspendBatchReportDeliveryStatus("members_suspend_batch_report_delivery_status_failed") +) +MembersSuspendBatchReportDeliveryStatus.other = MembersSuspendBatchReportDeliveryStatus("other") + +MembersSuspendBatchRowFailure._protected_acting_admin_validator = bv.Void() +MembersSuspendBatchRowFailure._permission_changed_validator = bv.Void() +MembersSuspendBatchRowFailure._suspend_failed_validator = bv.Void() +MembersSuspendBatchRowFailure._tagmap = { + "protected_acting_admin": MembersSuspendBatchRowFailure._protected_acting_admin_validator, + "permission_changed": MembersSuspendBatchRowFailure._permission_changed_validator, + "suspend_failed": MembersSuspendBatchRowFailure._suspend_failed_validator, +} +MembersSuspendBatchRowFailure._tagmap.update(MembersSuspendError._tagmap) + +MembersSuspendBatchRowFailure.protected_acting_admin = MembersSuspendBatchRowFailure( + "protected_acting_admin" +) +MembersSuspendBatchRowFailure.permission_changed = MembersSuspendBatchRowFailure( + "permission_changed" +) +MembersSuspendBatchRowFailure.suspend_failed = MembersSuspendBatchRowFailure("suspend_failed") + +MembersSuspendBatchRowOutcome._suspended_validator = bv.Void() +MembersSuspendBatchRowOutcome._failed_validator = MembersSuspendBatchRowFailure_validator +MembersSuspendBatchRowOutcome._unknown_validator = bv.Void() +MembersSuspendBatchRowOutcome._other_validator = bv.Void() +MembersSuspendBatchRowOutcome._tagmap = { + "suspended": MembersSuspendBatchRowOutcome._suspended_validator, + "failed": MembersSuspendBatchRowOutcome._failed_validator, + "unknown": MembersSuspendBatchRowOutcome._unknown_validator, + "other": MembersSuspendBatchRowOutcome._other_validator, +} + +MembersSuspendBatchRowOutcome.suspended = MembersSuspendBatchRowOutcome("suspended") +MembersSuspendBatchRowOutcome.unknown = MembersSuspendBatchRowOutcome("unknown") +MembersSuspendBatchRowOutcome.other = MembersSuspendBatchRowOutcome("other") + +MembersSuspendBatchTarget.client_item_id.validator = bv.String(min_length=1, max_length=128) +MembersSuspendBatchTarget.suspend_arg.validator = MembersDeactivateArg_validator +MembersSuspendBatchTarget._all_field_names_ = set( + [ + "client_item_id", + "suspend_arg", + ] +) +MembersSuspendBatchTarget._all_fields_ = [ + ("client_item_id", MembersSuspendBatchTarget.client_item_id.validator), + ("suspend_arg", MembersSuspendBatchTarget.suspend_arg.validator), +] + +MembersSuspendBatchTaskFailure._unusable_result_validator = bv.Void() +MembersSuspendBatchTaskFailure._other_validator = bv.Void() +MembersSuspendBatchTaskFailure._tagmap = { + "unusable_result": MembersSuspendBatchTaskFailure._unusable_result_validator, + "other": MembersSuspendBatchTaskFailure._other_validator, +} + +MembersSuspendBatchTaskFailure.unusable_result = MembersSuspendBatchTaskFailure("unusable_result") +MembersSuspendBatchTaskFailure.other = MembersSuspendBatchTaskFailure("other") + MembersTransferFormerMembersFilesError._user_data_is_being_transferred_validator = bv.Void() MembersTransferFormerMembersFilesError._user_not_removed_validator = bv.Void() MembersTransferFormerMembersFilesError._user_data_cannot_be_transferred_validator = bv.Void() @@ -20343,6 +21040,24 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): MembersSuspendError_validator, {"auth": "team", "host": "api", "style": "rpc"}, ) +members_suspend_batch = bb.Route( + "members/suspend_batch", + 1, + False, + MembersSuspendBatchArg_validator, + async_.LaunchResultBase_validator, + MembersSuspendBatchError_validator, + {"auth": "team", "host": "api", "style": "rpc"}, +) +members_suspend_batch_job_status_check = bb.Route( + "members/suspend_batch/job_status/check", + 1, + False, + async_.PollArg_validator, + MembersSuspendBatchJobStatus_validator, + async_.PollError_validator, + {"auth": "team", "host": "api", "style": "rpc"}, +) members_unsuspend = bb.Route( "members/unsuspend", 1, @@ -20640,6 +21355,8 @@ def _process_custom_annotations(self, annotation_type, field_path, processor): "members/set_profile_photo": members_set_profile_photo, "members/set_profile_photo:2": members_set_profile_photo_v2, "members/suspend": members_suspend, + "members/suspend_batch": members_suspend_batch, + "members/suspend_batch/job_status/check": members_suspend_batch_job_status_check, "members/unsuspend": members_unsuspend, "namespaces/list": namespaces_list, "namespaces/list/continue": namespaces_list_continue, diff --git a/spec b/spec index 3f06f3f..0adcebc 160000 --- a/spec +++ b/spec @@ -1 +1 @@ -Subproject commit 3f06f3f85201cd17cfe67701525ca1bd2dade8b2 +Subproject commit 0adcebc8331935c905bceac02237314074ff5a4a