diff --git a/.codegen.json b/.codegen.json index f12674df..d018b340 100644 --- a/.codegen.json +++ b/.codegen.json @@ -1 +1 @@ -{ "engineHash": "7fa5d4a", "specHash": "131c54a", "version": "10.13.0" } +{ "engineHash": "2cee311", "specHash": "cc375ad", "version": "10.13.0" } diff --git a/box_sdk_gen/client.py b/box_sdk_gen/client.py index 25518b94..1be4933e 100644 --- a/box_sdk_gen/client.py +++ b/box_sdk_gen/client.py @@ -196,6 +196,8 @@ from box_sdk_gen.managers.notes import NotesManager +from box_sdk_gen.managers.query import QueryManager + from box_sdk_gen.networking.auth import Authentication from box_sdk_gen.networking.network import NetworkSession @@ -472,6 +474,7 @@ def __init__(self, auth: Authentication, *, network_session: NetworkSession = No auth=self.auth, network_session=self.network_session ) self.notes = NotesManager(auth=self.auth, network_session=self.network_session) + self.query = QueryManager(auth=self.auth, network_session=self.network_session) def make_request(self, fetch_options: FetchOptions) -> FetchResponse: """ diff --git a/box_sdk_gen/managers/__init__.py b/box_sdk_gen/managers/__init__.py index 2a1464fc..7ce34c33 100644 --- a/box_sdk_gen/managers/__init__.py +++ b/box_sdk_gen/managers/__init__.py @@ -167,3 +167,5 @@ from box_sdk_gen.managers.automate_workflows import * from box_sdk_gen.managers.notes import * + +from box_sdk_gen.managers.query import * diff --git a/box_sdk_gen/managers/query.py b/box_sdk_gen/managers/query.py new file mode 100644 index 00000000..82001e0a --- /dev/null +++ b/box_sdk_gen/managers/query.py @@ -0,0 +1,269 @@ +from typing import Optional + +from typing import Dict + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json import serialize + +from box_sdk_gen.serialization.json import deserialize + +from box_sdk_gen.schemas.v2026_r0.query_ancestor_reference_v2026_r0 import ( + QueryAncestorReferenceV2026R0, +) + +from box_sdk_gen.schemas.v2026_r0.query_insights_group_by_v2026_r0 import ( + QueryInsightsGroupByV2026R0, +) + +from box_sdk_gen.schemas.v2026_r0.query_order_by_v2026_r0 import QueryOrderByV2026R0 + +from box_sdk_gen.networking.fetch_options import ResponseFormat + +from box_sdk_gen.schemas.v2026_r0.query_insights_metric_definition_v2026_r0 import ( + QueryInsightsMetricDefinitionV2026R0, +) + +from box_sdk_gen.schemas.v2026_r0.query_results_v2026_r0 import QueryResultsV2026R0 + +from box_sdk_gen.schemas.v2026_r0.client_error_v2026_r0 import ClientErrorV2026R0 + +from box_sdk_gen.parameters.v2026_r0.box_version_header_v2026_r0 import ( + BoxVersionHeaderV2026R0, +) + +from box_sdk_gen.schemas.v2026_r0.query_request_body_v2026_r0 import ( + QueryRequestBodyV2026R0, +) + +from box_sdk_gen.schemas.v2026_r0.query_insights_v2026_r0 import QueryInsightsV2026R0 + +from box_sdk_gen.schemas.v2026_r0.query_insights_request_body_v2026_r0 import ( + QueryInsightsRequestBodyV2026R0, +) + +from box_sdk_gen.box.errors import BoxSDKError + +from box_sdk_gen.networking.auth import Authentication + +from box_sdk_gen.networking.network import NetworkSession + +from box_sdk_gen.networking.fetch_options import FetchOptions + +from box_sdk_gen.networking.fetch_response import FetchResponse + +from box_sdk_gen.internal.utils import prepare_params + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.internal.utils import ByteStream + +from box_sdk_gen.serialization.json import sd_to_json + +from box_sdk_gen.serialization.json import SerializedData + + +class CreateQueryV2026R0Query(BaseObject): + def __init__( + self, + predicate: str, + *, + params: Optional[Dict] = None, + ancestors: Optional[List[QueryAncestorReferenceV2026R0]] = None, + **kwargs + ): + """ + :param predicate: A logical expression used to filter the dataset, similar to an SQL + `WHERE` clause. May include named parameters referenced as + `:placeholder`. + :type predicate: str + :param params: A map of placeholder names (without the `:` prefix) to their values. + Required only when the predicate contains parameter placeholders. The + type of each value must match the type of the field it is compared to., defaults to None + :type params: Optional[Dict], optional + :param ancestors: Restricts results to the specified ancestor entities and their + recursive descendants. The user must have read access to every listed + ancestor., defaults to None + :type ancestors: Optional[List[QueryAncestorReferenceV2026R0]], optional + """ + super().__init__(**kwargs) + self.predicate = predicate + self.params = params + self.ancestors = ancestors + + +class CreateQueryInsightV2026R0Query(BaseObject): + def __init__( + self, + predicate: str, + *, + params: Optional[Dict] = None, + ancestors: Optional[List[QueryAncestorReferenceV2026R0]] = None, + group_by: Optional[List[QueryInsightsGroupByV2026R0]] = None, + **kwargs + ): + """ + :param predicate: A logical expression used to filter the dataset prior to metric + computation, similar to an SQL `WHERE` clause. May include + named parameters referenced as `:placeholder`. + :type predicate: str + :param params: A map of placeholder names (without the `:` prefix) to their values. + Required only when the predicate contains parameter placeholders. The + type of each value must match the type of the field it is compared to., defaults to None + :type params: Optional[Dict], optional + :param ancestors: Restricts results to items contained within any of the specified + ancestors. The user must have access to every listed ancestor. When + omitted, insights are computed across all accessible items., defaults to None + :type ancestors: Optional[List[QueryAncestorReferenceV2026R0]], optional + :param group_by: Defines how data is grouped for insights computation. Currently only a + single grouping field is supported., defaults to None + :type group_by: Optional[List[QueryInsightsGroupByV2026R0]], optional + """ + super().__init__(**kwargs) + self.predicate = predicate + self.params = params + self.ancestors = ancestors + self.group_by = group_by + + +class QueryManager: + def __init__( + self, + *, + auth: Optional[Authentication] = None, + network_session: NetworkSession = None + ): + if network_session is None: + network_session = NetworkSession() + self.auth = auth + self.network_session = network_session + + def create_query_v2026_r0( + self, + query: CreateQueryV2026R0Query, + *, + order_by: Optional[List[QueryOrderByV2026R0]] = None, + limit: Optional[int] = None, + fields: Optional[List[str]] = None, + marker: Optional[str] = None, + box_version: BoxVersionHeaderV2026R0 = BoxVersionHeaderV2026R0._2026_0, + extra_headers: Optional[Dict[str, Optional[str]]] = None + ) -> QueryResultsV2026R0: + """ + Runs a query to discover Box items using a logical predicate that can filter + + across item fields and metadata templates. Results can be sorted, paginated, + + + and shaped to include additional item or metadata fields. + + :param query: The query definition, including the filtering predicate and its optional + parameters and ancestor restrictions. + :type query: CreateQueryV2026R0Query + :param order_by: The sorting criteria for the result set. Entries are applied sequentially + to define multi-level sorting., defaults to None + :type order_by: Optional[List[QueryOrderByV2026R0]], optional + :param limit: The maximum number of results to return. Defaults to `50` when not + provided., defaults to None + :type limit: Optional[int], optional + :param fields: Controls which additional fields are included in each result entry. Each + value must be one of: a fully qualified item field key (for example + `box:item:name`), a metadata template key to hydrate the full template (for + example `enterprise_12345678:project`), or a specific metadata template + field key to hydrate a single field from the template (for example + `enterprise_12345678:project:name`). When omitted, entries include only the + item type and identifier., defaults to None + :type fields: Optional[List[str]], optional + :param marker: An opaque token returned from a previous response, used to continue + retrieval. When provided, all other request parameters must exactly match + those of the original request., defaults to None + :type marker: Optional[str], optional + :param box_version: Version header., defaults to BoxVersionHeaderV2026R0._2026_0 + :type box_version: BoxVersionHeaderV2026R0, optional + :param extra_headers: Extra headers that will be included in the HTTP request., defaults to None + :type extra_headers: Optional[Dict[str, Optional[str]]], optional + """ + if extra_headers is None: + extra_headers = {} + request_body: Dict = { + 'query': query, + 'order_by': order_by, + 'limit': limit, + 'fields': fields, + 'marker': marker, + } + headers_map: Dict[str, str] = prepare_params( + {'box-version': to_string(box_version), **extra_headers} + ) + response: FetchResponse = self.network_session.network_client.fetch( + FetchOptions( + url=''.join([self.network_session.base_urls.base_url, '/2.0/query']), + method='POST', + headers=headers_map, + data=serialize(request_body), + content_type='application/json', + response_format=ResponseFormat.JSON, + auth=self.auth, + network_session=self.network_session, + ) + ) + return deserialize(response.data, QueryResultsV2026R0) + + def create_query_insight_v2026_r0( + self, + query: CreateQueryInsightV2026R0Query, + metrics: Dict[str, QueryInsightsMetricDefinitionV2026R0], + *, + box_version: BoxVersionHeaderV2026R0 = BoxVersionHeaderV2026R0._2026_0, + extra_headers: Optional[Dict[str, Optional[str]]] = None + ) -> QueryInsightsV2026R0: + """ + Computes aggregated metrics over Box items matching a query predicate. + + Filters are applied first, followed by optional grouping, after which the + + + requested metrics (such as `sum`, `avg`, `min`, `max`, and `count`) are + + + computed for each resulting group or over the entire filtered dataset. + + :param query: The filtering and grouping definition. Filters are applied first, followed + by grouping, before metrics are computed. + :type query: CreateQueryInsightV2026R0Query + :param metrics: A map of user-defined metric aliases to their definitions. A maximum of 10 + metrics may be defined. Each alias must be a unique, non-empty string of up + to 256 characters, containing only letters, digits, `_`, `-`, or `.`, and + must not start with a digit, `_`, `-`, or `.`. May be empty to request + only a total count. + :type metrics: Dict[str, QueryInsightsMetricDefinitionV2026R0] + :param box_version: Version header., defaults to BoxVersionHeaderV2026R0._2026_0 + :type box_version: BoxVersionHeaderV2026R0, optional + :param extra_headers: Extra headers that will be included in the HTTP request., defaults to None + :type extra_headers: Optional[Dict[str, Optional[str]]], optional + """ + if extra_headers is None: + extra_headers = {} + request_body: Dict = {'query': query, 'metrics': metrics} + headers_map: Dict[str, str] = prepare_params( + {'box-version': to_string(box_version), **extra_headers} + ) + response: FetchResponse = self.network_session.network_client.fetch( + FetchOptions( + url=''.join( + [self.network_session.base_urls.base_url, '/2.0/query_insights'] + ), + method='POST', + headers=headers_map, + data=serialize(request_body), + content_type='application/json', + response_format=ResponseFormat.JSON, + auth=self.auth, + network_session=self.network_session, + ) + ) + return deserialize(response.data, QueryInsightsV2026R0) diff --git a/box_sdk_gen/schemas/file_full.py b/box_sdk_gen/schemas/file_full.py index c9535978..682a6851 100644 --- a/box_sdk_gen/schemas/file_full.py +++ b/box_sdk_gen/schemas/file_full.py @@ -30,6 +30,8 @@ from box_sdk_gen.schemas.metadata_full import MetadataFull +from box_sdk_gen.schemas.collection import Collection + from box_sdk_gen.box.errors import BoxSDKError from box_sdk_gen.internal.utils import DateTime @@ -413,6 +415,12 @@ class FileFullSharedLinkPermissionOptionsField(str, Enum): CAN_EDIT = 'can_edit' +class FileFullAllowedSharedLinkAccessLevelsField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + + class FileFull(File): _discriminator = 'type', {'file'} @@ -443,6 +451,13 @@ def __init__( List[FileFullSharedLinkPermissionOptionsField] ] = None, is_associated_with_app_item: Optional[bool] = None, + collections: Optional[List[Collection]] = None, + is_download_available: Optional[bool] = None, + download_url: Optional[str] = None, + authenticated_download_url: Optional[str] = None, + allowed_shared_link_access_levels: Optional[ + List[FileFullAllowedSharedLinkAccessLevelsField] + ] = None, description: Optional[str] = None, size: Optional[int] = None, path_collection: Optional[FilePathCollectionField] = None, @@ -509,6 +524,36 @@ def __init__( true even if the context user does not have access to the app item(s) associated with the file., defaults to None :type is_associated_with_app_item: Optional[bool], optional + :param collections: The collections that this file belongs to. + + For more information, see the + [collections guide](https://developer.box.com/guides/collections)., defaults to None + :type collections: Optional[List[Collection]], optional + :param is_download_available: Whether the file's binary content is eligible to be downloaded. + + This is a content-level flag and does not reflect whether the + current user is authorized to download the file. Use + `permissions.can_download`, when available, for that., defaults to None + :type is_download_available: Optional[bool], optional + :param download_url: A pre-authorized, expiring URL for directly downloading the file's + content. Requires authentication and is valid only for the current + session. + + This field is only returned for files, not folders or web links., defaults to None + :type download_url: Optional[str], optional + :param authenticated_download_url: A stable API URL for the file content endpoint, + `/2.0/files/{id}/content`. Unlike `download_url`, authorization is + evaluated when the URL is requested with a valid access token. + + This field is only returned for files, not folders or web links., defaults to None + :type authenticated_download_url: Optional[str], optional + :param allowed_shared_link_access_levels: The shared link access levels the authenticated user is allowed to + use when creating or updating a shared link for this file. + + The list depends on item policy and user authorization, so it may be + narrower than the levels available to the owner. An empty array means + no access level is available to this user., defaults to None + :type allowed_shared_link_access_levels: Optional[List[FileFullAllowedSharedLinkAccessLevelsField]], optional :param description: The optional description of this file. If the description exceeds 255 characters, the first 255 characters are set as a file description and the rest of it is ignored., defaults to None @@ -595,3 +640,8 @@ def __init__( self.disposition_at = disposition_at self.shared_link_permission_options = shared_link_permission_options self.is_associated_with_app_item = is_associated_with_app_item + self.collections = collections + self.is_download_available = is_download_available + self.download_url = download_url + self.authenticated_download_url = authenticated_download_url + self.allowed_shared_link_access_levels = allowed_shared_link_access_levels diff --git a/box_sdk_gen/schemas/folder_full.py b/box_sdk_gen/schemas/folder_full.py index 734d8ef9..2d58bcce 100644 --- a/box_sdk_gen/schemas/folder_full.py +++ b/box_sdk_gen/schemas/folder_full.py @@ -30,6 +30,8 @@ from box_sdk_gen.schemas.metadata_full import MetadataFull +from box_sdk_gen.schemas.collection import Collection + from box_sdk_gen.box.errors import BoxSDKError @@ -182,6 +184,7 @@ def __init__( can_non_owners_view_collaborators: Optional[bool] = None, classification: Optional[FolderFullClassificationField] = None, is_associated_with_app_item: Optional[bool] = None, + collections: Optional[List[Collection]] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, description: Optional[str] = None, @@ -219,11 +222,12 @@ def __init__( :param is_externally_owned: Specifies if this folder is owned by a user outside of the authenticated enterprise., defaults to None :type is_externally_owned: Optional[bool], optional - :param allowed_shared_link_access_levels: A list of access levels that are available - for this folder. + :param allowed_shared_link_access_levels: The shared link access levels the authenticated user is allowed to + use when creating or updating a shared link for this folder. - For some folders, like the root folder, this will always - be an empty list as sharing is not allowed at that level., defaults to None + The list depends on item policy and user authorization. For some + folders, like the root folder, this is always empty as sharing is + not allowed at that level., defaults to None :type allowed_shared_link_access_levels: Optional[List[FolderFullAllowedSharedLinkAccessLevelsField]], optional :param allowed_invitee_roles: A list of the types of roles that user can be invited at when sharing this folder., defaults to None @@ -244,6 +248,11 @@ def __init__( return true even if the context user does not have access to the app item(s) associated with the folder., defaults to None :type is_associated_with_app_item: Optional[bool], optional + :param collections: The collections that this folder belongs to. + + For more information, see the + [collections guide](https://developer.box.com/guides/collections)., defaults to None + :type collections: Optional[List[Collection]], optional :param created_at: The date and time when the folder was created. This value may be `null` for some folders such as the root folder or the trash folder., defaults to None @@ -332,3 +341,4 @@ def __init__( self.can_non_owners_view_collaborators = can_non_owners_view_collaborators self.classification = classification self.is_associated_with_app_item = is_associated_with_app_item + self.collections = collections diff --git a/box_sdk_gen/schemas/v2026_r0/__init__.py b/box_sdk_gen/schemas/v2026_r0/__init__.py index 5735f86f..95e2bce5 100644 --- a/box_sdk_gen/schemas/v2026_r0/__init__.py +++ b/box_sdk_gen/schemas/v2026_r0/__init__.py @@ -10,6 +10,28 @@ from box_sdk_gen.schemas.v2026_r0.notes_convert_response_v2026_r0 import * +from box_sdk_gen.schemas.v2026_r0.query_ancestor_reference_v2026_r0 import * + +from box_sdk_gen.schemas.v2026_r0.query_insight_metric_result_v2026_r0 import * + +from box_sdk_gen.schemas.v2026_r0.query_insight_entry_v2026_r0 import * + +from box_sdk_gen.schemas.v2026_r0.query_insights_v2026_r0 import * + +from box_sdk_gen.schemas.v2026_r0.query_insights_group_by_v2026_r0 import * + +from box_sdk_gen.schemas.v2026_r0.query_insights_metric_definition_v2026_r0 import * + +from box_sdk_gen.schemas.v2026_r0.query_insights_request_body_v2026_r0 import * + +from box_sdk_gen.schemas.v2026_r0.query_order_by_v2026_r0 import * + +from box_sdk_gen.schemas.v2026_r0.query_request_body_v2026_r0 import * + +from box_sdk_gen.schemas.v2026_r0.query_result_entry_v2026_r0 import * + +from box_sdk_gen.schemas.v2026_r0.query_results_v2026_r0 import * + from box_sdk_gen.schemas.v2026_r0.user_base_v2026_r0 import * from box_sdk_gen.schemas.v2026_r0.user_mini_v2026_r0 import * diff --git a/box_sdk_gen/schemas/v2026_r0/query_ancestor_reference_v2026_r0.py b/box_sdk_gen/schemas/v2026_r0/query_ancestor_reference_v2026_r0.py new file mode 100644 index 00000000..b8515b8b --- /dev/null +++ b/box_sdk_gen/schemas/v2026_r0/query_ancestor_reference_v2026_r0.py @@ -0,0 +1,16 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + + +class QueryAncestorReferenceV2026R0(BaseObject): + def __init__(self, id: str, type: str, **kwargs): + """ + :param id: The unique identifier of the ancestor entity. + :type id: str + :param type: The type of the ancestor entity. Possible value: folder. + :type type: str + """ + super().__init__(**kwargs) + self.id = id + self.type = type diff --git a/box_sdk_gen/schemas/v2026_r0/query_insight_entry_v2026_r0.py b/box_sdk_gen/schemas/v2026_r0/query_insight_entry_v2026_r0.py new file mode 100644 index 00000000..ccf391f0 --- /dev/null +++ b/box_sdk_gen/schemas/v2026_r0/query_insight_entry_v2026_r0.py @@ -0,0 +1,47 @@ +from enum import Enum + +from typing import List + +from typing import Dict + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.v2026_r0.query_insight_metric_result_v2026_r0 import ( + QueryInsightMetricResultV2026R0, +) + +from box_sdk_gen.box.errors import BoxSDKError + + +class QueryInsightEntryV2026R0TypeField(str, Enum): + GROUP = 'group' + OVERALL = 'overall' + OTHER = 'other' + + +class QueryInsightEntryV2026R0(BaseObject): + _discriminator = 'type', {'group', 'overall', 'other'} + + def __init__( + self, + key: List[str], + type: QueryInsightEntryV2026R0TypeField, + metrics: Dict[str, QueryInsightMetricResultV2026R0], + **kwargs + ): + """ + :param key: The grouping key values associated with the entry. Contains one value per + `group_by` field for `group` entries, and is empty for `overall` and + `other` entries. + :type key: List[str] + :param type: The type of insight entry, indicating how the associated metrics are + aggregated. + :type type: QueryInsightEntryV2026R0TypeField + :param metrics: A map of metric aliases to their computed results. For `other` entries, the + count is reported under the `totalCountBeyondTopGroups` key. + :type metrics: Dict[str, QueryInsightMetricResultV2026R0] + """ + super().__init__(**kwargs) + self.key = key + self.type = type + self.metrics = metrics diff --git a/box_sdk_gen/schemas/v2026_r0/query_insight_metric_result_v2026_r0.py b/box_sdk_gen/schemas/v2026_r0/query_insight_metric_result_v2026_r0.py new file mode 100644 index 00000000..d93966c5 --- /dev/null +++ b/box_sdk_gen/schemas/v2026_r0/query_insight_metric_result_v2026_r0.py @@ -0,0 +1,19 @@ +from typing import Dict + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + + +class QueryInsightMetricResultV2026R0(BaseObject): + def __init__(self, type: str, values: Dict[str, float], **kwargs): + """ + :param type: The metric type that was computed. + :type type: str + :param values: The computed metric result(s), keyed by the metric function (for example + `sum`, `avg`, `min`, `max`, or `count`). + :type values: Dict[str, float] + """ + super().__init__(**kwargs) + self.type = type + self.values = values diff --git a/box_sdk_gen/schemas/v2026_r0/query_insights_group_by_v2026_r0.py b/box_sdk_gen/schemas/v2026_r0/query_insights_group_by_v2026_r0.py new file mode 100644 index 00000000..1671b31f --- /dev/null +++ b/box_sdk_gen/schemas/v2026_r0/query_insights_group_by_v2026_r0.py @@ -0,0 +1,19 @@ +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + + +class QueryInsightsGroupByV2026R0(BaseObject): + def __init__(self, field: str, *, bucket_limit: Optional[int] = None, **kwargs): + """ + :param field: The fully qualified field name to group by. Supports metadata and item + properties. + :type field: str + :param bucket_limit: The maximum number of buckets to return for the grouping. Defaults to `5`., defaults to None + :type bucket_limit: Optional[int], optional + """ + super().__init__(**kwargs) + self.field = field + self.bucket_limit = bucket_limit diff --git a/box_sdk_gen/schemas/v2026_r0/query_insights_metric_definition_v2026_r0.py b/box_sdk_gen/schemas/v2026_r0/query_insights_metric_definition_v2026_r0.py new file mode 100644 index 00000000..79670067 --- /dev/null +++ b/box_sdk_gen/schemas/v2026_r0/query_insights_metric_definition_v2026_r0.py @@ -0,0 +1,30 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + + +class QueryInsightsMetricDefinitionV2026R0TypeField(str, Enum): + SUM = 'sum' + AVG = 'avg' + MIN = 'min' + MAX = 'max' + COUNT = 'count' + + +class QueryInsightsMetricDefinitionV2026R0(BaseObject): + _discriminator = 'type', {'sum', 'avg', 'min', 'max', 'count'} + + def __init__( + self, type: QueryInsightsMetricDefinitionV2026R0TypeField, field: str, **kwargs + ): + """ + :param type: The aggregation function to apply. + :type type: QueryInsightsMetricDefinitionV2026R0TypeField + :param field: The fully qualified field name on which the metric is computed. + :type field: str + """ + super().__init__(**kwargs) + self.type = type + self.field = field diff --git a/box_sdk_gen/schemas/v2026_r0/query_insights_request_body_v2026_r0.py b/box_sdk_gen/schemas/v2026_r0/query_insights_request_body_v2026_r0.py new file mode 100644 index 00000000..b4d776c2 --- /dev/null +++ b/box_sdk_gen/schemas/v2026_r0/query_insights_request_body_v2026_r0.py @@ -0,0 +1,78 @@ +from typing import Optional + +from typing import Dict + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.v2026_r0.query_ancestor_reference_v2026_r0 import ( + QueryAncestorReferenceV2026R0, +) + +from box_sdk_gen.schemas.v2026_r0.query_insights_group_by_v2026_r0 import ( + QueryInsightsGroupByV2026R0, +) + +from box_sdk_gen.schemas.v2026_r0.query_insights_metric_definition_v2026_r0 import ( + QueryInsightsMetricDefinitionV2026R0, +) + +from box_sdk_gen.box.errors import BoxSDKError + + +class QueryInsightsRequestBodyV2026R0QueryField(BaseObject): + def __init__( + self, + predicate: str, + *, + params: Optional[Dict] = None, + ancestors: Optional[List[QueryAncestorReferenceV2026R0]] = None, + group_by: Optional[List[QueryInsightsGroupByV2026R0]] = None, + **kwargs + ): + """ + :param predicate: A logical expression used to filter the dataset prior to metric + computation, similar to an SQL `WHERE` clause. May include + named parameters referenced as `:placeholder`. + :type predicate: str + :param params: A map of placeholder names (without the `:` prefix) to their values. + Required only when the predicate contains parameter placeholders. The + type of each value must match the type of the field it is compared to., defaults to None + :type params: Optional[Dict], optional + :param ancestors: Restricts results to items contained within any of the specified + ancestors. The user must have access to every listed ancestor. When + omitted, insights are computed across all accessible items., defaults to None + :type ancestors: Optional[List[QueryAncestorReferenceV2026R0]], optional + :param group_by: Defines how data is grouped for insights computation. Currently only a + single grouping field is supported., defaults to None + :type group_by: Optional[List[QueryInsightsGroupByV2026R0]], optional + """ + super().__init__(**kwargs) + self.predicate = predicate + self.params = params + self.ancestors = ancestors + self.group_by = group_by + + +class QueryInsightsRequestBodyV2026R0(BaseObject): + def __init__( + self, + query: QueryInsightsRequestBodyV2026R0QueryField, + metrics: Dict[str, QueryInsightsMetricDefinitionV2026R0], + **kwargs + ): + """ + :param query: The filtering and grouping definition. Filters are applied first, followed + by grouping, before metrics are computed. + :type query: QueryInsightsRequestBodyV2026R0QueryField + :param metrics: A map of user-defined metric aliases to their definitions. A maximum of 10 + metrics may be defined. Each alias must be a unique, non-empty string of up + to 256 characters, containing only letters, digits, `_`, `-`, or `.`, and + must not start with a digit, `_`, `-`, or `.`. May be empty to request + only a total count. + :type metrics: Dict[str, QueryInsightsMetricDefinitionV2026R0] + """ + super().__init__(**kwargs) + self.query = query + self.metrics = metrics diff --git a/box_sdk_gen/schemas/v2026_r0/query_insights_v2026_r0.py b/box_sdk_gen/schemas/v2026_r0/query_insights_v2026_r0.py new file mode 100644 index 00000000..f052c008 --- /dev/null +++ b/box_sdk_gen/schemas/v2026_r0/query_insights_v2026_r0.py @@ -0,0 +1,20 @@ +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.v2026_r0.query_insight_entry_v2026_r0 import ( + QueryInsightEntryV2026R0, +) + +from box_sdk_gen.box.errors import BoxSDKError + + +class QueryInsightsV2026R0(BaseObject): + def __init__(self, insights: List[QueryInsightEntryV2026R0], **kwargs): + """ + :param insights: The list of computed insight entries. Each entry corresponds to a group, + the overall dataset, or the aggregate of groups outside the top results. + :type insights: List[QueryInsightEntryV2026R0] + """ + super().__init__(**kwargs) + self.insights = insights diff --git a/box_sdk_gen/schemas/v2026_r0/query_order_by_v2026_r0.py b/box_sdk_gen/schemas/v2026_r0/query_order_by_v2026_r0.py new file mode 100644 index 00000000..a63d7ab9 --- /dev/null +++ b/box_sdk_gen/schemas/v2026_r0/query_order_by_v2026_r0.py @@ -0,0 +1,25 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + + +class QueryOrderByV2026R0DirectionField(str, Enum): + ASC = 'asc' + DESC = 'desc' + + +class QueryOrderByV2026R0(BaseObject): + def __init__( + self, field_key: str, direction: QueryOrderByV2026R0DirectionField, **kwargs + ): + """ + :param field_key: The fully qualified field key to sort by. + :type field_key: str + :param direction: The direction in which results are ordered. + :type direction: QueryOrderByV2026R0DirectionField + """ + super().__init__(**kwargs) + self.field_key = field_key + self.direction = direction diff --git a/box_sdk_gen/schemas/v2026_r0/query_request_body_v2026_r0.py b/box_sdk_gen/schemas/v2026_r0/query_request_body_v2026_r0.py new file mode 100644 index 00000000..fadc4366 --- /dev/null +++ b/box_sdk_gen/schemas/v2026_r0/query_request_body_v2026_r0.py @@ -0,0 +1,86 @@ +from typing import Optional + +from typing import Dict + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.v2026_r0.query_ancestor_reference_v2026_r0 import ( + QueryAncestorReferenceV2026R0, +) + +from box_sdk_gen.schemas.v2026_r0.query_order_by_v2026_r0 import QueryOrderByV2026R0 + +from box_sdk_gen.box.errors import BoxSDKError + + +class QueryRequestBodyV2026R0QueryField(BaseObject): + def __init__( + self, + predicate: str, + *, + params: Optional[Dict] = None, + ancestors: Optional[List[QueryAncestorReferenceV2026R0]] = None, + **kwargs + ): + """ + :param predicate: A logical expression used to filter the dataset, similar to an SQL + `WHERE` clause. May include named parameters referenced as + `:placeholder`. + :type predicate: str + :param params: A map of placeholder names (without the `:` prefix) to their values. + Required only when the predicate contains parameter placeholders. The + type of each value must match the type of the field it is compared to., defaults to None + :type params: Optional[Dict], optional + :param ancestors: Restricts results to the specified ancestor entities and their + recursive descendants. The user must have read access to every listed + ancestor., defaults to None + :type ancestors: Optional[List[QueryAncestorReferenceV2026R0]], optional + """ + super().__init__(**kwargs) + self.predicate = predicate + self.params = params + self.ancestors = ancestors + + +class QueryRequestBodyV2026R0(BaseObject): + def __init__( + self, + query: QueryRequestBodyV2026R0QueryField, + *, + order_by: Optional[List[QueryOrderByV2026R0]] = None, + limit: Optional[int] = None, + fields: Optional[List[str]] = None, + marker: Optional[str] = None, + **kwargs + ): + """ + :param query: The query definition, including the filtering predicate and its optional + parameters and ancestor restrictions. + :type query: QueryRequestBodyV2026R0QueryField + :param order_by: The sorting criteria for the result set. Entries are applied sequentially + to define multi-level sorting., defaults to None + :type order_by: Optional[List[QueryOrderByV2026R0]], optional + :param limit: The maximum number of results to return. Defaults to `50` when not + provided., defaults to None + :type limit: Optional[int], optional + :param fields: Controls which additional fields are included in each result entry. Each + value must be one of: a fully qualified item field key (for example + `box:item:name`), a metadata template key to hydrate the full template (for + example `enterprise_12345678:project`), or a specific metadata template + field key to hydrate a single field from the template (for example + `enterprise_12345678:project:name`). When omitted, entries include only the + item type and identifier., defaults to None + :type fields: Optional[List[str]], optional + :param marker: An opaque token returned from a previous response, used to continue + retrieval. When provided, all other request parameters must exactly match + those of the original request., defaults to None + :type marker: Optional[str], optional + """ + super().__init__(**kwargs) + self.query = query + self.order_by = order_by + self.limit = limit + self.fields = fields + self.marker = marker diff --git a/box_sdk_gen/schemas/v2026_r0/query_result_entry_v2026_r0.py b/box_sdk_gen/schemas/v2026_r0/query_result_entry_v2026_r0.py new file mode 100644 index 00000000..f562c705 --- /dev/null +++ b/box_sdk_gen/schemas/v2026_r0/query_result_entry_v2026_r0.py @@ -0,0 +1,17 @@ +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.box.errors import BoxSDKError + + +class QueryResultEntryV2026R0(BaseObject): + def __init__(self, id: str, type: str, **kwargs): + """ + :param id: The unique identifier of the matching item. + :type id: str + :param type: The type of the matching item. + :type type: str + """ + super().__init__(**kwargs) + self.id = id + self.type = type + self.extra_data = kwargs diff --git a/box_sdk_gen/schemas/v2026_r0/query_results_v2026_r0.py b/box_sdk_gen/schemas/v2026_r0/query_results_v2026_r0.py new file mode 100644 index 00000000..120d05aa --- /dev/null +++ b/box_sdk_gen/schemas/v2026_r0/query_results_v2026_r0.py @@ -0,0 +1,36 @@ +from typing import List + +from typing import Optional + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.v2026_r0.query_result_entry_v2026_r0 import ( + QueryResultEntryV2026R0, +) + +from box_sdk_gen.box.errors import BoxSDKError + + +class QueryResultsV2026R0(BaseObject): + def __init__( + self, + entries: List[QueryResultEntryV2026R0], + limit: int, + *, + next_marker: Optional[str] = None, + **kwargs + ): + """ + :param entries: The list of items matching the query predicate. + :type entries: List[QueryResultEntryV2026R0] + :param limit: The limit that was used for this request. This will be the same as the limit query + parameter unless that value exceeded the maximum value allowed. + :type limit: int + :param next_marker: The marker for the start of the next page of results. When `null`, there + are no further results available., defaults to None + :type next_marker: Optional[str], optional + """ + super().__init__(**kwargs) + self.entries = entries + self.limit = limit + self.next_marker = next_marker diff --git a/box_sdk_gen/schemas/web_link.py b/box_sdk_gen/schemas/web_link.py index 744df7c5..facbdf6a 100644 --- a/box_sdk_gen/schemas/web_link.py +++ b/box_sdk_gen/schemas/web_link.py @@ -16,6 +16,8 @@ from box_sdk_gen.schemas.user_mini import UserMini +from box_sdk_gen.schemas.collection import Collection + from box_sdk_gen.box.errors import BoxSDKError from box_sdk_gen.internal.utils import DateTime @@ -172,6 +174,12 @@ class WebLinkItemStatusField(str, Enum): DELETED = 'deleted' +class WebLinkAllowedSharedLinkAccessLevelsField(str, Enum): + OPEN = 'open' + COMPANY = 'company' + COLLABORATORS = 'collaborators' + + class WebLink(WebLinkMini): _discriminator = 'type', {'web_link'} @@ -191,6 +199,10 @@ def __init__( owned_by: Optional[UserMini] = None, shared_link: Optional[WebLinkSharedLinkField] = None, item_status: Optional[WebLinkItemStatusField] = None, + collections: Optional[List[Collection]] = None, + allowed_shared_link_access_levels: Optional[ + List[WebLinkAllowedSharedLinkAccessLevelsField] + ] = None, url: Optional[str] = None, sequence_id: Optional[str] = None, name: Optional[str] = None, @@ -217,6 +229,18 @@ def __init__( `trashed` if the file has been moved to the trash, and `deleted` if the file has been permanently deleted., defaults to None :type item_status: Optional[WebLinkItemStatusField], optional + :param collections: The collections that this web link belongs to. + + For more information, see the + [collections guide](https://developer.box.com/guides/collections)., defaults to None + :type collections: Optional[List[Collection]], optional + :param allowed_shared_link_access_levels: The shared link access levels the authenticated user is allowed to + use when creating or updating a shared link for this web link. + + The list depends on item policy and user authorization, so it may be + narrower than the levels available to the owner. An empty array means + no access level is available to this user., defaults to None + :type allowed_shared_link_access_levels: Optional[List[WebLinkAllowedSharedLinkAccessLevelsField]], optional :param url: The URL this web link points to., defaults to None :type url: Optional[str], optional :param name: The name of the web link., defaults to None @@ -248,3 +272,5 @@ def __init__( self.owned_by = owned_by self.shared_link = shared_link self.item_status = item_status + self.collections = collections + self.allowed_shared_link_access_levels = allowed_shared_link_access_levels diff --git a/docs/README.md b/docs/README.md index e9d057ee..271ddc11 100644 --- a/docs/README.md +++ b/docs/README.md @@ -62,6 +62,7 @@ the SDK are available by topic: - [Metadata taxonomies](metadata_taxonomies.md) - [Metadata templates](metadata_templates.md) - [Notes](notes.md) +- [Query](query.md) - [Recent items](recent_items.md) - [Retention policies](retention_policies.md) - [Retention policy assignments](retention_policy_assignments.md) diff --git a/docs/query.md b/docs/query.md new file mode 100644 index 00000000..f26e1391 --- /dev/null +++ b/docs/query.md @@ -0,0 +1,71 @@ +# QueryManager + +- [Query for Box items](#query-for-box-items) +- [Create insights for Box items](#create-insights-for-box-items) + +## Query for Box items + +Runs a query to discover Box items using a logical predicate that can filter +across item fields and metadata templates. Results can be sorted, paginated, +and shaped to include additional item or metadata fields. + +This operation is performed by calling function `create_query_v2026_r0`. + +See the endpoint docs at +[API Reference](https://developer.box.com/reference/v2026.0/post-query/). + +_Currently we don't have an example for calling `create_query_v2026_r0` in integration tests_ + +### Arguments + +- query `CreateQueryV2026R0Query` + - The query definition, including the filtering predicate and its optional parameters and ancestor restrictions. +- order_by `Optional[List[QueryOrderByV2026R0]]` + - The sorting criteria for the result set. Entries are applied sequentially to define multi-level sorting. +- limit `Optional[int]` + - The maximum number of results to return. Defaults to `50` when not provided. +- fields `Optional[List[str]]` + - Controls which additional fields are included in each result entry. Each value must be one of: a fully qualified item field key (for example `box:item:name`), a metadata template key to hydrate the full template (for example `enterprise_12345678:project`), or a specific metadata template field key to hydrate a single field from the template (for example `enterprise_12345678:project:name`). When omitted, entries include only the item type and identifier. +- marker `Optional[str]` + - An opaque token returned from a previous response, used to continue retrieval. When provided, all other request parameters must exactly match those of the original request. +- box_version `BoxVersionHeaderV2026R0` + - Version header. +- extra_headers `Optional[Dict[str, Optional[str]]]` + - Extra headers that will be included in the HTTP request. + +### Returns + +This function returns a value of type `QueryResultsV2026R0`. + +Returns a paginated list of items matching the query. + +## Create insights for Box items + +Computes aggregated metrics over Box items matching a query predicate. +Filters are applied first, followed by optional grouping, after which the +requested metrics (such as `sum`, `avg`, `min`, `max`, and `count`) are +computed for each resulting group or over the entire filtered dataset. + +This operation is performed by calling function `create_query_insight_v2026_r0`. + +See the endpoint docs at +[API Reference](https://developer.box.com/reference/v2026.0/post-query-insights/). + +_Currently we don't have an example for calling `create_query_insight_v2026_r0` in integration tests_ + +### Arguments + +- query `CreateQueryInsightV2026R0Query` + - The filtering and grouping definition. Filters are applied first, followed by grouping, before metrics are computed. +- metrics `Dict[str, QueryInsightsMetricDefinitionV2026R0]` + - A map of user-defined metric aliases to their definitions. A maximum of 10 metrics may be defined. Each alias must be a unique, non-empty string of up to 256 characters, containing only letters, digits, `_`, `-`, or `.`, and must not start with a digit, `_`, `-`, or `.`. May be empty to request only a total count. +- box_version `BoxVersionHeaderV2026R0` + - Version header. +- extra_headers `Optional[Dict[str, Optional[str]]]` + - Extra headers that will be included in the HTTP request. + +### Returns + +This function returns a value of type `QueryInsightsV2026R0`. + +Returns the computed insight entries.