From 8b6ea0bbec719a36eb11b6d214c08801c4f1a40b Mon Sep 17 00:00:00 2001 From: box-sdk-build <94016436+box-sdk-build@users.noreply.github.com> Date: Fri, 6 Sep 2024 11:46:29 +0200 Subject: [PATCH] feat: Support App item associations (box/box-codegen#561) (#299) --- .codegen.json | 2 +- .github/workflows/build.yml | 4 + README.md | 1 + box_sdk_gen/client.py | 5 + box_sdk_gen/managers/__init__.py | 2 + box_sdk_gen/managers/app_item_associations.py | 195 ++++++++++++++++++ box_sdk_gen/schemas/__init__.py | 6 + box_sdk_gen/schemas/app_item.py | 32 +++ box_sdk_gen/schemas/app_item_association.py | 42 ++++ box_sdk_gen/schemas/app_item_associations.py | 34 +++ box_sdk_gen/schemas/collaboration.py | 4 + box_sdk_gen/schemas/file_full.py | 7 + box_sdk_gen/schemas/folder_full.py | 7 + docs/README.md | 1 + docs/app_item_associations.md | 84 ++++++++ docs/files.md | 2 +- docs/folders.md | 2 +- test/app_item_associations.py | 55 +++++ tox.ini | 4 +- 19 files changed, 484 insertions(+), 5 deletions(-) create mode 100644 box_sdk_gen/managers/app_item_associations.py create mode 100644 box_sdk_gen/schemas/app_item.py create mode 100644 box_sdk_gen/schemas/app_item_association.py create mode 100644 box_sdk_gen/schemas/app_item_associations.py create mode 100644 docs/app_item_associations.md create mode 100644 test/app_item_associations.py diff --git a/.codegen.json b/.codegen.json index bb6592c9..a8d7e4f1 100644 --- a/.codegen.json +++ b/.codegen.json @@ -1 +1 @@ -{ "engineHash": "a3c5813", "specHash": "739d87b", "version": "1.4.1" } +{ "engineHash": "66f851a", "specHash": "6ca858e", "version": "1.4.1" } diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a4996914..92e59e2a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,6 +39,8 @@ jobs: ENTERPRISE_ID: ${{ secrets.ENTERPRISE_ID }} BOX_FILE_REQUEST_ID: ${{ secrets.BOX_FILE_REQUEST_ID }} BOX_EXTERNAL_USER_EMAIL: ${{ secrets.BOX_EXTERNAL_USER_EMAIL }} + APP_ITEM_ASSOCIATION_FILE_ID: ${{ secrets.APP_ITEM_ASSOCIATION_FILE_ID }} + APP_ITEM_ASSOCIATION_FOLDER_ID: ${{ secrets.APP_ITEM_ASSOCIATION_FOLDER_ID }} WORKFLOW_FOLDER_ID: ${{ secrets.WORKFLOW_FOLDER_ID }} run: | tox @@ -73,3 +75,5 @@ jobs: BOX_FILE_REQUEST_ID: ${{ secrets.BOX_FILE_REQUEST_ID }} BOX_EXTERNAL_USER_EMAIL: ${{ secrets.BOX_EXTERNAL_USER_EMAIL }} WORKFLOW_FOLDER_ID: ${{ secrets.WORKFLOW_FOLDER_ID }} + APP_ITEM_ASSOCIATION_FILE_ID: ${{ secrets.APP_ITEM_ASSOCIATION_FILE_ID }} + APP_ITEM_ASSOCIATION_FOLDER_ID: ${{ secrets.APP_ITEM_ASSOCIATION_FOLDER_ID }} diff --git a/README.md b/README.md index 99ca2b49..fc23a044 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,7 @@ Now select `Authorization` and submit application to be reviewed by account admi 3. Set environment variable: `JWT_CONFIG_BASE_64` with base64 encoded jwt configuration file 4. Set environment variable: `BOX_FILE_REQUEST_ID` with ID of file request already created in the user account, `BOX_EXTERNAL_USER_EMAIL` with email of free external user which not belongs to any enterprise. 5. Set environment variable: `WORKFLOW_FOLDER_ID` with the ID of the Relay workflow that deletes the file that triggered the workflow. The workflow should have a manual start to be able to start it from the API. +6. Set environment variable: `APP_ITEM_ASSOCIATION_FILE_ID` to the ID of the file with associated app item and `APP_ITEM_ASSOCIATION_FOLDER_ID` to the ID of the folder with associated app item. ### Running tests diff --git a/box_sdk_gen/client.py b/box_sdk_gen/client.py index 368d0957..c781d315 100644 --- a/box_sdk_gen/client.py +++ b/box_sdk_gen/client.py @@ -6,6 +6,8 @@ from box_sdk_gen.managers.trashed_files import TrashedFilesManager +from box_sdk_gen.managers.app_item_associations import AppItemAssociationsManager + from box_sdk_gen.managers.downloads import DownloadsManager from box_sdk_gen.managers.uploads import UploadsManager @@ -182,6 +184,9 @@ def __init__(self, auth: Authentication, *, network_session: NetworkSession = No self.trashed_files = TrashedFilesManager( auth=self.auth, network_session=self.network_session ) + self.app_item_associations = AppItemAssociationsManager( + auth=self.auth, network_session=self.network_session + ) self.downloads = DownloadsManager( auth=self.auth, network_session=self.network_session ) diff --git a/box_sdk_gen/managers/__init__.py b/box_sdk_gen/managers/__init__.py index ca5771c5..dbeba680 100644 --- a/box_sdk_gen/managers/__init__.py +++ b/box_sdk_gen/managers/__init__.py @@ -4,6 +4,8 @@ from box_sdk_gen.managers.trashed_files import * +from box_sdk_gen.managers.app_item_associations import * + from box_sdk_gen.managers.downloads import * from box_sdk_gen.managers.uploads import * diff --git a/box_sdk_gen/managers/app_item_associations.py b/box_sdk_gen/managers/app_item_associations.py new file mode 100644 index 00000000..4c15353c --- /dev/null +++ b/box_sdk_gen/managers/app_item_associations.py @@ -0,0 +1,195 @@ +from typing import Optional + +from typing import Dict + +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.serialization.json.serializer import deserialize + +from box_sdk_gen.schemas.app_item_associations import AppItemAssociations + +from box_sdk_gen.schemas.client_error import ClientError + +from box_sdk_gen.networking.auth import Authentication + +from box_sdk_gen.networking.network import NetworkSession + +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.json_data import sd_to_json + +from box_sdk_gen.networking.fetch import FetchOptions + +from box_sdk_gen.networking.fetch import FetchResponse + +from box_sdk_gen.networking.fetch import fetch + +from box_sdk_gen.serialization.json.json_data import SerializedData + + +class AppItemAssociationsManager: + 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 get_file_app_item_associations( + self, + file_id: str, + *, + limit: Optional[int] = None, + marker: Optional[str] = None, + application_type: Optional[str] = None, + extra_headers: Optional[Dict[str, Optional[str]]] = None + ) -> AppItemAssociations: + """ + **This is a beta feature, which means that its availability might be limited.** + + Returns all app items the file is associated with. This includes app items + + + associated with ancestors of the file. Assuming the context user has access + + + to the file, the type/ids are revealed even if the context user does not + + + have **View** permission on the app item. + + :param file_id: The unique identifier that represents a file. + + The ID for any file can be determined + by visiting a file in the web application + and copying the ID from the URL. For example, + for the URL `https://*.app.box.com/files/123` + the `file_id` is `123`. + Example: "12345" + :type file_id: str + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param marker: Defines the position marker at which to begin returning results. This is + used when paginating using marker-based pagination. + + This requires `usemarker` to be set to `true`., defaults to None + :type marker: Optional[str], optional + :param application_type: If given, only return app items for this application type, defaults to None + :type application_type: Optional[str], 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 = {} + query_params_map: Dict[str, str] = prepare_params( + { + 'limit': to_string(limit), + 'marker': to_string(marker), + 'application_type': to_string(application_type), + } + ) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = fetch( + FetchOptions( + url=''.join( + [ + self.network_session.base_urls.base_url, + '/2.0/files/', + to_string(file_id), + '/app_item_associations', + ] + ), + method='GET', + params=query_params_map, + headers=headers_map, + response_format='json', + auth=self.auth, + network_session=self.network_session, + ) + ) + return deserialize(response.data, AppItemAssociations) + + def get_folder_app_item_associations( + self, + folder_id: str, + *, + limit: Optional[int] = None, + marker: Optional[str] = None, + application_type: Optional[str] = None, + extra_headers: Optional[Dict[str, Optional[str]]] = None + ) -> AppItemAssociations: + """ + **This is a beta feature, which means that its availability might be limited.** + + Returns all app items the folder is associated with. This includes app items + + + associated with ancestors of the folder. Assuming the context user has access + + + to the folder, the type/ids are revealed even if the context user does not + + + have **View** permission on the app item. + + :param folder_id: The unique identifier that represent a folder. + + The ID for any folder can be determined + by visiting this folder in the web application + and copying the ID from the URL. For example, + for the URL `https://*.app.box.com/folder/123` + the `folder_id` is `123`. + + The root folder of a Box account is + always represented by the ID `0`. + Example: "12345" + :type folder_id: str + :param limit: The maximum number of items to return per page., defaults to None + :type limit: Optional[int], optional + :param marker: Defines the position marker at which to begin returning results. This is + used when paginating using marker-based pagination. + + This requires `usemarker` to be set to `true`., defaults to None + :type marker: Optional[str], optional + :param application_type: If given, returns only app items for this application type, defaults to None + :type application_type: Optional[str], 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 = {} + query_params_map: Dict[str, str] = prepare_params( + { + 'limit': to_string(limit), + 'marker': to_string(marker), + 'application_type': to_string(application_type), + } + ) + headers_map: Dict[str, str] = prepare_params({**extra_headers}) + response: FetchResponse = fetch( + FetchOptions( + url=''.join( + [ + self.network_session.base_urls.base_url, + '/2.0/folders/', + to_string(folder_id), + '/app_item_associations', + ] + ), + method='GET', + params=query_params_map, + headers=headers_map, + response_format='json', + auth=self.auth, + network_session=self.network_session, + ) + ) + return deserialize(response.data, AppItemAssociations) diff --git a/box_sdk_gen/schemas/__init__.py b/box_sdk_gen/schemas/__init__.py index b5d4f912..70a466cf 100644 --- a/box_sdk_gen/schemas/__init__.py +++ b/box_sdk_gen/schemas/__init__.py @@ -18,6 +18,8 @@ from box_sdk_gen.schemas.ai_response import * +from box_sdk_gen.schemas.app_item import * + from box_sdk_gen.schemas.classification import * from box_sdk_gen.schemas.classification_template import * @@ -314,6 +316,10 @@ from box_sdk_gen.schemas.webhook_invocation import * +from box_sdk_gen.schemas.app_item_association import * + +from box_sdk_gen.schemas.app_item_associations import * + from box_sdk_gen.schemas.workflow_mini import * from box_sdk_gen.schemas.workflow import * diff --git a/box_sdk_gen/schemas/app_item.py b/box_sdk_gen/schemas/app_item.py new file mode 100644 index 00000000..50b4391b --- /dev/null +++ b/box_sdk_gen/schemas/app_item.py @@ -0,0 +1,32 @@ +from enum import Enum + +from box_sdk_gen.internal.base_object import BaseObject + + +class AppItemTypeField(str, Enum): + APP_ITEM = 'app_item' + + +class AppItem(BaseObject): + _discriminator = 'type', {'app_item'} + + def __init__( + self, + id: str, + application_type: str, + *, + type: AppItemTypeField = AppItemTypeField.APP_ITEM.value, + **kwargs + ): + """ + :param id: The unique identifier for this app item. + :type id: str + :param application_type: The type of the app that owns this app item. + :type application_type: str + :param type: `app_item`, defaults to AppItemTypeField.APP_ITEM.value + :type type: AppItemTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.application_type = application_type + self.type = type diff --git a/box_sdk_gen/schemas/app_item_association.py b/box_sdk_gen/schemas/app_item_association.py new file mode 100644 index 00000000..db478f8e --- /dev/null +++ b/box_sdk_gen/schemas/app_item_association.py @@ -0,0 +1,42 @@ +from enum import Enum + +from typing import Union + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.app_item import AppItem + +from box_sdk_gen.schemas.file_base import FileBase + +from box_sdk_gen.schemas.folder_base import FolderBase + +from box_sdk_gen.schemas.web_link_base import WebLinkBase + + +class AppItemAssociationTypeField(str, Enum): + APP_ITEM_ASSOCIATION = 'app_item_association' + + +class AppItemAssociation(BaseObject): + _discriminator = 'type', {'app_item_association'} + + def __init__( + self, + id: str, + app_item: AppItem, + item: Union[FileBase, FolderBase, WebLinkBase], + *, + type: AppItemAssociationTypeField = AppItemAssociationTypeField.APP_ITEM_ASSOCIATION.value, + **kwargs + ): + """ + :param id: The unique identifier for this app item association. + :type id: str + :param type: `app_item_association`, defaults to AppItemAssociationTypeField.APP_ITEM_ASSOCIATION.value + :type type: AppItemAssociationTypeField, optional + """ + super().__init__(**kwargs) + self.id = id + self.app_item = app_item + self.item = item + self.type = type diff --git a/box_sdk_gen/schemas/app_item_associations.py b/box_sdk_gen/schemas/app_item_associations.py new file mode 100644 index 00000000..a2317f91 --- /dev/null +++ b/box_sdk_gen/schemas/app_item_associations.py @@ -0,0 +1,34 @@ +from typing import Optional + +from typing import List + +from box_sdk_gen.internal.base_object import BaseObject + +from box_sdk_gen.schemas.app_item_association import AppItemAssociation + + +class AppItemAssociations(BaseObject): + def __init__( + self, + *, + limit: Optional[int] = None, + next_marker: Optional[str] = None, + prev_marker: Optional[str] = None, + entries: Optional[List[AppItemAssociation]] = None, + **kwargs + ): + """ + :param limit: The limit that was used for these entries. This will be the same as the + `limit` query parameter unless that value exceeded the maximum value + allowed. The maximum value varies by API., defaults to None + :type limit: Optional[int], optional + :param next_marker: The marker for the start of the next page of results., defaults to None + :type next_marker: Optional[str], optional + :param prev_marker: The marker for the start of the previous page of results., defaults to None + :type prev_marker: Optional[str], optional + """ + super().__init__(**kwargs) + self.limit = limit + self.next_marker = next_marker + self.prev_marker = prev_marker + self.entries = entries diff --git a/box_sdk_gen/schemas/collaboration.py b/box_sdk_gen/schemas/collaboration.py index d2213521..f012d99d 100644 --- a/box_sdk_gen/schemas/collaboration.py +++ b/box_sdk_gen/schemas/collaboration.py @@ -12,6 +12,8 @@ from box_sdk_gen.schemas.web_link import WebLink +from box_sdk_gen.schemas.app_item import AppItem + from box_sdk_gen.schemas.user_collaborations import UserCollaborations from box_sdk_gen.schemas.group_mini import GroupMini @@ -151,6 +153,7 @@ def __init__( *, type: CollaborationTypeField = CollaborationTypeField.COLLABORATION.value, item: Optional[Union[File, Folder, WebLink]] = None, + app_item: Optional[AppItem] = None, accessible_by: Optional[Union[UserCollaborations, GroupMini]] = None, invite_email: Optional[str] = None, role: Optional[CollaborationRoleField] = None, @@ -200,6 +203,7 @@ def __init__( self.id = id self.type = type self.item = item + self.app_item = app_item self.accessible_by = accessible_by self.invite_email = invite_email self.role = role diff --git a/box_sdk_gen/schemas/file_full.py b/box_sdk_gen/schemas/file_full.py index e4375a1b..ac7ee089 100644 --- a/box_sdk_gen/schemas/file_full.py +++ b/box_sdk_gen/schemas/file_full.py @@ -420,6 +420,7 @@ def __init__( shared_link_permission_options: Optional[ List[FileFullSharedLinkPermissionOptionsField] ] = None, + is_associated_with_app_item: Optional[bool] = None, description: Optional[str] = None, size: Optional[int] = None, path_collection: Optional[FilePathCollectionField] = None, @@ -481,6 +482,11 @@ def __init__( :param shared_link_permission_options: A list of the types of roles that user can be invited at when sharing this file., defaults to None :type shared_link_permission_options: Optional[List[FileFullSharedLinkPermissionOptionsField]], optional + :param is_associated_with_app_item: This field will return true if the file or any ancestor of the file + is associated with at least one app item. Note that this will return + 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 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 @@ -566,3 +572,4 @@ def __init__( self.uploader_display_name = uploader_display_name 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 diff --git a/box_sdk_gen/schemas/folder_full.py b/box_sdk_gen/schemas/folder_full.py index 3f7b4508..8879c5cc 100644 --- a/box_sdk_gen/schemas/folder_full.py +++ b/box_sdk_gen/schemas/folder_full.py @@ -159,6 +159,7 @@ def __init__( is_accessible_via_shared_link: Optional[bool] = None, can_non_owners_view_collaborators: Optional[bool] = None, classification: Optional[FolderFullClassificationField] = None, + is_associated_with_app_item: Optional[bool] = None, created_at: Optional[DateTime] = None, modified_at: Optional[DateTime] = None, description: Optional[str] = None, @@ -216,6 +217,11 @@ def __init__( It also restricts non-owners from inviting new collaborators., defaults to None :type can_non_owners_view_collaborators: Optional[bool], optional + :param is_associated_with_app_item: This field will return true if the folder or any ancestor of the + folder is associated with at least one app item. Note that this will + 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 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 @@ -303,3 +309,4 @@ def __init__( self.is_accessible_via_shared_link = is_accessible_via_shared_link 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 diff --git a/docs/README.md b/docs/README.md index 5d9255f5..b19cf1bd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,6 +6,7 @@ General explanations of the available functionality and examples of how to use the SDK are available by topic: - [Ai](ai.md) +- [App item associations](app_item_associations.md) - [Authorization](authorization.md) - [Avatars](avatars.md) - [Chunked uploads](chunked_uploads.md) diff --git a/docs/app_item_associations.md b/docs/app_item_associations.md new file mode 100644 index 00000000..0426b89b --- /dev/null +++ b/docs/app_item_associations.md @@ -0,0 +1,84 @@ +# AppItemAssociationsManager + +- [List file app item associations](#list-file-app-item-associations) +- [List folder app item associations](#list-folder-app-item-associations) + +## List file app item associations + +**This is a beta feature, which means that its availability might be limited.** +Returns all app items the file is associated with. This includes app items +associated with ancestors of the file. Assuming the context user has access +to the file, the type/ids are revealed even if the context user does not +have **View** permission on the app item. + +This operation is performed by calling function `get_file_app_item_associations`. + +See the endpoint docs at +[API Reference](https://developer.box.com/reference/get-files-id-app-item-associations/). + + + +```python +client.app_item_associations.get_file_app_item_associations(file_id) +``` + +### Arguments + +- file_id `str` + - The unique identifier that represents a file. The ID for any file can be determined by visiting a file in the web application and copying the ID from the URL. For example, for the URL `https://*.app.box.com/files/123` the `file_id` is `123`. Example: "12345" +- limit `Optional[int]` + - The maximum number of items to return per page. +- marker `Optional[str]` + - Defines the position marker at which to begin returning results. This is used when paginating using marker-based pagination. This requires `usemarker` to be set to `true`. +- application_type `Optional[str]` + - If given, only return app items for this application type +- 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 `AppItemAssociations`. + +Returns a collection of app item objects. If there are no +app items on this file, an empty collection will be returned. +This list includes app items on ancestors of this File. + +## List folder app item associations + +**This is a beta feature, which means that its availability might be limited.** +Returns all app items the folder is associated with. This includes app items +associated with ancestors of the folder. Assuming the context user has access +to the folder, the type/ids are revealed even if the context user does not +have **View** permission on the app item. + +This operation is performed by calling function `get_folder_app_item_associations`. + +See the endpoint docs at +[API Reference](https://developer.box.com/reference/get-folders-id-app-item-associations/). + + + +```python +client.app_item_associations.get_folder_app_item_associations(folder_id) +``` + +### Arguments + +- folder_id `str` + - The unique identifier that represent a folder. The ID for any folder can be determined by visiting this folder in the web application and copying the ID from the URL. For example, for the URL `https://*.app.box.com/folder/123` the `folder_id` is `123`. The root folder of a Box account is always represented by the ID `0`. Example: "12345" +- limit `Optional[int]` + - The maximum number of items to return per page. +- marker `Optional[str]` + - Defines the position marker at which to begin returning results. This is used when paginating using marker-based pagination. This requires `usemarker` to be set to `true`. +- application_type `Optional[str]` + - If given, returns only app items for this application type +- 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 `AppItemAssociations`. + +Returns a collection of app item objects. If there are no +app items on this folder an empty collection will be returned. +This list includes app items on ancestors of this folder. diff --git a/docs/files.md b/docs/files.md index 7c67ab6c..0ac0c5a5 100644 --- a/docs/files.md +++ b/docs/files.md @@ -18,7 +18,7 @@ See the endpoint docs at ```python -client.files.get_file_by_id(file.id) +client.files.get_file_by_id(file_id, fields=["is_associated_with_app_item"]) ``` ### Arguments diff --git a/docs/folders.md b/docs/folders.md index 885618f4..77628902 100644 --- a/docs/folders.md +++ b/docs/folders.md @@ -28,7 +28,7 @@ See the endpoint docs at ```python -client.folders.get_folder_by_id(new_folder.id) +client.folders.get_folder_by_id(folder_id, fields=["is_associated_with_app_item"]) ``` ### Arguments diff --git a/test/app_item_associations.py b/test/app_item_associations.py new file mode 100644 index 00000000..e4a8b707 --- /dev/null +++ b/test/app_item_associations.py @@ -0,0 +1,55 @@ +from box_sdk_gen.internal.utils import to_string + +from box_sdk_gen.client import BoxClient + +from box_sdk_gen.schemas.app_item_associations import AppItemAssociations + +from box_sdk_gen.schemas.app_item_association import AppItemAssociation + +from box_sdk_gen.schemas.file_full import FileFull + +from box_sdk_gen.schemas.folder_full import FolderFull + +from box_sdk_gen.internal.utils import get_uuid + +from box_sdk_gen.internal.utils import get_env_var + +from test.commons import get_default_client_with_user_subject + + +def testListFileAppItemAssocations(): + client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + file_id: str = get_env_var('APP_ITEM_ASSOCIATION_FILE_ID') + file_app_item_associations: AppItemAssociations = ( + client.app_item_associations.get_file_app_item_associations(file_id) + ) + assert len(file_app_item_associations.entries) == 1 + association: AppItemAssociation = file_app_item_associations.entries[0] + assert not association.id == '' + assert to_string(association.app_item.application_type) == 'hubs' + assert to_string(association.app_item.type) == 'app_item' + assert to_string(association.item.type) == 'file' + assert association.item.id == file_id + file: FileFull = client.files.get_file_by_id( + file_id, fields=['is_associated_with_app_item'] + ) + assert file.is_associated_with_app_item == True + + +def testListFolderAppItemAssocations(): + client: BoxClient = get_default_client_with_user_subject(get_env_var('USER_ID')) + folder_id: str = get_env_var('APP_ITEM_ASSOCIATION_FOLDER_ID') + folder_app_item_associations: AppItemAssociations = ( + client.app_item_associations.get_folder_app_item_associations(folder_id) + ) + assert len(folder_app_item_associations.entries) == 1 + association: AppItemAssociation = folder_app_item_associations.entries[0] + assert not association.id == '' + assert to_string(association.app_item.application_type) == 'hubs' + assert to_string(association.app_item.type) == 'app_item' + assert to_string(association.item.type) == 'folder' + assert association.item.id == folder_id + folder: FolderFull = client.folders.get_folder_by_id( + folder_id, fields=['is_associated_with_app_item'] + ) + assert folder.is_associated_with_app_item == True diff --git a/tox.ini b/tox.ini index 155d04ef..a9ad267e 100644 --- a/tox.ini +++ b/tox.ini @@ -20,7 +20,7 @@ commands = pytest {posargs} --disable-pytest-warnings deps = -rrequirements-test.txt allowlist_externals = pytest -passenv = JWT_CONFIG_BASE_64,ADMIN_USER_ID,CLIENT_ID,CLIENT_SECRET,USER_ID,ENTERPRISE_ID,BOX_FILE_REQUEST_ID,BOX_EXTERNAL_USER_EMAIL,WORKFLOW_FOLDER_ID +passenv = JWT_CONFIG_BASE_64,ADMIN_USER_ID,CLIENT_ID,CLIENT_SECRET,USER_ID,ENTERPRISE_ID,BOX_FILE_REQUEST_ID,BOX_EXTERNAL_USER_EMAIL,WORKFLOW_FOLDER_ID,APP_ITEM_ASSOCIATION_FILE_ID,APP_ITEM_ASSOCIATION_FOLDER_ID [testenv:pycodestyle] commands = @@ -45,7 +45,7 @@ commands = deps = coverage -rrequirements-test.txt -passenv = JWT_CONFIG_BASE_64,ADMIN_USER_ID,CLIENT_ID,CLIENT_SECRET,USER_ID,ENTERPRISE_ID,BOX_FILE_REQUEST_ID,BOX_EXTERNAL_USER_EMAIL,WORKFLOW_FOLDER_ID +passenv = JWT_CONFIG_BASE_64,ADMIN_USER_ID,CLIENT_ID,CLIENT_SECRET,USER_ID,ENTERPRISE_ID,BOX_FILE_REQUEST_ID,BOX_EXTERNAL_USER_EMAIL,WORKFLOW_FOLDER_ID,APP_ITEM_ASSOCIATION_FILE_ID,APP_ITEM_ASSOCIATION_FOLDER_ID [testenv:py310-build] description = Build the source and binary wheel packages for distribution.